Commit 481e34a7 authored by Felix Fietkau's avatar Felix Fietkau
Browse files

mt76: mt7915: simplify aggregation session check



Use the txwi data as primary source information to avoid touching skb data
Use bitfield instead of state variable + spinlock

Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 5c4b29fd
Loading
Loading
Loading
Loading
+15 −29
Original line number Diff line number Diff line
@@ -765,45 +765,29 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
	return 0;
}

static inline bool
mt7915_tx_check_aggr_tid(struct mt7915_sta *msta, u8 tid)
{
	bool ret = false;

	spin_lock_bh(&msta->ampdu_lock);
	if (msta->ampdu_state[tid] == MT7915_AGGR_STOP)
		ret = true;
	spin_unlock_bh(&msta->ampdu_lock);

	return ret;
}

static void
mt7915_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	struct mt7915_sta *msta;
	u16 tid;

	if (!sta->ht_cap.ht_supported)
		return;
	u16 fc, tid;
	u32 val;

	if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
	if (!sta || !sta->ht_cap.ht_supported)
		return;

	if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
	tid = FIELD_GET(MT_TXD1_TID, le32_to_cpu(txwi[1]));
	if (tid >= 6) /* skip VO queue */
		return;

	if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE)))
	val = le32_to_cpu(txwi[2]);
	fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
	     FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
	if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
		return;

	msta = (struct mt7915_sta *)sta->drv_priv;
	tid = ieee80211_get_tid(hdr);

	if (mt7915_tx_check_aggr_tid(msta, tid)) {
	if (!test_and_set_bit(tid, &msta->ampdu_state))
		ieee80211_start_tx_ba_session(sta, tid, 0);
		mt7915_set_aggr_state(msta, tid, MT7915_AGGR_PROGRESS);
	}
}

static inline void
@@ -840,8 +824,6 @@ mt7915_tx_complete_status(struct mt76_dev *mdev, struct sk_buff *skb,

	if (info->flags & IEEE80211_TX_CTL_AMPDU)
		info->flags |= IEEE80211_TX_STAT_AMPDU;
	else if (sta)
		mt7915_tx_check_aggr(sta, skb);

	if (stat)
		ieee80211_tx_info_clear_status(info);
@@ -931,6 +913,10 @@ void mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)

		mt7915_txp_skb_unmap(mdev, txwi);
		if (txwi->skb) {
			void *txwi_ptr = mt76_get_txwi_ptr(mdev, txwi);

			if (likely(txwi->skb->protocol != cpu_to_be16(ETH_P_PAE)))
				mt7915_tx_check_aggr(sta, txwi_ptr);
			mt7915_tx_complete_status(mdev, txwi->skb, sta, stat);
			txwi->skb = NULL;
		}
+3 −5
Original line number Diff line number Diff line
@@ -498,7 +498,6 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
	INIT_LIST_HEAD(&msta->rc_list);
	INIT_LIST_HEAD(&msta->stats_list);
	INIT_LIST_HEAD(&msta->poll_list);
	spin_lock_init(&msta->ampdu_lock);
	msta->vif = mvif;
	msta->wcid.sta = 1;
	msta->wcid.idx = idx;
@@ -610,22 +609,21 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
	case IEEE80211_AMPDU_TX_OPERATIONAL:
		mtxq->aggr = true;
		mtxq->send_bar = false;
		mt7915_set_aggr_state(msta, tid, MT7915_AGGR_OPERATIONAL);
		mt7915_mcu_add_tx_ba(dev, params, true);
		break;
	case IEEE80211_AMPDU_TX_STOP_FLUSH:
	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
		mtxq->aggr = false;
		mt7915_set_aggr_state(msta, tid, MT7915_AGGR_STOP);
		clear_bit(tid, &msta->ampdu_state);
		mt7915_mcu_add_tx_ba(dev, params, false);
		break;
	case IEEE80211_AMPDU_TX_START:
		mt7915_set_aggr_state(msta, tid, MT7915_AGGR_START);
		set_bit(tid, &msta->ampdu_state);
		ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
		break;
	case IEEE80211_AMPDU_TX_STOP_CONT:
		mtxq->aggr = false;
		mt7915_set_aggr_state(msta, tid, MT7915_AGGR_STOP);
		clear_bit(tid, &msta->ampdu_state);
		mt7915_mcu_add_tx_ba(dev, params, false);
		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
		break;
+1 −18
Original line number Diff line number Diff line
@@ -62,13 +62,6 @@ enum mt7915_rxq_id {
	MT7915_RXQ_MCU_WA,
};

enum mt7915_ampdu_state {
	MT7915_AGGR_STOP,
	MT7915_AGGR_PROGRESS,
	MT7915_AGGR_START,
	MT7915_AGGR_OPERATIONAL
};

struct mt7915_sta_stats {
	struct rate_info prob_rate;
	struct rate_info tx_rate;
@@ -90,8 +83,7 @@ struct mt7915_sta {

	struct mt7915_sta_stats stats;

	spinlock_t ampdu_lock;
	enum mt7915_ampdu_state ampdu_state[IEEE80211_NUM_TIDS];
	unsigned long ampdu_state;
};

struct mt7915_vif {
@@ -278,15 +270,6 @@ static inline u8 mt7915_lmac_mapping(struct mt7915_dev *dev, u8 ac)
	return lmac_queue_map[ac];
}

static inline void
mt7915_set_aggr_state(struct mt7915_sta *msta, u8 tid,
		      enum mt7915_ampdu_state state)
{
	spin_lock_bh(&msta->ampdu_lock);
	msta->ampdu_state[tid] = state;
	spin_unlock_bh(&msta->ampdu_lock);
}

extern const struct ieee80211_ops mt7915_ops;
extern struct pci_driver mt7915_pci_driver;