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>
This commit is contained in:
Ming Yen Hsieh 2025-03-04 19:36:45 +08:00 committed by Felix Fietkau
parent f2027ef3f7
commit f0317215b3
5 changed files with 71 additions and 7 deletions

View File

@ -58,6 +58,44 @@ static int mt7925_thermal_init(struct mt792x_phy *phy)
return PTR_ERR_OR_ZERO(hwmon);
}
void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2)
{
struct mt792x_phy *phy = &dev->phy;
struct mt7925_clc_rule_v2 *rule;
struct mt7925_clc *clc;
bool old = dev->has_eht, new = true;
u8 *pos;
if (!phy->clc[MT792x_CLC_BE_CTRL])
goto out;
clc = (struct mt7925_clc *)phy->clc[MT792x_CLC_BE_CTRL];
pos = clc->data;
while (1) {
rule = (struct mt7925_clc_rule_v2 *)pos;
if (rule->alpha2[0] == alpha2[0] &&
rule->alpha2[1] == alpha2[1]) {
new = false;
break;
}
/* Check the last one */
if (rule->flag && BIT(0))
break;
pos += sizeof(*rule);
}
out:
if (old == new)
return;
dev->has_eht = new;
mt7925_set_stream_he_eht_caps(phy);
}
void mt7925_regd_update(struct mt792x_dev *dev)
{
struct mt76_dev *mdev = &dev->mt76;

View File

@ -1418,6 +1418,8 @@ void mt7925_scan_work(struct work_struct *work)
if (!is_valid_alpha2(evt->alpha2))
break;
mt7925_regd_be_ctrl(phy->dev, evt->alpha2);
if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0')
break;

View File

@ -742,7 +742,9 @@ static int mt7925_load_clc(struct mt792x_dev *dev, const char *fw_name)
continue;
/* header content sanity */
if (u8_get_bits(clc->type, MT_EE_HW_TYPE_ENCAP) != hw_encap)
if ((clc->idx == MT792x_CLC_BE_CTRL &&
u8_get_bits(clc->t2.type, MT_EE_HW_TYPE_ENCAP) != hw_encap) ||
u8_get_bits(clc->t0.type, MT_EE_HW_TYPE_ENCAP) != hw_encap)
continue;
phy->clc[clc->idx] = devm_kmemdup(mdev->dev, clc,
@ -851,7 +853,6 @@ mt7925_mcu_parse_phy_cap(struct mt792x_dev *dev, char *data)
mdev->phy.chainmask = mdev->phy.antenna_mask;
mdev->phy.cap.has_2ghz = cap->hw_path & BIT(WF0_24G);
mdev->phy.cap.has_5ghz = cap->hw_path & BIT(WF0_5G);
dev->has_eht = cap->eht;
}
static void
@ -3193,7 +3194,7 @@ __mt7925_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
if (!clc)
return 0;
pos = clc->data + sizeof(*seg) * clc->nr_seg;
pos = clc->data + sizeof(*seg) * clc->t0.nr_seg;
last_pos = clc->data + le32_to_cpu(*(__le32 *)(clc->data + 4));
while (pos < last_pos) {
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,
/* submit all clc config */
for (i = 0; i < ARRAY_SIZE(phy->clc); i++) {
if (i == MT792x_CLC_BE_CTRL)
continue;
ret = __mt7925_mcu_set_clc(dev, alpha2, env_cap,
phy->clc[i], i);

View File

@ -137,6 +137,12 @@ enum {
MT7925_CLC_MAX_NUM,
};
struct mt7925_clc_rule_v2 {
u32 flag;
u8 alpha2[2];
u8 rsv[10];
} __packed;
struct mt7925_clc_rule {
u8 alpha2[2];
u8 type[2];
@ -152,14 +158,26 @@ struct mt7925_clc_segment {
u8 rsv2[4];
} __packed;
struct mt7925_clc {
__le32 len;
u8 idx;
u8 ver;
struct mt7925_clc_type0 {
u8 nr_country;
u8 type;
u8 nr_seg;
u8 rsv[7];
} __packed;
struct mt7925_clc_type2 {
u8 type;
u8 rsv[9];
} __packed;
struct mt7925_clc {
__le32 len;
u8 idx;
u8 ver;
union {
struct mt7925_clc_type0 t0;
struct mt7925_clc_type2 t2;
};
u8 data[];
} __packed;
@ -238,6 +256,7 @@ int mt7925_mcu_chip_config(struct mt792x_dev *dev, const char *cmd);
int mt7925_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif,
u8 bit_op, u32 bit_map);
void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2);
void mt7925_regd_update(struct mt792x_dev *dev);
int mt7925_mac_init(struct mt792x_dev *dev);
int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,

View File

@ -71,6 +71,7 @@ struct mt792x_fw_features {
enum {
MT792x_CLC_POWER,
MT792x_CLC_POWER_EXT,
MT792x_CLC_BE_CTRL,
MT792x_CLC_MAX_NUM,
};