support per-device regulatory settings
Subsystems (2)
cover support per-device regulatory settings
Some platform vendors need to apply their own regualtory settings and the vendor-specific data would be written in dts or acpi. This patch set adds the functionalities to handle this per-device 5.9/6GHz channel configurations.
Deren Wu (1):
wifi: mt76: mt7921: move connac nic capability handling to mt7921
Ming Yen Hsieh (4):
wifi: mt76: mt7921: enable set txpower for UNII-4
wifi: mt76: mt7921: add 6GHz power type support for clc
wifi: mt76: mt7921: get regulatory information from the clc event
wifi: mt76: mt7921: update the channel usage when the regd domain
changed
rong.yan (1):
wifi: mt76: mt7921: support 5.9/6GHz channel config in acpi
drivers/net/wireless/mediatek/mt76/eeprom.c | 7 +- drivers/net/wireless/mediatek/mt76/mt76.h | 5 + .../wireless/mediatek/mt76/mt76_connac_mcu.c | 122 +------------- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 2 +- .../net/wireless/mediatek/mt76/mt7921/init.c | 51 ++++++ .../net/wireless/mediatek/mt76/mt7921/main.c | 34 ++++ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 157 +++++++++++++++++- .../net/wireless/mediatek/mt76/mt7921/mcu.h | 13 ++ .../wireless/mediatek/mt76/mt7921/mt7921.h | 1 + drivers/net/wireless/mediatek/mt76/mt792x.h | 19 +++ .../wireless/mediatek/mt76/mt792x_acpi_sar.c | 53 ++++++ .../wireless/mediatek/mt76/mt792x_acpi_sar.h | 2 + 12 files changed, 336 insertions(+), 130 deletions(-)
Signature · 1 line
2.18.0
PATCH 1/6 wifi: mt76: mt7921: move connac nic capability handling to mt7921
mt76_connac_mcu_get_nic_capability() is used by mt7921 only. It would be better to put the code in chip folder. And we can provide more chip capability information in mt792x_phy without making mt76_phy much bigger.
The three functions would be moved to mt7921 folder and renamed. mt76_connac_mcu_parse_tx_resource() mt76_connac_mcu_parse_phy_cap() mt76_connac_mcu_get_nic_capability()
--- .../wireless/mediatek/mt76/mt76_connac_mcu.c | 120 ----------------- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 - .../net/wireless/mediatek/mt76/mt7921/mcu.c | 122 +++++++++++++++++- 3 files changed, 121 insertions(+), 122 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +0 -120
@@ -1941,126 +1941,6 @@ void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb, }EXPORT_SYMBOL_GPL (mt76_connac_mcu_coredump_event); -static void mt76_connac_mcu_parse_tx_resource (struct mt76_dev *dev, -struct sk_buff *skb) -{ -struct mt76_sdio *sdio = &dev->sdio; -struct mt76_connac_tx_resource { -__le32 version; -__le32 pse_data_quota; -__le32 pse_mcu_quota; -__le32 ple_data_quota; -__le32 ple_mcu_quota; -__le16 pse_page_size; -__le16 ple_page_size; -u8 pp_padding; -u8 pad[3 ]; - } __packed * tx_res; - - tx_res = (struct mt76_connac_tx_resource *)skb->data; - sdio->sched.pse_data_quota =le32_to_cpu (tx_res->pse_data_quota); - sdio->sched.pse_mcu_quota =le32_to_cpu (tx_res->pse_mcu_quota); - sdio->sched.ple_data_quota =le32_to_cpu (tx_res->ple_data_quota); - sdio->sched.pse_page_size =le16_to_cpu (tx_res->pse_page_size); - sdio->sched.deficit = tx_res->pp_padding; -} - -static void mt76_connac_mcu_parse_phy_cap (struct mt76_dev *dev, -struct sk_buff *skb) -{ -struct mt76_connac_phy_cap { -u8 ht; -u8 vht; -u8 _5g; -u8 max_bw; -u8 nss; -u8 dbdc; -u8 tx_ldpc; -u8 rx_ldpc; -u8 tx_stbc; -u8 rx_stbc; -u8 hw_path; -u8 he; - } __packed * cap; - -enum { -WF0_24G , -WF0_5G - }; - - cap = (struct mt76_connac_phy_cap *)skb->data; - - dev->phy.antenna_mask =BIT (cap->nss) -1 ; - dev->phy.chainmask = dev->phy.antenna_mask; - dev->phy.cap.has_2ghz = cap->hw_path &BIT (WF0_24G ); - dev->phy.cap.has_5ghz = cap->hw_path &BIT (WF0_5G ); -} - -int mt76_connac_mcu_get_nic_capability (struct mt76_phy *phy) -{ -struct mt76_connac_cap_hdr { -__le16 n_element; -u8 rsv[2 ]; - } __packed * hdr; -struct sk_buff *skb; -int ret, i; - - ret =mt76_mcu_send_and_get_msg (phy->dev,MCU_CE_CMD (GET_NIC_CAPAB ), -NULL ,0 , true, &skb); -if (ret) -return ret; - - hdr = (struct mt76_connac_cap_hdr *)skb->data; -if (skb->len <sizeof (*hdr)) { - ret = -EINVAL ; - goto out; - } - -skb_pull (skb,sizeof (*hdr)); - -for (i =0 ; i <le16_to_cpu (hdr->n_element); i++) { -struct tlv_hdr { -__le32 type; -__le32 len; - } __packed * tlv = (struct tlv_hdr *)skb->data; -int len; - -if (skb->len <sizeof (*tlv)) -break ; - -skb_pull (skb,sizeof (*tlv)); - - len =le32_to_cpu (tlv->len); -if (skb->len < len) -break ; - -switch (le32_to_cpu (tlv->type)) { -case MT_NIC_CAP_6G : - phy->cap.has_6ghz = skb->data[0 ]; -break ; -case MT_NIC_CAP_MAC_ADDR : -memcpy (phy->macaddr, (void *)skb->data,ETH_ALEN ); -break ; -case MT_NIC_CAP_PHY : -mt76_connac_mcu_parse_phy_cap (phy->dev, skb); -break ; -case MT_NIC_CAP_TX_RESOURCE : -if (mt76_is_sdio (phy->dev)) -mt76_connac_mcu_parse_tx_resource (phy->dev, - skb); -break ; -default : -break ; - } -skb_pull (skb, len); - } -out: -dev_kfree_skb (skb); - -return ret; -} -EXPORT_SYMBOL_GPL (mt76_connac_mcu_get_nic_capability); - static void mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku, struct mt76_power_limits *limits,
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +0 -1
@@ -1881,7 +1881,6 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,int mt76_connac_mcu_start_patch (struct mt76_dev *dev);int mt76_connac_mcu_patch_sem_ctrl (struct mt76_dev *dev,bool get);int mt76_connac_mcu_start_firmware (struct mt76_dev *dev,u32 addr,u32 option); -int mt76_connac_mcu_get_nic_capability (struct mt76_phy *phy);int mt76_connac_mcu_hw_scan (struct mt76_phy *phy,struct ieee80211_vif *vif,struct ieee80211_scan_request *scan_req);
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +121 -1
134 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH 2/6 wifi: mt76: mt7921: enable set txpower for UNII-4
In reply to Deren WuFrom: Ming Yen Hsieh <[email protected]>
support power config for channel 165/173/177
--- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +1 -1
@@ -2042,7 +2042,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,112 ,114 ,116 ,118 ,120 ,122 ,124 ,126 ,128 ,132 ,134 ,136 ,138 ,140 ,142 ,144 ,149 ,151 ,153 ,155 ,157 , -159 ,161 ,165 +159 ,161 ,165 ,169 ,173 ,177 };static const u8 chan_list_6ghz[] = { 1, 3, 5, 7, 9, 11, 13,
Signature · 1 line
2.18.0
PATCH 3/6 wifi: mt76: mt7921: add 6GHz power type support for clc
In reply to Deren WuFrom: Ming Yen Hsieh <[email protected]>
There are several power type should be supported in 6GHz band. mt7921 apply 6GHz power type from AP settings and clc will setup the corresponding regulatory power.
--- .../net/wireless/mediatek/mt76/mt7921/main.c | 34 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 4 ++- drivers/net/wireless/mediatek/mt76/mt792x.h | 9 +++++ 3 files changed, 46 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +34 -0
@@ -701,6 +701,38 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw,mt792x_mutex_release (dev); } +static void +mt7921_regd_set_6ghz_power_type (struct ieee80211_vif *vif) +{ +struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; +struct mt792x_phy *phy = mvif->phy; +struct mt792x_dev *dev = phy->dev; + +if (hweight64 (dev->mt76.vif_mask) >1 ) { + phy->power_type =MT_AP_DEFAULT ; + goto out; + } + +switch (vif->bss_conf.power_type) { +case IEEE80211_REG_SP_AP : + phy->power_type =MT_AP_SP ; +break ; +case IEEE80211_REG_VLP_AP : + phy->power_type =MT_AP_VLP ; +break ; +case IEEE80211_REG_LPI_AP : + phy->power_type =MT_AP_LPI ; +break ; +case IEEE80211_REG_UNSET_AP : +default : + phy->power_type =MT_AP_DEFAULT ; +break ; + } + +out: +mt7921_mcu_set_clc (dev, dev->mt76.alpha2, dev->country_ie_env); +} +int mt7921_mac_sta_add (struct mt76_dev *mdev,struct ieee80211_vif *vif,struct ieee80211_sta *sta) {
@@ -736,6 +768,8 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,if (ret)return ret; +mt7921_regd_set_6ghz_power_type (vif); +mt76_connac_power_save_sched (&dev->mphy, &dev->pm);return 0 ;
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +3 -1
@@ -1254,10 +1254,12 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,u8 pad1;u8 alpha2[2 ];u8 type[2 ]; -u8 rsvd[64 ]; +u8 env_6g; +u8 rsvd[63 ]; }__packed req = { .idx = idx, .env = env_cap, + .env_6g = dev->phy.power_type, .acpi_conf =mt792x_acpi_get_flags (&dev->phy), };int ret, valid_cnt =0 ;
drivers/net/wireless/mediatek/mt76/mt792x.h +9 -0
@@ -63,6 +63,14 @@ enum { MT792x_CLC_MAX_NUM, }; +enum mt792x_reg_power_type { +MT_AP_UNSET =0 , +MT_AP_DEFAULT , +MT_AP_LPI , +MT_AP_SP , +MT_AP_VLP , +}; + DECLARE_EWMA(avg_signal, 10, 8)struct mt792x_sta {
@@ -114,6 +122,7 @@ struct mt792x_phy {struct mt76_mib_stats mib;u8 sta_work_count; +enum mt792x_reg_power_type power_type;struct sk_buff_head scan_event_list;struct delayed_work scan_work;
Signature · 1 line
2.18.0
PATCH 4/6 wifi: mt76: mt7921: get regulatory information from the clc event
In reply to Deren WuFrom: Ming Yen Hsieh <[email protected]>
The clc event can report the radio configuration for the corresponding country and the driver would take it as regulatory information of a certain platform device.
This patch would change the clc commnad from no-waiting to waiting for event. For backward compatible, we also add a new nic capability tag to indicate the firmware did support this new clc event from now on.
--- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + .../net/wireless/mediatek/mt76/mt7921/mcu.c | 26 ++++++++++++++++--- .../net/wireless/mediatek/mt76/mt7921/mcu.h | 13 ++++++++++ .../wireless/mediatek/mt76/mt7921/mt7921.h | 1 + drivers/net/wireless/mediatek/mt76/mt792x.h | 4 +++ 5 files changed, 41 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +1 -0
@@ -1340,6 +1340,7 @@ enum {MT_NIC_CAP_ANTSWP =0x16 ,MT_NIC_CAP_WFDMA_REALLOC ,MT_NIC_CAP_6G , + MT_NIC_CAP_CHIP_CAP = 0x20, };#define UNI_WOW_DETECT_TYPE_MAGIC BIT(0)
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +22 -4
@@ -557,6 +557,9 @@ static int mt7921_mcu_get_nic_capability(struct mt792x_phy *mphy)mt7921_mcu_parse_tx_resource (phy->dev, skb);break ; +case MT_NIC_CAP_CHIP_CAP : +memcpy (&mphy->chip_cap, (void *)skb->data,sizeof (u64)); +break ;default :break ; }
@@ -1243,7 +1246,8 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, struct mt7921_clc *clc, u8 idx) { -struct sk_buff *skb; +#define CLC_CAP_EVT_EN BIT(0) +struct sk_buff *skb, *ret_skb =NULL ;struct {u8 ver;u8 pad0;
@@ -1251,7 +1255,7 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,u8 idx;u8 env;u8 acpi_conf; -u8 pad1; +u8 cap;u8 alpha2[2 ];u8 type[2 ];u8 env_6g;
@@ -1268,6 +1272,9 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,if (!clc)return 0 ; +if (dev->phy.chip_cap & MT792x_CHIP_CAP_CLC_EVT_EN) + req.cap |=CLC_CAP_EVT_EN ; + pos = clc->data;for (i =0 ; i < clc->nr_country; i++) {struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos;
@@ -1289,10 +1296,21 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,return -ENOMEM ;skb_put_data (skb, rule->data, len); - ret =mt76_mcu_skb_send_msg (&dev->mt76, skb, -MCU_CE_CMD (SET_CLC ), false); + ret =mt76_mcu_skb_send_and_get_msg (&dev->mt76, skb, +MCU_CE_CMD (SET_CLC ), + !!(req.cap &CLC_CAP_EVT_EN ), + &ret_skb);if (ret <0 )return ret; + +if (ret_skb) { +struct mt7921_clc_info_tlv *info; + + info = (struct mt7921_clc_info_tlv *)(ret_skb->data +4 ); + dev->phy.clc_chan_conf = info->chan_conf; +dev_kfree_skb (ret_skb); + } + valid_cnt++; }
drivers/net/wireless/mediatek/mt76/mt7921/mcu.h +13 -0
@@ -99,4 +99,17 @@ struct mt7921_rftest_evt {__le32 param0; __le32 param1; } __packed; + +struct mt7921_clc_info_tlv { +__le16 tag; +__le16 len; + +u8 chan_conf;/* BIT(0) : Enable UNII-4 +* BIT(1) : Enable UNII-5 +* BIT(2) : Enable UNII-6 +* BIT(3) : Enable UNII-7 +* BIT(4) : Enable UNII-8 +*/ +u8 rsv[63 ]; +} __packed;#endif
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +1 -0
@@ -27,6 +27,7 @@#define MT7921_SDIO_HDR_PKT_TYPE GENMASK(17, 16)#define MCU_UNI_EVENT_ROC 0x27 +#define MCU_UNI_EVENT_CLC 0x80enum {UNI_ROC_ACQUIRE ,
drivers/net/wireless/mediatek/mt76/mt792x.h +4 -0
@@ -25,6 +25,8 @@#define MT792x_FW_TAG_FEATURE 4#define MT792x_FW_CAP_CNM BIT(7) +#define MT792x_CHIP_CAP_CLC_EVT_EN BIT(0) +/* NOTE: used to map mt76_rates. idx may change if firmware expands table */ #define MT792x_BASIC_RATES_TBL 11
@@ -122,6 +124,7 @@ struct mt792x_phy {struct mt76_mib_stats mib;u8 sta_work_count; +u8 clc_chan_conf;enum mt792x_reg_power_type power_type;struct sk_buff_head scan_event_list;
@@ -130,6 +133,7 @@ struct mt792x_phy {void *acpisar;#endif void *clc[MT792x_CLC_MAX_NUM]; +u64 chip_cap;struct work_struct roc_work;struct timer_list roc_timer;
Signature · 1 line
2.18.0
PATCH 5/6 wifi: mt76: mt7921: update the channel usage when the regd domain changed
In reply to Deren WuFrom: Ming Yen Hsieh <[email protected]>
The 5.9/6GHz channel license of a certain platform device has been regulated in various countries. That may be difference with standard Liunx regulatory domain settings. In this case, when .reg_notifier() called for regulatory change, mt792x chipset should update the channel usage based on clc or dts configurations.
Channel would be disabled by following cases.
* clc report the particular UNII-x is disabled.
* dts enabled and the channel is not configured.
--- drivers/net/wireless/mediatek/mt76/eeprom.c | 7 ++- drivers/net/wireless/mediatek/mt76/mt76.h | 5 ++ .../net/wireless/mediatek/mt76/mt7921/init.c | 51 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 3 ++ 4 files changed, 64 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/eeprom.c +5 -2
@@ -188,7 +188,7 @@ static bool mt76_string_prop_find(struct property *prop, const char *str)return false; } -static struct device_node * +struct device_node *mt76_find_power_limits_node (struct mt76_dev *dev) {struct device_node *np = dev->dev->of_node;
@@ -227,6 +227,7 @@ mt76_find_power_limits_node(struct mt76_dev *dev)of_node_put (np);return fallback; } +EXPORT_SYMBOL_GPL (mt76_find_power_limits_node);static const __be32 *mt76_get_of_array (struct device_node *np,char *name,size_t *len,int min)
@@ -241,7 +242,7 @@ mt76_get_of_array(struct device_node *np, char *name, size_t *len, int min)return prop->value; } -static struct device_node * +struct device_node *mt76_find_channel_node (struct device_node *np,struct ieee80211_channel *chan) {struct device_node *cur;
@@ -265,6 +266,8 @@ mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan)return NULL ; } +EXPORT_SYMBOL_GPL (mt76_find_channel_node); +static s8 mt76_get_txs_delta (struct device_node *np,u8 nss)
drivers/net/wireless/mediatek/mt76/mt76.h +5 -0
@@ -1537,6 +1537,11 @@ mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd,void mt76_set_irq_mask (struct mt76_dev *dev,u32 addr,u32 clear,u32 set); +struct device_node * +mt76_find_power_limits_node (struct mt76_dev *dev); +struct device_node * +mt76_find_channel_node (struct device_node *np,struct ieee80211_channel *chan); + s8 mt76_get_rate_power_limits(struct mt76_phy *phy, struct ieee80211_channel *chan, struct mt76_power_limits *dest,
drivers/net/wireless/mediatek/mt76/mt7921/init.c +51 -0
63 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +3 -0
@@ -1247,6 +1247,7 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, u8 idx) {#define CLC_CAP_EVT_EN BIT(0) +#define CLC_CAP_DTS_EN BIT(1)struct sk_buff *skb, *ret_skb =NULL ;struct {u8 ver;
@@ -1274,6 +1275,8 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,if (dev->phy.chip_cap & MT792x_CHIP_CAP_CLC_EVT_EN) req.cap |=CLC_CAP_EVT_EN ; +if (mt76_find_power_limits_node (&dev->mt76)) + req.cap |=CLC_CAP_DTS_EN ; pos = clc->data;for (i =0 ; i < clc->nr_country; i++) {
Signature · 1 line
2.18.0
PATCH 6/6 wifi: mt76: mt7921: support 5.9/6GHz channel config in acpi
In reply to Deren WuFrom: "rong.yan" <[email protected]>
The mtcl table, configured by platform vendor, provides regulatory information for 5.9/6 GHz channels. mt792x should work on corresponding channels supported by mtcl. This patch would parse the settings in mtcl table and apply the result into chip side.
--- .../net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +- drivers/net/wireless/mediatek/mt76/mt792x.h | 6 +++ .../wireless/mediatek/mt76/mt792x_acpi_sar.c | 53 +++++++++++++++++++ .../wireless/mediatek/mt76/mt792x_acpi_sar.h | 2 + 4 files changed, 64 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +3 -1
@@ -1260,12 +1260,14 @@ int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,u8 alpha2[2 ];u8 type[2 ];u8 env_6g; -u8 rsvd[63 ]; +u8 mtcl_conf; +u8 rsvd[62 ]; }__packed req = { .idx = idx, .env = env_cap, .env_6g = dev->phy.power_type, .acpi_conf =mt792x_acpi_get_flags (&dev->phy), + .mtcl_conf =mt792x_acpi_get_mtcl_conf (&dev->phy, alpha2), };int ret, valid_cnt =0 ;u8 i, *pos;
drivers/net/wireless/mediatek/mt76/mt792x.h +6 -0
@@ -364,6 +364,7 @@ int mt792xe_mcu_fw_pmctrl(struct mt792x_dev *dev);int mt792x_init_acpi_sar (struct mt792x_dev *dev);int mt792x_init_acpi_sar_power (struct mt792x_phy *phy,bool set_default);u8 mt792x_acpi_get_flags (struct mt792x_phy *phy); +u8 mt792x_acpi_get_mtcl_conf (struct mt792x_phy *phy,char *alpha2);#else static inline int mt792x_init_acpi_sar (struct mt792x_dev *dev) {
@@ -380,6 +381,11 @@ static inline u8 mt792x_acpi_get_flags(struct mt792x_phy *phy) {return 0 ; } + +static inline u8 mt792x_acpi_get_mtcl_conf (struct mt792x_phy *phy,char *alpha2) +{ +return 0xf ; +}#endif #endif /* __MT7925_H */
drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c +53 -0
56 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h +2 -0
@@ -77,6 +77,8 @@ struct mt792x_asar_cl {u8 version;u8 mode_6g;u8 cl6g[6 ]; +u8 mode_5g9; +u8 cl5g9[6 ]; } __packed;struct mt792x_asar_fg {
Signature · 1 line
2.18.0