wifi: mt76: mt7921: get regulatory information from the clc event
authorMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Sat, 30 Sep 2023 02:25:08 +0000 (10:25 +0800)
committerFelix Fietkau <nbd@nbd.name>
Sat, 30 Sep 2023 18:17:18 +0000 (20:17 +0200)
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.

Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Co-developed-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
drivers/net/wireless/mediatek/mt76/mt792x.h

index ac1fe9e9b939d02a74d983acccb41e880a59e422..0563b1b22f485b10c68c8ee7296dffb92b6f60de 100644 (file)
@@ -1355,6 +1355,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)
index 8c76ef92e14fd2d11f46163b688fd8ddab6840ff..4f66e27aa43aa19ddff5ac629289c3bfa27fd029 100644 (file)
@@ -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++;
        }
 
index 9b0aa3b70f0eb194eded9a0998274577a1addf73..f9a259ee6b82581e8554e26ad7dcbb26597eb057 100644 (file)
@@ -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
index 5e6e5fe85599c0587eab73aee83939b903357fd4..f28621121927e5c16eab8b4ff72ee4e25ba9c524 100644 (file)
@@ -24,6 +24,7 @@
 #define MT7921_SKU_TABLE_SIZE          (MT7921_SKU_RATE_NUM + 1)
 
 #define MCU_UNI_EVENT_ROC  0x27
+#define MCU_UNI_EVENT_CLC  0x80
 
 enum {
        UNI_ROC_ACQUIRE,
index 51e60e91bb3e721d4aafd535afadfaee1434fd2f..36fae736dd19251b0f48986551a68af123fe292c 100644 (file)
@@ -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
 
@@ -125,6 +127,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;
@@ -133,6 +136,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;