net: systemport: Remove need for DMA descriptor
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>hifive-unleashed-5.2
parent
697cd36cda
commit
7e6e185c74
|
@ -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);
|
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 */
|
/* Ethtool operations */
|
||||||
static void bcm_sysport_set_rx_csum(struct net_device *dev,
|
static void bcm_sysport_set_rx_csum(struct net_device *dev,
|
||||||
netdev_features_t wanted)
|
netdev_features_t wanted)
|
||||||
|
@ -1291,11 +1282,10 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
|
||||||
struct bcm_sysport_tx_ring *ring;
|
struct bcm_sysport_tx_ring *ring;
|
||||||
struct bcm_sysport_cb *cb;
|
struct bcm_sysport_cb *cb;
|
||||||
struct netdev_queue *txq;
|
struct netdev_queue *txq;
|
||||||
struct dma_desc *desc;
|
u32 len_status, addr_lo;
|
||||||
unsigned int skb_len;
|
unsigned int skb_len;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
dma_addr_t mapping;
|
dma_addr_t mapping;
|
||||||
u32 len_status;
|
|
||||||
u16 queue;
|
u16 queue;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -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_addr_set(cb, dma_addr, mapping);
|
||||||
dma_unmap_len_set(cb, dma_len, skb_len);
|
dma_unmap_len_set(cb, dma_len, skb_len);
|
||||||
|
|
||||||
/* Fetch a descriptor entry from our pool */
|
addr_lo = lower_32_bits(mapping);
|
||||||
desc = ring->desc_cpu;
|
|
||||||
|
|
||||||
desc->addr_lo = lower_32_bits(mapping);
|
|
||||||
len_status = upper_32_bits(mapping) & DESC_ADDR_HI_MASK;
|
len_status = upper_32_bits(mapping) & DESC_ADDR_HI_MASK;
|
||||||
len_status |= (skb_len << DESC_LEN_SHIFT);
|
len_status |= (skb_len << DESC_LEN_SHIFT);
|
||||||
len_status |= (DESC_SOP | DESC_EOP | TX_STATUS_APP_CRC) <<
|
len_status |= (DESC_SOP | DESC_EOP | TX_STATUS_APP_CRC) <<
|
||||||
|
@ -1354,16 +1341,9 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
|
||||||
ring->curr_desc = 0;
|
ring->curr_desc = 0;
|
||||||
ring->desc_count--;
|
ring->desc_count--;
|
||||||
|
|
||||||
/* Ensure write completion of the descriptor status/length
|
/* Ports are latched, so write upper address first */
|
||||||
* in DRAM before the System Port WRITE_PORT register latches
|
tdma_writel(priv, len_status, TDMA_WRITE_PORT_HI(ring->index));
|
||||||
* the value
|
tdma_writel(priv, addr_lo, TDMA_WRITE_PORT_LO(ring->index));
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* Check ring space and update SW control flow */
|
/* Check ring space and update SW control flow */
|
||||||
if (ring->desc_count == 0)
|
if (ring->desc_count == 0)
|
||||||
|
@ -1489,28 +1469,14 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
|
||||||
unsigned int index)
|
unsigned int index)
|
||||||
{
|
{
|
||||||
struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
|
struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
|
||||||
struct device *kdev = &priv->pdev->dev;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
void *p;
|
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
/* Simple descriptors partitioning for now */
|
/* Simple descriptors partitioning for now */
|
||||||
size = 256;
|
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);
|
ring->cbs = kcalloc(size, sizeof(struct bcm_sysport_cb), GFP_KERNEL);
|
||||||
if (!ring->cbs) {
|
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");
|
netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -1523,7 +1489,6 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
|
||||||
ring->size = size;
|
ring->size = size;
|
||||||
ring->clean_index = 0;
|
ring->clean_index = 0;
|
||||||
ring->alloc_size = ring->size;
|
ring->alloc_size = ring->size;
|
||||||
ring->desc_cpu = p;
|
|
||||||
ring->desc_count = ring->size;
|
ring->desc_count = ring->size;
|
||||||
ring->curr_desc = 0;
|
ring->curr_desc = 0;
|
||||||
|
|
||||||
|
@ -1578,8 +1543,8 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
|
||||||
napi_enable(&ring->napi);
|
napi_enable(&ring->napi);
|
||||||
|
|
||||||
netif_dbg(priv, hw, priv->netdev,
|
netif_dbg(priv, hw, priv->netdev,
|
||||||
"TDMA cfg, size=%d, desc_cpu=%p switch q=%d,port=%d\n",
|
"TDMA cfg, size=%d, switch q=%d,port=%d\n",
|
||||||
ring->size, ring->desc_cpu, ring->switch_queue,
|
ring->size, ring->switch_queue,
|
||||||
ring->switch_port);
|
ring->switch_port);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1589,7 +1554,6 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
|
||||||
unsigned int index)
|
unsigned int index)
|
||||||
{
|
{
|
||||||
struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
|
struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
|
||||||
struct device *kdev = &priv->pdev->dev;
|
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
/* Caller should stop the TDMA engine */
|
/* Caller should stop the TDMA engine */
|
||||||
|
@ -1611,12 +1575,6 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
|
||||||
|
|
||||||
kfree(ring->cbs);
|
kfree(ring->cbs);
|
||||||
ring->cbs = NULL;
|
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->size = 0;
|
||||||
ring->alloc_size = 0;
|
ring->alloc_size = 0;
|
||||||
|
|
||||||
|
|
|
@ -516,12 +516,6 @@ struct bcm_rsb {
|
||||||
|
|
||||||
#define TDMA_DEBUG 0x64c
|
#define TDMA_DEBUG 0x64c
|
||||||
|
|
||||||
/* Transmit/Receive descriptor */
|
|
||||||
struct dma_desc {
|
|
||||||
u32 addr_status_len;
|
|
||||||
u32 addr_lo;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Number of Receive hardware descriptor words */
|
/* Number of Receive hardware descriptor words */
|
||||||
#define SP_NUM_HW_RX_DESC_WORDS 1024
|
#define SP_NUM_HW_RX_DESC_WORDS 1024
|
||||||
#define SP_LT_NUM_HW_RX_DESC_WORDS 256
|
#define SP_LT_NUM_HW_RX_DESC_WORDS 256
|
||||||
|
@ -530,7 +524,7 @@ struct dma_desc {
|
||||||
#define SP_NUM_TX_DESC 1536
|
#define SP_NUM_TX_DESC 1536
|
||||||
#define SP_LT_NUM_TX_DESC 256
|
#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.*/
|
/* Rx/Tx common counter group.*/
|
||||||
struct bcm_sysport_pkt_counters {
|
struct bcm_sysport_pkt_counters {
|
||||||
|
@ -718,7 +712,6 @@ struct bcm_sysport_net_dim {
|
||||||
struct bcm_sysport_tx_ring {
|
struct bcm_sysport_tx_ring {
|
||||||
spinlock_t lock; /* Ring lock for tx reclaim/xmit */
|
spinlock_t lock; /* Ring lock for tx reclaim/xmit */
|
||||||
struct napi_struct napi; /* NAPI per tx queue */
|
struct napi_struct napi; /* NAPI per tx queue */
|
||||||
dma_addr_t desc_dma; /* DMA cookie */
|
|
||||||
unsigned int index; /* Ring index */
|
unsigned int index; /* Ring index */
|
||||||
unsigned int size; /* Ring current size */
|
unsigned int size; /* Ring current size */
|
||||||
unsigned int alloc_size; /* Ring one-time allocated size */
|
unsigned int alloc_size; /* Ring one-time allocated size */
|
||||||
|
@ -727,7 +720,6 @@ struct bcm_sysport_tx_ring {
|
||||||
unsigned int c_index; /* Last consumer index */
|
unsigned int c_index; /* Last consumer index */
|
||||||
unsigned int clean_index; /* Current clean index */
|
unsigned int clean_index; /* Current clean index */
|
||||||
struct bcm_sysport_cb *cbs; /* Transmit control blocks */
|
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 */
|
struct bcm_sysport_priv *priv; /* private context backpointer */
|
||||||
unsigned long packets; /* packets statistics */
|
unsigned long packets; /* packets statistics */
|
||||||
unsigned long bytes; /* bytes statistics */
|
unsigned long bytes; /* bytes statistics */
|
||||||
|
|
Loading…
Reference in New Issue