[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