Commit 73d74228 authored by Willy Tarreau's avatar Willy Tarreau Committed by Jakub Kicinski

macb: prepare at91 to use a 2-frame TX queue

The RM9200 supports one frame being sent while another one is waiting in
queue. This avoids the dead time that follows the emission of a frame
and which prevents one from reaching line speed.

Right now the driver supports only a single skb, so we'll first replace
the rm9200-specific skb info with an array of two macb_tx_skb (already
used by other drivers). This patch only moves the skb_length to
txq[0].size and skb_physaddr to skb[0].mapping but doesn't perform any
other change. It already uses [desc] in order to minimize future changes.

Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Daniel Palmer <daniel@0x0f.com>
Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/r/20201011090944.10607-3-w@1wt.euSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent fa6031df
...@@ -1207,10 +1207,8 @@ struct macb { ...@@ -1207,10 +1207,8 @@ struct macb {
phy_interface_t phy_interface; phy_interface_t phy_interface;
/* AT91RM9200 transmit */ /* AT91RM9200 transmit queue (1 on wire + 1 queued) */
struct sk_buff *skb; /* holds skb until xmit interrupt completes */ struct macb_tx_skb rm9200_txq[2];
dma_addr_t skb_physaddr; /* phys addr from pci_map_single */
int skb_length; /* saved skb length for pci_unmap_single */
unsigned int max_tx_length; unsigned int max_tx_length;
u64 ethtool_stats[GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES]; u64 ethtool_stats[GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES];
......
...@@ -3995,14 +3995,16 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb, ...@@ -3995,14 +3995,16 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
struct macb *lp = netdev_priv(dev); struct macb *lp = netdev_priv(dev);
if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) { if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) {
int desc = 0;
netif_stop_queue(dev); netif_stop_queue(dev);
/* Store packet information (to free when Tx completed) */ /* Store packet information (to free when Tx completed) */
lp->skb = skb; lp->rm9200_txq[desc].skb = skb;
lp->skb_length = skb->len; lp->rm9200_txq[desc].size = skb->len;
lp->skb_physaddr = dma_map_single(&lp->pdev->dev, skb->data, lp->rm9200_txq[desc].mapping = dma_map_single(&lp->pdev->dev, skb->data,
skb->len, DMA_TO_DEVICE); skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(&lp->pdev->dev, lp->skb_physaddr)) { if (dma_mapping_error(&lp->pdev->dev, lp->rm9200_txq[desc].mapping)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
netdev_err(dev, "%s: DMA mapping error\n", __func__); netdev_err(dev, "%s: DMA mapping error\n", __func__);
...@@ -4010,7 +4012,7 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb, ...@@ -4010,7 +4012,7 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
} }
/* Set address of the data in the Transmit Address register */ /* Set address of the data in the Transmit Address register */
macb_writel(lp, TAR, lp->skb_physaddr); macb_writel(lp, TAR, lp->rm9200_txq[desc].mapping);
/* Set length of the packet in the Transmit Control register */ /* Set length of the packet in the Transmit Control register */
macb_writel(lp, TCR, skb->len); macb_writel(lp, TCR, skb->len);
...@@ -4073,6 +4075,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id) ...@@ -4073,6 +4075,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
struct net_device *dev = dev_id; struct net_device *dev = dev_id;
struct macb *lp = netdev_priv(dev); struct macb *lp = netdev_priv(dev);
u32 intstatus, ctl; u32 intstatus, ctl;
unsigned int desc;
/* MAC Interrupt Status register indicates what interrupts are pending. /* MAC Interrupt Status register indicates what interrupts are pending.
* It is automatically cleared once read. * It is automatically cleared once read.
...@@ -4089,13 +4092,14 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id) ...@@ -4089,13 +4092,14 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE))) if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE)))
dev->stats.tx_errors++; dev->stats.tx_errors++;
if (lp->skb) { desc = 0;
dev_consume_skb_irq(lp->skb); if (lp->rm9200_txq[desc].skb) {
lp->skb = NULL; dev_consume_skb_irq(lp->rm9200_txq[desc].skb);
dma_unmap_single(&lp->pdev->dev, lp->skb_physaddr, lp->rm9200_txq[desc].skb = NULL;
lp->skb_length, DMA_TO_DEVICE); dma_unmap_single(&lp->pdev->dev, lp->rm9200_txq[desc].mapping,
lp->rm9200_txq[desc].size, DMA_TO_DEVICE);
dev->stats.tx_packets++; dev->stats.tx_packets++;
dev->stats.tx_bytes += lp->skb_length; dev->stats.tx_bytes += lp->rm9200_txq[desc].size;
} }
netif_wake_queue(dev); netif_wake_queue(dev);
} }
......
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