Skip to content

Commit f031721

Browse files
Ming Yen Hsiehnbd168
authored andcommitted
wifi: mt76: mt7925: add EHT control support based on the CLC data
Some countries do not support EHT modulation for now. To prevent violating regulations, the MT7925 chipset should control the EHT capabilities. Therefore, when a regulatory domain change is detected during scanning, the `mt7925_regd_be_ctrl` will process the CLC data to update the EHT capabilities. Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com> Link: https://patch.msgid.link/20250304113649.867387-2-mingyen.hsieh@mediatek.com Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent f2027ef commit f031721

File tree

5 files changed

+71
-7
lines changed

5 files changed

+71
-7
lines changed

drivers/net/wireless/mediatek/mt76/mt7925/init.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,44 @@ static int mt7925_thermal_init(struct mt792x_phy *phy)
5858
return PTR_ERR_OR_ZERO(hwmon);
5959
}
6060

61+
void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2)
62+
{
63+
struct mt792x_phy *phy = &dev->phy;
64+
struct mt7925_clc_rule_v2 *rule;
65+
struct mt7925_clc *clc;
66+
bool old = dev->has_eht, new = true;
67+
u8 *pos;
68+
69+
if (!phy->clc[MT792x_CLC_BE_CTRL])
70+
goto out;
71+
72+
clc = (struct mt7925_clc *)phy->clc[MT792x_CLC_BE_CTRL];
73+
pos = clc->data;
74+
75+
while (1) {
76+
rule = (struct mt7925_clc_rule_v2 *)pos;
77+
78+
if (rule->alpha2[0] == alpha2[0] &&
79+
rule->alpha2[1] == alpha2[1]) {
80+
new = false;
81+
break;
82+
}
83+
84+
/* Check the last one */
85+
if (rule->flag && BIT(0))
86+
break;
87+
88+
pos += sizeof(*rule);
89+
}
90+
91+
out:
92+
if (old == new)
93+
return;
94+
95+
dev->has_eht = new;
96+
mt7925_set_stream_he_eht_caps(phy);
97+
}
98+
6199
void mt7925_regd_update(struct mt792x_dev *dev)
62100
{
63101
struct mt76_dev *mdev = &dev->mt76;

drivers/net/wireless/mediatek/mt76/mt7925/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,8 @@ void mt7925_scan_work(struct work_struct *work)
14181418
if (!is_valid_alpha2(evt->alpha2))
14191419
break;
14201420

1421+
mt7925_regd_be_ctrl(phy->dev, evt->alpha2);
1422+
14211423
if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0')
14221424
break;
14231425

drivers/net/wireless/mediatek/mt76/mt7925/mcu.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,9 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name)
742742
continue;
743743

744744
/* header content sanity */
745-
if (u8_get_bits(clc->type, MT_EE_HW_TYPE_ENCAP) != hw_encap)
745+
if ((clc->idx == MT792x_CLC_BE_CTRL &&
746+
u8_get_bits(clc->t2.type, MT_EE_HW_TYPE_ENCAP) != hw_encap) ||
747+
u8_get_bits(clc->t0.type, MT_EE_HW_TYPE_ENCAP) != hw_encap)
746748
continue;
747749

748750
phy->clc[clc->idx] = devm_kmemdup(mdev->dev, clc,
@@ -851,7 +853,6 @@ mt7925_mcu_parse_phy_cap(struct mt792x_dev *dev, char *data)
851853
mdev->phy.chainmask = mdev->phy.antenna_mask;
852854
mdev->phy.cap.has_2ghz = cap->hw_path & BIT(WF0_24G);
853855
mdev->phy.cap.has_5ghz = cap->hw_path & BIT(WF0_5G);
854-
dev->has_eht = cap->eht;
855856
}
856857

857858
static void
@@ -3193,7 +3194,7 @@ __mt7925_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
31933194
if (!clc)
31943195
return 0;
31953196

3196-
pos = clc->data + sizeof(*seg) * clc->nr_seg;
3197+
pos = clc->data + sizeof(*seg) * clc->t0.nr_seg;
31973198
last_pos = clc->data + le32_to_cpu(*(__le32 *)(clc->data + 4));
31983199
while (pos < last_pos) {
31993200
struct mt7925_clc_rule *rule = (struct mt7925_clc_rule *)pos;
@@ -3239,6 +3240,9 @@ int mt7925_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
32393240

32403241
/* submit all clc config */
32413242
for (i = 0; i < ARRAY_SIZE(phy->clc); i++) {
3243+
if (i == MT792x_CLC_BE_CTRL)
3244+
continue;
3245+
32423246
ret = __mt7925_mcu_set_clc(dev, alpha2, env_cap,
32433247
phy->clc[i], i);
32443248

drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ enum {
137137
MT7925_CLC_MAX_NUM,
138138
};
139139

140+
struct mt7925_clc_rule_v2 {
141+
u32 flag;
142+
u8 alpha2[2];
143+
u8 rsv[10];
144+
} __packed;
145+
140146
struct mt7925_clc_rule {
141147
u8 alpha2[2];
142148
u8 type[2];
@@ -152,14 +158,26 @@ struct mt7925_clc_segment {
152158
u8 rsv2[4];
153159
} __packed;
154160

155-
struct mt7925_clc {
156-
__le32 len;
157-
u8 idx;
158-
u8 ver;
161+
struct mt7925_clc_type0 {
159162
u8 nr_country;
160163
u8 type;
161164
u8 nr_seg;
162165
u8 rsv[7];
166+
} __packed;
167+
168+
struct mt7925_clc_type2 {
169+
u8 type;
170+
u8 rsv[9];
171+
} __packed;
172+
173+
struct mt7925_clc {
174+
__le32 len;
175+
u8 idx;
176+
u8 ver;
177+
union {
178+
struct mt7925_clc_type0 t0;
179+
struct mt7925_clc_type2 t2;
180+
};
163181
u8 data[];
164182
} __packed;
165183

@@ -238,6 +256,7 @@ int mt7925_mcu_chip_config(struct mt792x_dev *dev, const char *cmd);
238256
int mt7925_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif,
239257
u8 bit_op, u32 bit_map);
240258

259+
void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2);
241260
void mt7925_regd_update(struct mt792x_dev *dev);
242261
int mt7925_mac_init(struct mt792x_dev *dev);
243262
int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,

drivers/net/wireless/mediatek/mt76/mt792x.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ struct mt792x_fw_features {
7171
enum {
7272
MT792x_CLC_POWER,
7373
MT792x_CLC_POWER_EXT,
74+
MT792x_CLC_BE_CTRL,
7475
MT792x_CLC_MAX_NUM,
7576
};
7677

0 commit comments

Comments
 (0)