[PATCH wireless-next v3 2/8] wifi: mac80211: change public RX API to use link stations
Jeff Johnson
jeff.johnson at oss.qualcomm.com
Thu Aug 20 10:56:14 PDT 2026
On 8/19/2026 6:57 AM, Benjamin Berg wrote:
> diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
> index abbe65cbcd89..3da06a55913e 100644
> --- a/drivers/net/wireless/mediatek/mt76/mac80211.c
> +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
> @@ -1255,7 +1255,7 @@ EXPORT_SYMBOL(mt76_rx_signal);
> static void
> mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
> struct ieee80211_hw **hw,
> - struct ieee80211_sta **sta)
> + struct ieee80211_link_sta **link_sta)
> {
> struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
> struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
> @@ -1302,11 +1302,15 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
> sizeof(mstat.chain_signal));
>
> if (mstat.wcid) {
> - status->link_valid = mstat.wcid->link_valid;
> - status->link_id = mstat.wcid->link_id;
> + struct ieee80211_sta *sta = wcid_to_sta(mstat.wcid);
> +
> + if (mstat.wcid->link_valid)
> + *link_sta =
> + rcu_dereference(sta->link[mstat.wcid->link_id]);
> + else
> + *link_sta = &sta->deflink;
> }
>
> - *sta = wcid_to_sta(mstat.wcid);
> *hw = mt76_phy_hw(dev, mstat.phy_idx);
> }
>
> @@ -1530,7 +1534,7 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
> void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
> struct napi_struct *napi)
> {
> - struct ieee80211_sta *sta;
> + struct ieee80211_link_sta *link_sta;
My review agent says:
**Issue 1 — mt76: uninitialized `link_sta` pointer on the no-wcid path.**
In `mt76_rx_complete()`, `link_sta` is declared but not initialized to NULL.
Then `mt76_rx_convert()` is called, which only sets `*link_sta` when
`mstat.wcid != NULL`. If `mstat.wcid` is NULL, `link_sta` remains
uninitialized and is then passed to `ieee80211_rx_list()`. This is a use of
an uninitialized pointer. The fix is trivially `= NULL`.
> struct ieee80211_hw *hw;
> struct sk_buff *skb, *tmp;
> LIST_HEAD(list);
> @@ -1541,8 +1545,8 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
>
> mt76_check_ccmp_pn(skb);
> skb_shinfo(skb)->frag_list = NULL;
> - mt76_rx_convert(dev, skb, &hw, &sta);
> - ieee80211_rx_list(hw, sta, skb, &list);
> + mt76_rx_convert(dev, skb, &hw, &link_sta);
> + ieee80211_rx_list(hw, link_sta, skb, &list);
>
> /* subsequent amsdu frames */
> while (nskb) {
> @@ -1550,8 +1554,8 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
> nskb = nskb->next;
> skb->next = NULL;
>
> - mt76_rx_convert(dev, skb, &hw, &sta);
> - ieee80211_rx_list(hw, sta, skb, &list);
> + mt76_rx_convert(dev, skb, &hw, &link_sta);
> + ieee80211_rx_list(hw, link_sta, skb, &list);
> }
> }
> spin_unlock(&dev->rx_lock);
More information about the ath12k
mailing list