Commit 3f1c16fd authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

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: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 6e39e9a1
...@@ -1195,6 +1195,7 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) ...@@ -1195,6 +1195,7 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
out: out:
rcu_read_unlock(); rcu_read_unlock();
} }
EXPORT_SYMBOL_GPL(mt7921_mac_add_txs);
void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb) struct sk_buff *skb)
......
...@@ -434,6 +434,7 @@ int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb, ...@@ -434,6 +434,7 @@ int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
struct sk_buff *skb, int seq); struct sk_buff *skb, int seq);
bool mt7921e_rx_check(struct mt76_dev *mdev, void *data, int len);
void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb); struct sk_buff *skb);
int mt7921e_driver_own(struct mt7921_dev *dev); int mt7921e_driver_own(struct mt7921_dev *dev);
......
...@@ -134,6 +134,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev, ...@@ -134,6 +134,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
.token_size = MT7921_TOKEN_SIZE, .token_size = MT7921_TOKEN_SIZE,
.tx_prepare_skb = mt7921e_tx_prepare_skb, .tx_prepare_skb = mt7921e_tx_prepare_skb,
.tx_complete_skb = mt7921e_tx_complete_skb, .tx_complete_skb = mt7921e_tx_complete_skb,
.rx_check = mt7921e_rx_check,
.rx_skb = mt7921e_queue_rx_skb, .rx_skb = mt7921e_queue_rx_skb,
.rx_poll_complete = mt7921_rx_poll_complete, .rx_poll_complete = mt7921_rx_poll_complete,
.sta_ps = mt7921_sta_ps, .sta_ps = mt7921_sta_ps,
......
...@@ -148,14 +148,15 @@ mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t, ...@@ -148,14 +148,15 @@ mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t,
} }
static void 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_dev *mdev = &dev->mt76;
struct mt76_txwi_cache *txwi; struct mt76_txwi_cache *txwi;
struct ieee80211_sta *sta = NULL; struct ieee80211_sta *sta = NULL;
struct sk_buff *skb, *tmp;
void *end = data + len;
LIST_HEAD(free_list); LIST_HEAD(free_list);
struct sk_buff *tmp;
bool wake = false; bool wake = false;
u8 i, count; u8 i, count;
...@@ -168,6 +169,9 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb) ...@@ -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. * 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)); 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++) { for (i = 0; i < count; i++) {
u32 msdu, info = le32_to_cpu(free->info[i]); u32 msdu, info = le32_to_cpu(free->info[i]);
u8 stat; u8 stat;
...@@ -208,8 +212,6 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb) ...@@ -208,8 +212,6 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb)
if (wake) if (wake)
mt76_set_tx_blocked(&dev->mt76, false); mt76_set_tx_blocked(&dev->mt76, false);
napi_consume_skb(skb, 1);
list_for_each_entry_safe(skb, tmp, &free_list, list) { list_for_each_entry_safe(skb, tmp, &free_list, list) {
skb_list_del_init(skb); skb_list_del_init(skb);
napi_consume_skb(skb, 1); napi_consume_skb(skb, 1);
...@@ -222,6 +224,27 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb) ...@@ -222,6 +224,27 @@ mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb)
mt76_worker_schedule(&dev->mt76.tx_worker); 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, void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb) struct sk_buff *skb)
{ {
...@@ -233,7 +256,8 @@ void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, ...@@ -233,7 +256,8 @@ void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
switch (type) { switch (type) {
case PKT_TYPE_TXRX_NOTIFY: 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; break;
default: default:
mt7921_queue_rx_skb(mdev, q, skb); mt7921_queue_rx_skb(mdev, q, skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment