Message ID | 20250304062854.829194-2-mingyen.hsieh@mediatek.com (mailing list archive) |
---|---|
State | Deferred |
Delegated to: | Felix Fietkau |
Headers | show |
Series | [v2,1/6] wifi: mt76: mt7925: load the appropriate CLC data based on hardware type | expand |
Context | Check | Description |
---|---|---|
jmberg/tree_selection | success | Guessing tree name failed - patch did not apply |
Mingyen Hsieh <mingyen.hsieh@mediatek.com> wrote: [...] > > +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) { while (1) could lead infinite loop unexpectedly. Adding a checking of clc->len would be safer. > + 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); > +} > + [...]
On Tue, 2025-03-04 at 09:10 +0000, Ping-Ke Shih wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > > > Mingyen Hsieh <mingyen.hsieh@mediatek.com> wrote: > > [...] > > > > > +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) { > > while (1) could lead infinite loop unexpectedly. > Adding a checking of clc->len would be safer. > > > + 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; > > + Hi Ping-Ke, I designed a flag to prevent the infinite loop. > > + pos += sizeof(*rule); > > + } > > + > > +out: > > + if (old == new) > > + return; > > + > > + dev->has_eht = new; > > + mt7925_set_stream_he_eht_caps(phy); > > +} > > + > > [...] >
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c index b40d979f1b65..94d7b762fe40 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c @@ -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; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index cefb9068fa72..80aa7f329cf8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -1449,6 +1449,9 @@ void mt7925_scan_work(struct work_struct *work) if (!is_valid_alpha2(evt->alpha2)) break; + if (memcmp(evt->alpha2, mdev->alpha2, 2)) + mt7925_regd_be_ctrl(phy->dev, evt->alpha2); + if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0') break; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 505a6467f147..e73320c5d8c0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -915,7 +915,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, @@ -1024,7 +1026,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 @@ -3427,7 +3428,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; @@ -3473,6 +3474,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); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h index abecaf897159..e6ca9021f487 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h @@ -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; @@ -239,6 +257,7 @@ int mt7925_mcu_chip_configv2(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, diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index 281df43d9060..85f07f936be5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -71,6 +71,7 @@ struct mt792x_fw_features { enum { MT792x_CLC_POWER, MT792x_CLC_POWER_EXT, + MT792x_CLC_BE_CTRL, MT792x_CLC_MAX_NUM, };