diff --git a/mt7603.h b/mt7603.h index 5c89b4996..6476cc677 100644 --- a/mt7603.h +++ b/mt7603.h @@ -69,9 +69,16 @@ struct mt7603_mcu { bool running; }; +struct mt7603_vif { + u8 idx; + + struct mt76_wcid wcid; +}; + struct mt7603_sta { struct mt76_wcid wcid; /* must be first */ + struct mt7603_vif *vif; struct ieee80211_tx_rate rates[8]; int rate_count; int n_rates; @@ -84,12 +91,6 @@ struct mt7603_sta { int ampdu_acked; }; -struct mt7603_vif { - u8 idx; - - struct mt7603_sta sta; -}; - #define MT7603_CB_DMA_DONE BIT(0) #define MT7603_CB_TXS_DONE BIT(1) #define MT7603_CB_TXS_FAILED BIT(2) diff --git a/mt7603_beacon.c b/mt7603_beacon.c index 01962d40e..59474cf8b 100644 --- a/mt7603_beacon.c +++ b/mt7603_beacon.c @@ -38,7 +38,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) return; mt76_tx_queue_skb(&dev->mt76, &dev->mt76.q_tx[MT_TXQ_BEACON], skb, - &mvif->sta.wcid, NULL); + &mvif->wcid, NULL); } static void @@ -123,7 +123,7 @@ void mt7603_pre_tbtt_tasklet(unsigned long arg) struct ieee80211_vif *vif = info->control.vif; struct mt7603_vif *mvif = (struct mt7603_vif *) vif->drv_priv; - mt76_tx_queue_skb(&dev->mt76, q, skb, &mvif->sta.wcid, NULL); + mt76_tx_queue_skb(&dev->mt76, q, skb, &mvif->wcid, NULL); } mt76_queue_kick(dev, q); spin_unlock_bh(&q->lock); diff --git a/mt7603_mac.c b/mt7603_mac.c index ba41ed7bc..7811eed07 100644 --- a/mt7603_mac.c +++ b/mt7603_mac.c @@ -351,12 +351,20 @@ mt7603_get_rate(struct mt7603_dev *dev, struct ieee80211_supported_band *sband, } static struct mt76_wcid * -mt7603_rx_get_wcid(struct mt7603_dev *dev, u8 idx) +mt7603_rx_get_wcid(struct mt7603_dev *dev, u8 idx, bool unicast) { + struct mt7603_sta *sta; + struct mt76_wcid *wcid; + if (idx >= ARRAY_SIZE(dev->wcid)) return NULL; - return rcu_dereference(dev->wcid[idx]); + wcid = rcu_dereference(dev->wcid[idx]); + if (unicast || !wcid) + return wcid; + + sta = container_of(wcid, struct mt7603_sta, wcid); + return &sta->vif->wcid; } int @@ -369,6 +377,7 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) u32 rxd0 = le32_to_cpu(rxd[0]); u32 rxd1 = le32_to_cpu(rxd[1]); u32 rxd2 = le32_to_cpu(rxd[2]); + bool unicast = rxd1 & MT_RXD1_NORMAL_U2M; bool remove_pad; int idx; int i; @@ -380,7 +389,7 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) i >>= 1; idx = FIELD_GET(MT_RXD2_NORMAL_WLAN_IDX, rxd2); - status->wcid = mt7603_rx_get_wcid(dev, idx); + status->wcid = mt7603_rx_get_wcid(dev, idx, unicast); status->band = sband->band; if (i < sband->n_channels) @@ -472,7 +481,7 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) if (!status->wcid || !ieee80211_is_data_qos(hdr->frame_control)) return 0; - status->aggr = true; + status->aggr = unicast; status->tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; status->seqno = hdr->seq_ctrl >> 4; diff --git a/mt7603_main.c b/mt7603_main.c index 9e7574914..44b802e54 100644 --- a/mt7603_main.c +++ b/mt7603_main.c @@ -58,7 +58,7 @@ mt7603_txq_init(struct mt7603_dev *dev, struct ieee80211_txq *txq) mtxq->wcid = &sta->wcid; } else { struct mt7603_vif *mvif = (struct mt7603_vif *) txq->vif->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = &mvif->wcid; } mt76_txq_init(&dev->mt76, txq); @@ -89,14 +89,14 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) idx = MT7603_WTBL_RESERVED - 1 - mvif->idx; dev->vif_mask |= BIT(mvif->idx); - mvif->sta.wcid.idx = idx; - mvif->sta.wcid.hw_key_idx = -1; + mvif->wcid.idx = idx; + mvif->wcid.hw_key_idx = -1; eth_broadcast_addr(bc_addr); mt7603_wtbl_init(dev, idx, mvif->idx, bc_addr); mt7603_wtbl_set_ps(dev, idx, false); - rcu_assign_pointer(dev->wcid[idx], &mvif->sta.wcid); + rcu_assign_pointer(dev->wcid[idx], &mvif->wcid); mt7603_txq_init(dev, vif->txq); out: @@ -110,7 +110,7 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt7603_vif *mvif = (struct mt7603_vif *) vif->drv_priv; struct mt7603_dev *dev = hw->priv; - int idx = mvif->sta.wcid.idx; + int idx = mvif->wcid.idx; mt7603_beacon_set_timer(dev, mvif->idx, 0); @@ -345,7 +345,7 @@ mt7603_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct mt7603_dev *dev = hw->priv; struct mt7603_vif *mvif = (struct mt7603_vif *) vif->drv_priv; struct mt7603_sta *msta = sta ? (struct mt7603_sta *) sta->drv_priv : NULL; - struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->sta.wcid; + struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->wcid; int idx = key->keyidx; /* diff --git a/mt76x2.h b/mt76x2.h index a12dfce8c..17df17afd 100644 --- a/mt76x2.h +++ b/mt76x2.h @@ -144,6 +144,7 @@ struct mt76x2_vif { struct mt76x2_sta { struct mt76_wcid wcid; /* must be first */ + struct mt76x2_vif *vif; struct mt76x2_tx_status status; int n_frames; }; diff --git a/mt76x2_mac.c b/mt76x2_mac.c index e047975dc..4bbca4f13 100644 --- a/mt76x2_mac.c +++ b/mt76x2_mac.c @@ -279,12 +279,20 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb) } static struct mt76_wcid * -mt76x2_rx_get_wcid(struct mt76x2_dev *dev, u8 idx) +mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, u8 idx, bool unicast) { + struct mt76x2_sta *sta; + struct mt76_wcid *wcid; + if (idx >= ARRAY_SIZE(dev->wcid)) return NULL; - return rcu_dereference(dev->wcid[idx]); + wcid = rcu_dereference(dev->wcid[idx]); + if (unicast || !wcid) + return wcid; + + sta = container_of(wcid, struct mt76x2_sta, wcid); + return &sta->vif->group_wcid; } int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, @@ -295,11 +303,12 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, u32 ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); u16 tid_sn = le16_to_cpu(rxwi->tid_sn); + bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST); u8 wcid; int len; wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl); - status->wcid = mt76x2_rx_get_wcid(dev, wcid); + status->wcid = mt76x2_rx_get_sta_wcid(dev, wcid, unicast); if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) mt76x2_remove_hdr_pad(skb); diff --git a/mt76x2_main.c b/mt76x2_main.c index bc0804012..08fe804c6 100644 --- a/mt76x2_main.c +++ b/mt76x2_main.c @@ -273,6 +273,7 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; } + msta->vif = mvif; msta->wcid.sta = 1; msta->wcid.idx = idx; msta->wcid.hw_key_idx = -1;