mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-03 17:51:23 +00:00
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:
parent
f2027ef3f7
commit
f0317215b3
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -71,6 +71,7 @@ struct mt792x_fw_features {
|
||||
enum {
|
||||
MT792x_CLC_POWER,
|
||||
MT792x_CLC_POWER_EXT,
|
||||
MT792x_CLC_BE_CTRL,
|
||||
MT792x_CLC_MAX_NUM,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user