mt76: mt7615e: process txfree and txstatus without allocating skbs
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 28 Dec 2021 14:33:57 +0000 (15:33 +0100)
committerFelix Fietkau <nbd@nbd.name>
Thu, 3 Feb 2022 12:57:58 +0000 (13:57 +0100)
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>
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h

index 8f8a7bc..2d81cbf 100644 (file)
@@ -1642,9 +1642,10 @@ mt7615_mac_tx_free_token(struct mt7615_dev *dev, u16 token)
        mt7615_txwi_free(dev, txwi);
 }
 
        mt7615_txwi_free(dev, txwi);
 }
 
-static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
+static void mt7615_mac_tx_free(struct mt7615_dev *dev, void *data, int len)
 {
 {
-       struct mt7615_tx_free *free = (struct mt7615_tx_free *)skb->data;
+       struct mt7615_tx_free *free = (struct mt7615_tx_free *)data;
+       void *end = data + len;
        u8 i, count;
 
        mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_PSD], false);
        u8 i, count;
 
        mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_PSD], false);
@@ -1659,17 +1660,21 @@ static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
        if (is_mt7615(&dev->mt76)) {
                __le16 *token = &free->token[0];
 
        if (is_mt7615(&dev->mt76)) {
                __le16 *token = &free->token[0];
 
+               if (WARN_ON_ONCE((void *)&token[count] > end))
+                       return;
+
                for (i = 0; i < count; i++)
                        mt7615_mac_tx_free_token(dev, le16_to_cpu(token[i]));
        } else {
                __le32 *token = (__le32 *)&free->token[0];
 
                for (i = 0; i < count; i++)
                        mt7615_mac_tx_free_token(dev, le16_to_cpu(token[i]));
        } else {
                __le32 *token = (__le32 *)&free->token[0];
 
+               if (WARN_ON_ONCE((void *)&token[count] > end))
+                       return;
+
                for (i = 0; i < count; i++)
                        mt7615_mac_tx_free_token(dev, le32_to_cpu(token[i]));
        }
 
                for (i = 0; i < count; i++)
                        mt7615_mac_tx_free_token(dev, le32_to_cpu(token[i]));
        }
 
-       dev_kfree_skb(skb);
-
        rcu_read_lock();
        mt7615_mac_sta_poll(dev);
        rcu_read_unlock();
        rcu_read_lock();
        mt7615_mac_sta_poll(dev);
        rcu_read_unlock();
@@ -1677,6 +1682,28 @@ static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
        mt76_worker_schedule(&dev->mt76.tx_worker);
 }
 
        mt76_worker_schedule(&dev->mt76.tx_worker);
 }
 
+bool mt7615_rx_check(struct mt76_dev *mdev, void *data, int len)
+{
+       struct mt7615_dev *dev = container_of(mdev, struct mt7615_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:
+               mt7615_mac_tx_free(dev, data, len);
+               return false;
+       case PKT_TYPE_TXS:
+               for (rxd++; rxd + 7 <= end; rxd += 7)
+                       mt7615_mac_add_txs(dev, rxd);
+               return false;
+       default:
+               return true;
+       }
+}
+EXPORT_SYMBOL_GPL(mt7615_rx_check);
+
 void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
                         struct sk_buff *skb)
 {
 void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
                         struct sk_buff *skb)
 {
@@ -1698,7 +1725,8 @@ void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
                dev_kfree_skb(skb);
                break;
        case PKT_TYPE_TXRX_NOTIFY:
                dev_kfree_skb(skb);
                break;
        case PKT_TYPE_TXRX_NOTIFY:
-               mt7615_mac_tx_free(dev, skb);
+               mt7615_mac_tx_free(dev, skb->data, skb->len);
+               dev_kfree_skb(skb);
                break;
        case PKT_TYPE_RX_EVENT:
                mt7615_mcu_rx_event(dev, skb);
                break;
        case PKT_TYPE_RX_EVENT:
                mt7615_mcu_rx_event(dev, skb);
index 33f72f3..ce45c3b 100644 (file)
@@ -194,6 +194,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
                .token_size = MT7615_TOKEN_SIZE,
                .tx_prepare_skb = mt7615_tx_prepare_skb,
                .tx_complete_skb = mt7615_tx_complete_skb,
                .token_size = MT7615_TOKEN_SIZE,
                .tx_prepare_skb = mt7615_tx_prepare_skb,
                .tx_complete_skb = mt7615_tx_complete_skb,
+               .rx_check = mt7615_rx_check,
                .rx_skb = mt7615_queue_rx_skb,
                .rx_poll_complete = mt7615_rx_poll_complete,
                .sta_ps = mt7615_sta_ps,
                .rx_skb = mt7615_queue_rx_skb,
                .rx_poll_complete = mt7615_rx_poll_complete,
                .sta_ps = mt7615_sta_ps,
index 3b66aa7..600fa2b 100644 (file)
@@ -509,6 +509,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 void mt7615_tx_worker(struct mt76_worker *w);
 void mt7615_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
 void mt7615_tx_token_put(struct mt7615_dev *dev);
 void mt7615_tx_worker(struct mt76_worker *w);
 void mt7615_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
 void mt7615_tx_token_put(struct mt7615_dev *dev);
+bool mt7615_rx_check(struct mt76_dev *mdev, void *data, int len);
 void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
                         struct sk_buff *skb);
 void mt7615_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);
 void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
                         struct sk_buff *skb);
 void mt7615_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);