Skip to content

Commit

Permalink
net: systemport: Remove need for DMA descriptor
Browse files Browse the repository at this point in the history
All we do is write the length/status and address bits to a DMA
descriptor only to write its contents into on-chip registers right
after, eliminate this unnecessary step.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Florian Fainelli authored and David S. Miller committed Apr 23, 2019
1 parent 697cd36 commit 7e6e185
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 58 deletions.
56 changes: 7 additions & 49 deletions drivers/net/ethernet/broadcom/bcmsysport.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,6 @@ static inline void dma_desc_set_addr(struct bcm_sysport_priv *priv,
writel_relaxed(lower_32_bits(addr), d + DESC_ADDR_LO);
}

static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
struct dma_desc *desc,
unsigned int port)
{
/* Ports are latched, so write upper address first */
tdma_writel(priv, desc->addr_status_len, TDMA_WRITE_PORT_HI(port));
tdma_writel(priv, desc->addr_lo, TDMA_WRITE_PORT_LO(port));
}

/* Ethtool operations */
static void bcm_sysport_set_rx_csum(struct net_device *dev,
netdev_features_t wanted)
Expand Down Expand Up @@ -1291,11 +1282,10 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
struct bcm_sysport_tx_ring *ring;
struct bcm_sysport_cb *cb;
struct netdev_queue *txq;
struct dma_desc *desc;
u32 len_status, addr_lo;
unsigned int skb_len;
unsigned long flags;
dma_addr_t mapping;
u32 len_status;
u16 queue;
int ret;

Expand Down Expand Up @@ -1338,10 +1328,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
dma_unmap_addr_set(cb, dma_addr, mapping);
dma_unmap_len_set(cb, dma_len, skb_len);

/* Fetch a descriptor entry from our pool */
desc = ring->desc_cpu;

desc->addr_lo = lower_32_bits(mapping);
addr_lo = lower_32_bits(mapping);
len_status = upper_32_bits(mapping) & DESC_ADDR_HI_MASK;
len_status |= (skb_len << DESC_LEN_SHIFT);
len_status |= (DESC_SOP | DESC_EOP | TX_STATUS_APP_CRC) <<
Expand All @@ -1354,16 +1341,9 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
ring->curr_desc = 0;
ring->desc_count--;

/* Ensure write completion of the descriptor status/length
* in DRAM before the System Port WRITE_PORT register latches
* the value
*/
wmb();
desc->addr_status_len = len_status;
wmb();

/* Write this descriptor address to the RING write port */
tdma_port_write_desc_addr(priv, desc, ring->index);
/* Ports are latched, so write upper address first */
tdma_writel(priv, len_status, TDMA_WRITE_PORT_HI(ring->index));
tdma_writel(priv, addr_lo, TDMA_WRITE_PORT_LO(ring->index));

/* Check ring space and update SW control flow */
if (ring->desc_count == 0)
Expand Down Expand Up @@ -1489,28 +1469,14 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
unsigned int index)
{
struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
struct device *kdev = &priv->pdev->dev;
size_t size;
void *p;
u32 reg;

/* Simple descriptors partitioning for now */
size = 256;

/* We just need one DMA descriptor which is DMA-able, since writing to
* the port will allocate a new descriptor in its internal linked-list
*/
p = dma_alloc_coherent(kdev, sizeof(struct dma_desc), &ring->desc_dma,
GFP_KERNEL);
if (!p) {
netif_err(priv, hw, priv->netdev, "DMA alloc failed\n");
return -ENOMEM;
}

ring->cbs = kcalloc(size, sizeof(struct bcm_sysport_cb), GFP_KERNEL);
if (!ring->cbs) {
dma_free_coherent(kdev, sizeof(struct dma_desc),
ring->desc_cpu, ring->desc_dma);
netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
return -ENOMEM;
}
Expand All @@ -1523,7 +1489,6 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
ring->size = size;
ring->clean_index = 0;
ring->alloc_size = ring->size;
ring->desc_cpu = p;
ring->desc_count = ring->size;
ring->curr_desc = 0;

Expand Down Expand Up @@ -1578,8 +1543,8 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
napi_enable(&ring->napi);

netif_dbg(priv, hw, priv->netdev,
"TDMA cfg, size=%d, desc_cpu=%p switch q=%d,port=%d\n",
ring->size, ring->desc_cpu, ring->switch_queue,
"TDMA cfg, size=%d, switch q=%d,port=%d\n",
ring->size, ring->switch_queue,
ring->switch_port);

return 0;
Expand All @@ -1589,7 +1554,6 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
unsigned int index)
{
struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
struct device *kdev = &priv->pdev->dev;
u32 reg;

/* Caller should stop the TDMA engine */
Expand All @@ -1611,12 +1575,6 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,

kfree(ring->cbs);
ring->cbs = NULL;

if (ring->desc_dma) {
dma_free_coherent(kdev, sizeof(struct dma_desc),
ring->desc_cpu, ring->desc_dma);
ring->desc_dma = 0;
}
ring->size = 0;
ring->alloc_size = 0;

Expand Down
10 changes: 1 addition & 9 deletions drivers/net/ethernet/broadcom/bcmsysport.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,6 @@ struct bcm_rsb {

#define TDMA_DEBUG 0x64c

/* Transmit/Receive descriptor */
struct dma_desc {
u32 addr_status_len;
u32 addr_lo;
};

/* Number of Receive hardware descriptor words */
#define SP_NUM_HW_RX_DESC_WORDS 1024
#define SP_LT_NUM_HW_RX_DESC_WORDS 256
Expand All @@ -530,7 +524,7 @@ struct dma_desc {
#define SP_NUM_TX_DESC 1536
#define SP_LT_NUM_TX_DESC 256

#define WORDS_PER_DESC (sizeof(struct dma_desc) / sizeof(u32))
#define WORDS_PER_DESC 2

/* Rx/Tx common counter group.*/
struct bcm_sysport_pkt_counters {
Expand Down Expand Up @@ -718,7 +712,6 @@ struct bcm_sysport_net_dim {
struct bcm_sysport_tx_ring {
spinlock_t lock; /* Ring lock for tx reclaim/xmit */
struct napi_struct napi; /* NAPI per tx queue */
dma_addr_t desc_dma; /* DMA cookie */
unsigned int index; /* Ring index */
unsigned int size; /* Ring current size */
unsigned int alloc_size; /* Ring one-time allocated size */
Expand All @@ -727,7 +720,6 @@ struct bcm_sysport_tx_ring {
unsigned int c_index; /* Last consumer index */
unsigned int clean_index; /* Current clean index */
struct bcm_sysport_cb *cbs; /* Transmit control blocks */
struct dma_desc *desc_cpu; /* CPU view of the descriptor */
struct bcm_sysport_priv *priv; /* private context backpointer */
unsigned long packets; /* packets statistics */
unsigned long bytes; /* bytes statistics */
Expand Down

0 comments on commit 7e6e185

Please sign in to comment.