diff options
author | Lorenzo Bianconi <lorenzo@kernel.org> | 2021-12-28 13:01:19 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2022-02-03 13:57:58 +0100 |
commit | 3f1c16fd8e00551763c7f75a2e24e735a33699f2 (patch) | |
tree | a75966ce9bbbbc1925d896127bf4a2b40ec36cdc /drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c | |
parent | 6e39e9a19cbe640897a4232dd67ae6836a224c0a (diff) |
mt76: mt7921e: process txfree and txstatus without allocating skbs
Similar to mt7915 driver, process txfree and txstatus without allocating
skbs in order to reduce pressure on the memory allocator
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c index a63ef5de5115..8ca58293ddf1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c @@ -148,14 +148,15 @@ out: } static void -mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921e_mac_tx_free(struct mt7921_dev *dev, void *data, int len) { - struct mt7921_tx_free *free = (struct mt7921_tx_free *)skb->data; + struct mt7921_tx_free *free = (struct mt7921_tx_free *)data; struct mt76_dev *mdev = &dev->mt76; struct mt76_txwi_cache *txwi; struct ieee80211_sta *sta = NULL; + struct sk_buff *skb, *tmp; + void *end = data + len; LIST_HEAD(free_list); - struct sk_buff *tmp; bool wake = false; u8 i, count; @@ -168,6 +169,9 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb) * Should avoid accessing WTBL to get Tx airtime, and use it instead. */ count = FIELD_GET(MT_TX_FREE_MSDU_CNT, le16_to_cpu(free->ctrl)); + if (WARN_ON_ONCE((void *)&free->info[count] > end)) + return; + for (i = 0; i < count; i++) { u32 msdu, info = le32_to_cpu(free->info[i]); u8 stat; @@ -208,8 +212,6 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb) if (wake) mt76_set_tx_blocked(&dev->mt76, false); - napi_consume_skb(skb, 1); - list_for_each_entry_safe(skb, tmp, &free_list, list) { skb_list_del_init(skb); napi_consume_skb(skb, 1); @@ -222,6 +224,27 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb) mt76_worker_schedule(&dev->mt76.tx_worker); } +bool mt7921e_rx_check(struct mt76_dev *mdev, void *data, int len) +{ + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + __le32 *rxd = (__le32 *)data; + __le32 *end = (__le32 *)&rxd[len / 4]; + enum rx_pkt_type type; + + type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0])); + switch (type) { + case PKT_TYPE_TXRX_NOTIFY: + mt7921e_mac_tx_free(dev, data, len); + return false; + case PKT_TYPE_TXS: + for (rxd += 2; rxd + 8 <= end; rxd += 8) + mt7921_mac_add_txs(dev, rxd); + return false; + default: + return true; + } +} + void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb) { @@ -233,7 +256,8 @@ void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, switch (type) { case PKT_TYPE_TXRX_NOTIFY: - mt7921_mac_tx_free(dev, skb); + mt7921e_mac_tx_free(dev, skb->data, skb->len); + napi_consume_skb(skb, 1); break; default: mt7921_queue_rx_skb(mdev, q, skb); |