Message ID | TYCPR01MB84376C7074C566865654F05098D42@TYCPR01MB8437.jpnprd01.prod.outlook.com |
---|---|
State | New |
Headers | show |
Series | [v9,RESEND] wifi: mt76: mt7915: add wds support when wed is enabled | expand |
Shengyu Qu <wiagn233@outlook.com> wrote: > @@ -1280,6 +1292,34 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, > if (!msta->wcid.sta) > return; > > + if (mtk_wed_device_active(&dev->mt76.mmio.wed) && > + !is_mt7915(&dev->mt76) && > + (msta->wcid.idx < min || msta->wcid.idx > max - 1)) { > + pre_sta = kmemdup(sta, sizeof(*sta) + sizeof(*msta), GFP_KERNEL | __GFP_ZERO); Need to check if pre_sta != NULL before using. > + pre_msta = (struct mt7915_sta *)pre_sta->drv_priv; > + > + flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ? > + MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE; > + > + tmp_idx = __mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA, flags); > + if (tmp_idx == -1) At other places, it checks this by 'idx < 0'. > + goto error; > + pre_msta->wcid.idx = (u16)tmp_idx; > + mt7915_mac_sta_add(&dev->mt76, vif, pre_sta); > + rcu_assign_pointer(dev->mt76.wcid[tmp_idx], &msta->wcid); > + > + tmp_idx = msta->wcid.idx; > + msta->wcid.idx = pre_msta->wcid.idx; > + pre_msta->wcid.idx = (u16)tmp_idx; > + rcu_assign_pointer(dev->mt76.wcid[tmp_idx], NULL); > + > + synchronize_rcu(); > + mt7915_mac_sta_remove(&dev->mt76, vif, pre_sta); > + > +error: > + kfree(pre_sta); > + } > + > mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta); > } > [...] > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c > b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c > index 9d790f234e82..32c5aa1a361e 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c > @@ -2385,10 +2385,20 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev) > > mt76_connac_mcu_del_wtbl_all(&dev->mt76); > > - if ((mtk_wed_device_active(&dev->mt76.mmio.wed) && > - is_mt7915(&dev->mt76)) || > - !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) > - mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0); > +#ifdef CONFIG_NET_MEDIATEK_SOC_WED if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) ... ? > + if (mtk_wed_device_active(&dev->mt76.mmio.wed)) { > + if (is_mt7915(&dev->mt76) || > + !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) > + ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), > + 0, 0, 0); > + else > + ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), > + MCU_WA_PARAM_WED_VERSION, > + dev->mt76.mmio.wed.rev_id, 0); > + if (ret) > + return ret; > + } > +#endif > > ret = mt7915_mcu_set_mwds(dev, 1); > if (ret) > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h > b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h > index 49476a4182fd..c3dd0cb4a5d3 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h > @@ -278,6 +278,7 @@ enum { > MCU_WA_PARAM_PDMA_RX = 0x04, > MCU_WA_PARAM_CPU_UTIL = 0x0b, > MCU_WA_PARAM_RED = 0x0e, > + MCU_WA_PARAM_WED_VERSION = 0x32, > MCU_WA_PARAM_RED_SETTING = 0x40, > }; > > diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c > index 95b3dc96e4c4..7fac9c79ebdf 100644 > --- a/drivers/net/wireless/mediatek/mt76/util.c > +++ b/drivers/net/wireless/mediatek/mt76/util.c > @@ -42,9 +42,11 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, > } > EXPORT_SYMBOL_GPL(____mt76_poll_msec); > > -int mt76_wcid_alloc(u32 *mask, int size) > +int __mt76_wcid_alloc(u32 *mask, int size, u8 flag) > { > int i, idx = 0, cur; > + int min = MT76_WED_WDS_MIN; > + int max = MT76_WED_WDS_MAX; In reverse X'mas tree order? > > for (i = 0; i < DIV_ROUND_UP(size, 32); i++) { > idx = ffs(~mask[i]); > @@ -53,16 +55,45 @@ int mt76_wcid_alloc(u32 *mask, int size) > > idx--; > cur = i * 32 + idx; > - if (cur >= size) > + > + switch (flag) { > + case MT76_WED_ACTIVE: > + if (cur >= min && cur < max) > + continue; > + > + if (cur >= size) { > + u32 end = max - min - 1; > + > + i = min / 32; > + idx = ffs(~mask[i] & GENMASK(end, 0)); > + if (!idx) > + goto error; > + idx--; > + cur = min + idx; > + } > + > break; > + case MT76_WED_WDS_ACTIVE: > + if (cur < min) > + continue; > + if (cur >= max) > + goto error; > + > + break; > + default: > + if (cur >= size) > + goto error; > + break; > + } > > mask[i] |= BIT(idx); > return cur; > } > > +error: > return -1; > } > -EXPORT_SYMBOL_GPL(mt76_wcid_alloc); > +EXPORT_SYMBOL_GPL(__mt76_wcid_alloc); > > int mt76_get_min_avg_rssi(struct mt76_dev *dev, u8 phy_idx) > { > diff --git a/drivers/net/wireless/mediatek/mt76/util.h b/drivers/net/wireless/mediatek/mt76/util.h > index 260965dde94c..99b7263c0a20 100644 > --- a/drivers/net/wireless/mediatek/mt76/util.h > +++ b/drivers/net/wireless/mediatek/mt76/util.h > @@ -27,7 +27,12 @@ enum { > #define MT76_INCR(_var, _size) \ > (_var = (((_var) + 1) % (_size))) > > -int mt76_wcid_alloc(u32 *mask, int size); > +int __mt76_wcid_alloc(u32 *mask, int size, u8 flags); > + > +static inline int mt76_wcid_alloc(u32 *mask, int size) > +{ > + return __mt76_wcid_alloc(mask, size, 0); return __mt76_wcid_alloc(mask, size, MT76_WED_DEFAULT); ? > +} > > static inline void > mt76_wcid_mask_set(u32 *mask, int idx) > -- > 2.48.1
在 2025/3/10 8:33, Ping-Ke Shih 写道: > Shengyu Qu <wiagn233@outlook.com> wrote: >> @@ -1280,6 +1292,34 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, >> if (!msta->wcid.sta) >> return; >> >> + if (mtk_wed_device_active(&dev->mt76.mmio.wed) && >> + !is_mt7915(&dev->mt76) && >> + (msta->wcid.idx < min || msta->wcid.idx > max - 1)) { >> + pre_sta = kmemdup(sta, sizeof(*sta) + sizeof(*msta), GFP_KERNEL | __GFP_ZERO); > > Need to check if pre_sta != NULL before using. Thanks, will fix. > >> + pre_msta = (struct mt7915_sta *)pre_sta->drv_priv; >> + >> + flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ? >> + MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE; >> + >> + tmp_idx = __mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA, flags); >> + if (tmp_idx == -1) > > At other places, it checks this by 'idx < 0'. Will fix. > >> + goto error; >> + pre_msta->wcid.idx = (u16)tmp_idx; >> + mt7915_mac_sta_add(&dev->mt76, vif, pre_sta); >> + rcu_assign_pointer(dev->mt76.wcid[tmp_idx], &msta->wcid); >> + >> + tmp_idx = msta->wcid.idx; >> + msta->wcid.idx = pre_msta->wcid.idx; >> + pre_msta->wcid.idx = (u16)tmp_idx; >> + rcu_assign_pointer(dev->mt76.wcid[tmp_idx], NULL); >> + >> + synchronize_rcu(); >> + mt7915_mac_sta_remove(&dev->mt76, vif, pre_sta); >> + >> +error: >> + kfree(pre_sta); >> + } >> + >> mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta); >> } >> > > [...] > >> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c >> b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c >> index 9d790f234e82..32c5aa1a361e 100644 >> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c >> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c >> @@ -2385,10 +2385,20 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev) >> >> mt76_connac_mcu_del_wtbl_all(&dev->mt76); >> >> - if ((mtk_wed_device_active(&dev->mt76.mmio.wed) && >> - is_mt7915(&dev->mt76)) || >> - !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) >> - mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0); >> +#ifdef CONFIG_NET_MEDIATEK_SOC_WED > > if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) ... ? I did a search in code about this, seems current MT76 code is using a mix of IS_ENABLED and ifdef. And this file already have a ifdef implementation. I prefer keep it as is and use another patch to convert the whole mt76 driver. > >> + if (mtk_wed_device_active(&dev->mt76.mmio.wed)) { >> + if (is_mt7915(&dev->mt76) || >> + !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) >> + ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), >> + 0, 0, 0); >> + else >> + ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), >> + MCU_WA_PARAM_WED_VERSION, >> + dev->mt76.mmio.wed.rev_id, 0); >> + if (ret) >> + return ret; >> + } >> +#endif >> >> ret = mt7915_mcu_set_mwds(dev, 1); >> if (ret) >> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h >> b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h >> index 49476a4182fd..c3dd0cb4a5d3 100644 >> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h >> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h >> @@ -278,6 +278,7 @@ enum { >> MCU_WA_PARAM_PDMA_RX = 0x04, >> MCU_WA_PARAM_CPU_UTIL = 0x0b, >> MCU_WA_PARAM_RED = 0x0e, >> + MCU_WA_PARAM_WED_VERSION = 0x32, >> MCU_WA_PARAM_RED_SETTING = 0x40, >> }; >> >> diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c >> index 95b3dc96e4c4..7fac9c79ebdf 100644 >> --- a/drivers/net/wireless/mediatek/mt76/util.c >> +++ b/drivers/net/wireless/mediatek/mt76/util.c >> @@ -42,9 +42,11 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, >> } >> EXPORT_SYMBOL_GPL(____mt76_poll_msec); >> >> -int mt76_wcid_alloc(u32 *mask, int size) >> +int __mt76_wcid_alloc(u32 *mask, int size, u8 flag) >> { >> int i, idx = 0, cur; >> + int min = MT76_WED_WDS_MIN; >> + int max = MT76_WED_WDS_MAX; > > In reverse X'mas tree order? Will fix. > >> >> for (i = 0; i < DIV_ROUND_UP(size, 32); i++) { >> idx = ffs(~mask[i]); >> @@ -53,16 +55,45 @@ int mt76_wcid_alloc(u32 *mask, int size) >> >> idx--; >> cur = i * 32 + idx; >> - if (cur >= size) >> + >> + switch (flag) { >> + case MT76_WED_ACTIVE: >> + if (cur >= min && cur < max) >> + continue; >> + >> + if (cur >= size) { >> + u32 end = max - min - 1; >> + >> + i = min / 32; >> + idx = ffs(~mask[i] & GENMASK(end, 0)); >> + if (!idx) >> + goto error; >> + idx--; >> + cur = min + idx; >> + } >> + >> break; >> + case MT76_WED_WDS_ACTIVE: >> + if (cur < min) >> + continue; >> + if (cur >= max) >> + goto error; >> + >> + break; >> + default: >> + if (cur >= size) >> + goto error; >> + break; >> + } >> >> mask[i] |= BIT(idx); >> return cur; >> } >> >> +error: >> return -1; >> } >> -EXPORT_SYMBOL_GPL(mt76_wcid_alloc); >> +EXPORT_SYMBOL_GPL(__mt76_wcid_alloc); >> >> int mt76_get_min_avg_rssi(struct mt76_dev *dev, u8 phy_idx) >> { >> diff --git a/drivers/net/wireless/mediatek/mt76/util.h b/drivers/net/wireless/mediatek/mt76/util.h >> index 260965dde94c..99b7263c0a20 100644 >> --- a/drivers/net/wireless/mediatek/mt76/util.h >> +++ b/drivers/net/wireless/mediatek/mt76/util.h >> @@ -27,7 +27,12 @@ enum { >> #define MT76_INCR(_var, _size) \ >> (_var = (((_var) + 1) % (_size))) >> >> -int mt76_wcid_alloc(u32 *mask, int size); >> +int __mt76_wcid_alloc(u32 *mask, int size, u8 flags); >> + >> +static inline int mt76_wcid_alloc(u32 *mask, int size) >> +{ >> + return __mt76_wcid_alloc(mask, size, 0); > > return __mt76_wcid_alloc(mask, size, MT76_WED_DEFAULT); ? Will fix. > >> +} >> >> static inline void >> mt76_wcid_mask_set(u32 *mask, int idx) >> -- >> 2.48.1 >
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 132148f7b107..638ee9fae0c7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -28,6 +28,9 @@ #define MT76_TOKEN_FREE_THR 64 +#define MT76_WED_WDS_MIN 256 +#define MT76_WED_WDS_MAX 272 + #define MT_QFLAG_WED_RING GENMASK(1, 0) #define MT_QFLAG_WED_TYPE GENMASK(4, 2) #define MT_QFLAG_WED BIT(5) @@ -73,6 +76,12 @@ enum mt76_wed_type { MT76_WED_RRO_Q_IND, }; +enum mt76_wed_state { + MT76_WED_DEFAULT, + MT76_WED_ACTIVE, + MT76_WED_WDS_ACTIVE, +}; + struct mt76_bus_ops { u32 (*rr)(struct mt76_dev *dev, u32 offset); void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 3aa31c5cefa6..9be5937727cb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -745,8 +745,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; bool ext_phy = mvif->phy != &dev->phy; int idx; + u8 flags = MT76_WED_DEFAULT; - idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA); + if (mtk_wed_device_active(&dev->mt76.mmio.wed) && + !is_mt7915(&dev->mt76)) { + flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ? + MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE; + } + + idx = __mt76_wcid_alloc(mdev->wcid_mask, MT7915_WTBL_STA, flags); if (idx < 0) return -ENOSPC; @@ -1271,6 +1278,11 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, { struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + int min = MT76_WED_WDS_MIN, max = MT76_WED_WDS_MAX; + struct ieee80211_sta *pre_sta; + struct mt7915_sta *pre_msta; + u8 flags = MT76_WED_DEFAULT; + int tmp_idx; if (enabled) set_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags); @@ -1280,6 +1292,34 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, if (!msta->wcid.sta) return; + if (mtk_wed_device_active(&dev->mt76.mmio.wed) && + !is_mt7915(&dev->mt76) && + (msta->wcid.idx < min || msta->wcid.idx > max - 1)) { + pre_sta = kmemdup(sta, sizeof(*sta) + sizeof(*msta), GFP_KERNEL | __GFP_ZERO); + pre_msta = (struct mt7915_sta *)pre_sta->drv_priv; + + flags = test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) ? + MT76_WED_WDS_ACTIVE : MT76_WED_ACTIVE; + + tmp_idx = __mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA, flags); + if (tmp_idx == -1) + goto error; + pre_msta->wcid.idx = (u16)tmp_idx; + mt7915_mac_sta_add(&dev->mt76, vif, pre_sta); + rcu_assign_pointer(dev->mt76.wcid[tmp_idx], &msta->wcid); + + tmp_idx = msta->wcid.idx; + msta->wcid.idx = pre_msta->wcid.idx; + pre_msta->wcid.idx = (u16)tmp_idx; + rcu_assign_pointer(dev->mt76.wcid[tmp_idx], NULL); + + synchronize_rcu(); + mt7915_mac_sta_remove(&dev->mt76, vif, pre_sta); + +error: + kfree(pre_sta); + } + mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta); } @@ -1726,15 +1766,19 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, if (!mtk_wed_device_active(wed)) return -ENODEV; - if (msta->wcid.idx > 0xff) + if (msta->wcid.idx > MT7915_WTBL_STA) return -EIO; path->type = DEV_PATH_MTK_WDMA; path->dev = ctx->dev; path->mtk_wdma.wdma_idx = wed->wdma_idx; path->mtk_wdma.bss = mvif->mt76.idx; - path->mtk_wdma.wcid = is_mt7915(&dev->mt76) ? msta->wcid.idx : 0x3ff; path->mtk_wdma.queue = phy != &dev->phy; + if (test_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags) || + is_mt7915(&dev->mt76)) + path->mtk_wdma.wcid = msta->wcid.idx; + else + path->mtk_wdma.wcid = 0x3ff; ctx->dev = NULL; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 9d790f234e82..32c5aa1a361e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2385,10 +2385,20 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev) mt76_connac_mcu_del_wtbl_all(&dev->mt76); - if ((mtk_wed_device_active(&dev->mt76.mmio.wed) && - is_mt7915(&dev->mt76)) || - !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) - mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), 0, 0, 0); +#ifdef CONFIG_NET_MEDIATEK_SOC_WED + if (mtk_wed_device_active(&dev->mt76.mmio.wed)) { + if (is_mt7915(&dev->mt76) || + !mtk_wed_get_rx_capa(&dev->mt76.mmio.wed)) + ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(CAPABILITY), + 0, 0, 0); + else + ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), + MCU_WA_PARAM_WED_VERSION, + dev->mt76.mmio.wed.rev_id, 0); + if (ret) + return ret; + } +#endif ret = mt7915_mcu_set_mwds(dev, 1); if (ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index 49476a4182fd..c3dd0cb4a5d3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -278,6 +278,7 @@ enum { MCU_WA_PARAM_PDMA_RX = 0x04, MCU_WA_PARAM_CPU_UTIL = 0x0b, MCU_WA_PARAM_RED = 0x0e, + MCU_WA_PARAM_WED_VERSION = 0x32, MCU_WA_PARAM_RED_SETTING = 0x40, }; diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c index 95b3dc96e4c4..7fac9c79ebdf 100644 --- a/drivers/net/wireless/mediatek/mt76/util.c +++ b/drivers/net/wireless/mediatek/mt76/util.c @@ -42,9 +42,11 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, } EXPORT_SYMBOL_GPL(____mt76_poll_msec); -int mt76_wcid_alloc(u32 *mask, int size) +int __mt76_wcid_alloc(u32 *mask, int size, u8 flag) { int i, idx = 0, cur; + int min = MT76_WED_WDS_MIN; + int max = MT76_WED_WDS_MAX; for (i = 0; i < DIV_ROUND_UP(size, 32); i++) { idx = ffs(~mask[i]); @@ -53,16 +55,45 @@ int mt76_wcid_alloc(u32 *mask, int size) idx--; cur = i * 32 + idx; - if (cur >= size) + + switch (flag) { + case MT76_WED_ACTIVE: + if (cur >= min && cur < max) + continue; + + if (cur >= size) { + u32 end = max - min - 1; + + i = min / 32; + idx = ffs(~mask[i] & GENMASK(end, 0)); + if (!idx) + goto error; + idx--; + cur = min + idx; + } + break; + case MT76_WED_WDS_ACTIVE: + if (cur < min) + continue; + if (cur >= max) + goto error; + + break; + default: + if (cur >= size) + goto error; + break; + } mask[i] |= BIT(idx); return cur; } +error: return -1; } -EXPORT_SYMBOL_GPL(mt76_wcid_alloc); +EXPORT_SYMBOL_GPL(__mt76_wcid_alloc); int mt76_get_min_avg_rssi(struct mt76_dev *dev, u8 phy_idx) { diff --git a/drivers/net/wireless/mediatek/mt76/util.h b/drivers/net/wireless/mediatek/mt76/util.h index 260965dde94c..99b7263c0a20 100644 --- a/drivers/net/wireless/mediatek/mt76/util.h +++ b/drivers/net/wireless/mediatek/mt76/util.h @@ -27,7 +27,12 @@ enum { #define MT76_INCR(_var, _size) \ (_var = (((_var) + 1) % (_size))) -int mt76_wcid_alloc(u32 *mask, int size); +int __mt76_wcid_alloc(u32 *mask, int size, u8 flags); + +static inline int mt76_wcid_alloc(u32 *mask, int size) +{ + return __mt76_wcid_alloc(mask, size, 0); +} static inline void mt76_wcid_mask_set(u32 *mask, int idx)