Commit b99ac751 authored by Gerhard Engleder's avatar Gerhard Engleder Committed by David S. Miller

tsnep: Improve TX length handling

TX length can by calculated more efficient during map and unmap of
fragments. Another reason is that, by moving TX statistic counting to
tsnep_tx_poll() it can be used there for XDP too.
Signed-off-by: default avatarGerhard Engleder <gerhard@engleder-embedded.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4b222008
...@@ -262,14 +262,14 @@ static int tsnep_tx_ring_init(struct tsnep_tx *tx) ...@@ -262,14 +262,14 @@ static int tsnep_tx_ring_init(struct tsnep_tx *tx)
return retval; return retval;
} }
static void tsnep_tx_activate(struct tsnep_tx *tx, int index, bool last) static void tsnep_tx_activate(struct tsnep_tx *tx, int index, int length,
bool last)
{ {
struct tsnep_tx_entry *entry = &tx->entry[index]; struct tsnep_tx_entry *entry = &tx->entry[index];
entry->properties = 0; entry->properties = 0;
if (entry->skb) { if (entry->skb) {
entry->properties = entry->properties = length & TSNEP_DESC_LENGTH_MASK;
skb_pagelen(entry->skb) & TSNEP_DESC_LENGTH_MASK;
entry->properties |= TSNEP_DESC_INTERRUPT_FLAG; entry->properties |= TSNEP_DESC_INTERRUPT_FLAG;
if (skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS) if (skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS)
entry->properties |= TSNEP_DESC_EXTENDED_WRITEBACK_FLAG; entry->properties |= TSNEP_DESC_EXTENDED_WRITEBACK_FLAG;
...@@ -334,6 +334,7 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count) ...@@ -334,6 +334,7 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count)
struct tsnep_tx_entry *entry; struct tsnep_tx_entry *entry;
unsigned int len; unsigned int len;
dma_addr_t dma; dma_addr_t dma;
int map_len = 0;
int i; int i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
...@@ -356,15 +357,18 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count) ...@@ -356,15 +357,18 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count)
dma_unmap_addr_set(entry, dma, dma); dma_unmap_addr_set(entry, dma, dma);
entry->desc->tx = __cpu_to_le64(dma); entry->desc->tx = __cpu_to_le64(dma);
map_len += len;
} }
return 0; return map_len;
} }
static void tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count) static int tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count)
{ {
struct device *dmadev = tx->adapter->dmadev; struct device *dmadev = tx->adapter->dmadev;
struct tsnep_tx_entry *entry; struct tsnep_tx_entry *entry;
int map_len = 0;
int i; int i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
...@@ -381,9 +385,12 @@ static void tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count) ...@@ -381,9 +385,12 @@ static void tsnep_tx_unmap(struct tsnep_tx *tx, int index, int count)
dma_unmap_addr(entry, dma), dma_unmap_addr(entry, dma),
dma_unmap_len(entry, len), dma_unmap_len(entry, len),
DMA_TO_DEVICE); DMA_TO_DEVICE);
map_len += entry->len;
entry->len = 0; entry->len = 0;
} }
} }
return map_len;
} }
static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
...@@ -392,6 +399,7 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, ...@@ -392,6 +399,7 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
unsigned long flags; unsigned long flags;
int count = 1; int count = 1;
struct tsnep_tx_entry *entry; struct tsnep_tx_entry *entry;
int length;
int i; int i;
int retval; int retval;
...@@ -415,7 +423,7 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, ...@@ -415,7 +423,7 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
entry->skb = skb; entry->skb = skb;
retval = tsnep_tx_map(skb, tx, count); retval = tsnep_tx_map(skb, tx, count);
if (retval != 0) { if (retval < 0) {
tsnep_tx_unmap(tx, tx->write, count); tsnep_tx_unmap(tx, tx->write, count);
dev_kfree_skb_any(entry->skb); dev_kfree_skb_any(entry->skb);
entry->skb = NULL; entry->skb = NULL;
...@@ -428,12 +436,13 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, ...@@ -428,12 +436,13 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
length = retval;
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
tsnep_tx_activate(tx, (tx->write + i) % TSNEP_RING_SIZE, tsnep_tx_activate(tx, (tx->write + i) % TSNEP_RING_SIZE, length,
i == (count - 1)); i == (count - 1));
tx->write = (tx->write + count) % TSNEP_RING_SIZE; tx->write = (tx->write + count) % TSNEP_RING_SIZE;
...@@ -449,9 +458,6 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, ...@@ -449,9 +458,6 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb,
netif_stop_queue(tx->adapter->netdev); netif_stop_queue(tx->adapter->netdev);
} }
tx->packets++;
tx->bytes += skb_pagelen(entry->skb) + ETH_FCS_LEN;
spin_unlock_irqrestore(&tx->lock, flags); spin_unlock_irqrestore(&tx->lock, flags);
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -463,6 +469,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget) ...@@ -463,6 +469,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
int budget = 128; int budget = 128;
struct tsnep_tx_entry *entry; struct tsnep_tx_entry *entry;
int count; int count;
int length;
spin_lock_irqsave(&tx->lock, flags); spin_lock_irqsave(&tx->lock, flags);
...@@ -485,7 +492,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget) ...@@ -485,7 +492,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
if (skb_shinfo(entry->skb)->nr_frags > 0) if (skb_shinfo(entry->skb)->nr_frags > 0)
count += skb_shinfo(entry->skb)->nr_frags; count += skb_shinfo(entry->skb)->nr_frags;
tsnep_tx_unmap(tx, tx->read, count); length = tsnep_tx_unmap(tx, tx->read, count);
if ((skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS) && if ((skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS) &&
(__le32_to_cpu(entry->desc_wb->properties) & (__le32_to_cpu(entry->desc_wb->properties) &
...@@ -512,6 +519,9 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget) ...@@ -512,6 +519,9 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
tx->read = (tx->read + count) % TSNEP_RING_SIZE; tx->read = (tx->read + count) % TSNEP_RING_SIZE;
tx->packets++;
tx->bytes += length + ETH_FCS_LEN;
budget--; budget--;
} while (likely(budget)); } while (likely(budget));
......
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