mt76: allow drivers to drop rx packets early
authorFelix Fietkau <nbd@nbd.name>
Fri, 3 Dec 2021 17:01:52 +0000 (18:01 +0100)
committerFelix Fietkau <nbd@nbd.name>
Sun, 19 Dec 2021 14:24:02 +0000 (15:24 +0100)
This can be used to free received events without allocating an extra skb

Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/dma.c
drivers/net/wireless/mediatek/mt76/mt76.h

index 5e1c150..3a9af89 100644 (file)
@@ -572,9 +572,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
                if (data_len < len + q->buf_offset) {
                        dev_kfree_skb(q->rx_head);
                        q->rx_head = NULL;
-
-                       skb_free_frag(data);
-                       continue;
+                       goto free_frag;
                }
 
                if (q->rx_head) {
@@ -582,11 +580,14 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
                        continue;
                }
 
+               if (!more && dev->drv->rx_check &&
+                   !(dev->drv->rx_check(dev, data, len)))
+                       goto free_frag;
+
                skb = build_skb(data, q->buf_size);
-               if (!skb) {
-                       skb_free_frag(data);
-                       continue;
-               }
+               if (!skb)
+                       goto free_frag;
+
                skb_reserve(skb, q->buf_offset);
 
                if (q == &dev->q_rx[MT_RXQ_MCU]) {
@@ -603,6 +604,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
                }
 
                dev->drv->rx_skb(dev, q - dev->q_rx, skb);
+               continue;
+
+free_frag:
+               skb_free_frag(data);
        }
 
        mt76_dma_rx_fill(dev, q);
index 2397421..8edbf42 100644 (file)
@@ -373,6 +373,8 @@ struct mt76_driver_ops {
 
        bool (*tx_status_data)(struct mt76_dev *dev, u8 *update);
 
+       bool (*rx_check)(struct mt76_dev *dev, void *data, int len);
+
        void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q,
                       struct sk_buff *skb);