mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 02:29:01 +00:00
196f3d586f
5.4.102 backported a lot of stuff that our WireGuard backport already did, in addition to other patches we had, so those patches were removed from that part of the series. In the process other patches were refreshed or reworked to account for upstream changes. This commit involved `update_kernel.sh -v -u 5.4`. Cc: John Audia <graysky@archlinux.us> Cc: David Bauer <mail@david-bauer.net> Cc: Petr Štetiar <ynezz@true.cz> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
211 lines
6.1 KiB
Diff
211 lines
6.1 KiB
Diff
From 9e58c8b410650b5a6eb5b8fad8474bd8425a4023 Mon Sep 17 00:00:00 2001
|
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Date: Sat, 19 Oct 2019 10:13:26 +0200
|
|
Subject: [PATCH 6/7] net: mvneta: make tx buffer array agnostic
|
|
|
|
Allow tx buffer array to contain both skb and xdp buffers in order to
|
|
enable xdp frame recycling adding XDP_TX verdict support
|
|
|
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/ethernet/marvell/mvneta.c | 66 +++++++++++++++++----------
|
|
1 file changed, 43 insertions(+), 23 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/marvell/mvneta.c
|
|
+++ b/drivers/net/ethernet/marvell/mvneta.c
|
|
@@ -565,6 +565,20 @@ struct mvneta_rx_desc {
|
|
};
|
|
#endif
|
|
|
|
+enum mvneta_tx_buf_type {
|
|
+ MVNETA_TYPE_SKB,
|
|
+ MVNETA_TYPE_XDP_TX,
|
|
+ MVNETA_TYPE_XDP_NDO,
|
|
+};
|
|
+
|
|
+struct mvneta_tx_buf {
|
|
+ enum mvneta_tx_buf_type type;
|
|
+ union {
|
|
+ struct xdp_frame *xdpf;
|
|
+ struct sk_buff *skb;
|
|
+ };
|
|
+};
|
|
+
|
|
struct mvneta_tx_queue {
|
|
/* Number of this TX queue, in the range 0-7 */
|
|
u8 id;
|
|
@@ -580,8 +594,8 @@ struct mvneta_tx_queue {
|
|
int tx_stop_threshold;
|
|
int tx_wake_threshold;
|
|
|
|
- /* Array of transmitted skb */
|
|
- struct sk_buff **tx_skb;
|
|
+ /* Array of transmitted buffers */
|
|
+ struct mvneta_tx_buf *buf;
|
|
|
|
/* Index of last TX DMA descriptor that was inserted */
|
|
int txq_put_index;
|
|
@@ -1793,14 +1807,9 @@ static void mvneta_txq_bufs_free(struct
|
|
int i;
|
|
|
|
for (i = 0; i < num; i++) {
|
|
+ struct mvneta_tx_buf *buf = &txq->buf[txq->txq_get_index];
|
|
struct mvneta_tx_desc *tx_desc = txq->descs +
|
|
txq->txq_get_index;
|
|
- struct sk_buff *skb = txq->tx_skb[txq->txq_get_index];
|
|
-
|
|
- if (skb) {
|
|
- bytes_compl += skb->len;
|
|
- pkts_compl++;
|
|
- }
|
|
|
|
mvneta_txq_inc_get(txq);
|
|
|
|
@@ -1808,9 +1817,12 @@ static void mvneta_txq_bufs_free(struct
|
|
dma_unmap_single(pp->dev->dev.parent,
|
|
tx_desc->buf_phys_addr,
|
|
tx_desc->data_size, DMA_TO_DEVICE);
|
|
- if (!skb)
|
|
+ if (!buf->skb)
|
|
continue;
|
|
- dev_kfree_skb_any(skb);
|
|
+
|
|
+ bytes_compl += buf->skb->len;
|
|
+ pkts_compl++;
|
|
+ dev_kfree_skb_any(buf->skb);
|
|
}
|
|
|
|
netdev_tx_completed_queue(nq, pkts_compl, bytes_compl);
|
|
@@ -2335,16 +2347,19 @@ static inline void
|
|
mvneta_tso_put_hdr(struct sk_buff *skb,
|
|
struct mvneta_port *pp, struct mvneta_tx_queue *txq)
|
|
{
|
|
- struct mvneta_tx_desc *tx_desc;
|
|
int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
|
|
+ struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
|
|
+ struct mvneta_tx_desc *tx_desc;
|
|
|
|
- txq->tx_skb[txq->txq_put_index] = NULL;
|
|
tx_desc = mvneta_txq_next_desc_get(txq);
|
|
tx_desc->data_size = hdr_len;
|
|
tx_desc->command = mvneta_skb_tx_csum(pp, skb);
|
|
tx_desc->command |= MVNETA_TXD_F_DESC;
|
|
tx_desc->buf_phys_addr = txq->tso_hdrs_phys +
|
|
txq->txq_put_index * TSO_HEADER_SIZE;
|
|
+ buf->type = MVNETA_TYPE_SKB;
|
|
+ buf->skb = NULL;
|
|
+
|
|
mvneta_txq_inc_put(txq);
|
|
}
|
|
|
|
@@ -2353,6 +2368,7 @@ mvneta_tso_put_data(struct net_device *d
|
|
struct sk_buff *skb, char *data, int size,
|
|
bool last_tcp, bool is_last)
|
|
{
|
|
+ struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
|
|
struct mvneta_tx_desc *tx_desc;
|
|
|
|
tx_desc = mvneta_txq_next_desc_get(txq);
|
|
@@ -2366,7 +2382,8 @@ mvneta_tso_put_data(struct net_device *d
|
|
}
|
|
|
|
tx_desc->command = 0;
|
|
- txq->tx_skb[txq->txq_put_index] = NULL;
|
|
+ buf->type = MVNETA_TYPE_SKB;
|
|
+ buf->skb = NULL;
|
|
|
|
if (last_tcp) {
|
|
/* last descriptor in the TCP packet */
|
|
@@ -2374,7 +2391,7 @@ mvneta_tso_put_data(struct net_device *d
|
|
|
|
/* last descriptor in SKB */
|
|
if (is_last)
|
|
- txq->tx_skb[txq->txq_put_index] = skb;
|
|
+ buf->skb = skb;
|
|
}
|
|
mvneta_txq_inc_put(txq);
|
|
return 0;
|
|
@@ -2459,6 +2476,7 @@ static int mvneta_tx_frag_process(struct
|
|
int i, nr_frags = skb_shinfo(skb)->nr_frags;
|
|
|
|
for (i = 0; i < nr_frags; i++) {
|
|
+ struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
|
|
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
|
void *addr = skb_frag_address(frag);
|
|
|
|
@@ -2478,12 +2496,13 @@ static int mvneta_tx_frag_process(struct
|
|
if (i == nr_frags - 1) {
|
|
/* Last descriptor */
|
|
tx_desc->command = MVNETA_TXD_L_DESC | MVNETA_TXD_Z_PAD;
|
|
- txq->tx_skb[txq->txq_put_index] = skb;
|
|
+ buf->skb = skb;
|
|
} else {
|
|
/* Descriptor in the middle: Not First, Not Last */
|
|
tx_desc->command = 0;
|
|
- txq->tx_skb[txq->txq_put_index] = NULL;
|
|
+ buf->skb = NULL;
|
|
}
|
|
+ buf->type = MVNETA_TYPE_SKB;
|
|
mvneta_txq_inc_put(txq);
|
|
}
|
|
|
|
@@ -2511,6 +2530,7 @@ static netdev_tx_t mvneta_tx(struct sk_b
|
|
struct mvneta_port *pp = netdev_priv(dev);
|
|
u16 txq_id = skb_get_queue_mapping(skb);
|
|
struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
|
|
+ struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
|
|
struct mvneta_tx_desc *tx_desc;
|
|
int len = skb->len;
|
|
int frags = 0;
|
|
@@ -2543,16 +2563,17 @@ static netdev_tx_t mvneta_tx(struct sk_b
|
|
goto out;
|
|
}
|
|
|
|
+ buf->type = MVNETA_TYPE_SKB;
|
|
if (frags == 1) {
|
|
/* First and Last descriptor */
|
|
tx_cmd |= MVNETA_TXD_FLZ_DESC;
|
|
tx_desc->command = tx_cmd;
|
|
- txq->tx_skb[txq->txq_put_index] = skb;
|
|
+ buf->skb = skb;
|
|
mvneta_txq_inc_put(txq);
|
|
} else {
|
|
/* First but not Last */
|
|
tx_cmd |= MVNETA_TXD_F_DESC;
|
|
- txq->tx_skb[txq->txq_put_index] = NULL;
|
|
+ buf->skb = NULL;
|
|
mvneta_txq_inc_put(txq);
|
|
tx_desc->command = tx_cmd;
|
|
/* Continue with other skb fragments */
|
|
@@ -3138,9 +3159,8 @@ static int mvneta_txq_sw_init(struct mvn
|
|
|
|
txq->last_desc = txq->size - 1;
|
|
|
|
- txq->tx_skb = kmalloc_array(txq->size, sizeof(*txq->tx_skb),
|
|
- GFP_KERNEL);
|
|
- if (!txq->tx_skb) {
|
|
+ txq->buf = kmalloc_array(txq->size, sizeof(*txq->buf), GFP_KERNEL);
|
|
+ if (!txq->buf) {
|
|
dma_free_coherent(pp->dev->dev.parent,
|
|
txq->size * MVNETA_DESC_ALIGNED_SIZE,
|
|
txq->descs, txq->descs_phys);
|
|
@@ -3152,7 +3172,7 @@ static int mvneta_txq_sw_init(struct mvn
|
|
txq->size * TSO_HEADER_SIZE,
|
|
&txq->tso_hdrs_phys, GFP_KERNEL);
|
|
if (!txq->tso_hdrs) {
|
|
- kfree(txq->tx_skb);
|
|
+ kfree(txq->buf);
|
|
dma_free_coherent(pp->dev->dev.parent,
|
|
txq->size * MVNETA_DESC_ALIGNED_SIZE,
|
|
txq->descs, txq->descs_phys);
|
|
@@ -3207,7 +3227,7 @@ static void mvneta_txq_sw_deinit(struct
|
|
{
|
|
struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id);
|
|
|
|
- kfree(txq->tx_skb);
|
|
+ kfree(txq->buf);
|
|
|
|
if (txq->tso_hdrs)
|
|
dma_free_coherent(pp->dev->dev.parent,
|