Skip to content

Commit

Permalink
macb: prepare at91 to use a 2-frame TX queue
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: Claudiu Beznea <[email protected]>
Cc: Daniel Palmer <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
wtarreau authored and kuba-moo committed Oct 13, 2020
1 parent fa6031d commit 73d7422
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 16 deletions.
6 changes: 2 additions & 4 deletions drivers/net/ethernet/cadence/macb.h
Original file line number Diff line number Diff line change
Expand Up @@ -1207,10 +1207,8 @@ struct macb {

phy_interface_t phy_interface;

/* AT91RM9200 transmit */
struct sk_buff *skb; /* holds skb until xmit interrupt completes */
dma_addr_t skb_physaddr; /* phys addr from pci_map_single */
int skb_length; /* saved skb length for pci_unmap_single */
/* AT91RM9200 transmit queue (1 on wire + 1 queued) */
struct macb_tx_skb rm9200_txq[2];
unsigned int max_tx_length;

u64 ethtool_stats[GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES];
Expand Down
28 changes: 16 additions & 12 deletions drivers/net/ethernet/cadence/macb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3995,22 +3995,24 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
struct macb *lp = netdev_priv(dev);

if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) {
int desc = 0;

netif_stop_queue(dev);

/* Store packet information (to free when Tx completed) */
lp->skb = skb;
lp->skb_length = skb->len;
lp->skb_physaddr = dma_map_single(&lp->pdev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(&lp->pdev->dev, lp->skb_physaddr)) {
lp->rm9200_txq[desc].skb = skb;
lp->rm9200_txq[desc].size = skb->len;
lp->rm9200_txq[desc].mapping = dma_map_single(&lp->pdev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(&lp->pdev->dev, lp->rm9200_txq[desc].mapping)) {
dev_kfree_skb_any(skb);
dev->stats.tx_dropped++;
netdev_err(dev, "%s: DMA mapping error\n", __func__);
return NETDEV_TX_OK;
}

/* 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 */
macb_writel(lp, TCR, skb->len);

Expand Down Expand Up @@ -4073,6 +4075,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
struct net_device *dev = dev_id;
struct macb *lp = netdev_priv(dev);
u32 intstatus, ctl;
unsigned int desc;

/* MAC Interrupt Status register indicates what interrupts are pending.
* It is automatically cleared once read.
Expand All @@ -4089,13 +4092,14 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE)))
dev->stats.tx_errors++;

if (lp->skb) {
dev_consume_skb_irq(lp->skb);
lp->skb = NULL;
dma_unmap_single(&lp->pdev->dev, lp->skb_physaddr,
lp->skb_length, DMA_TO_DEVICE);
desc = 0;
if (lp->rm9200_txq[desc].skb) {
dev_consume_skb_irq(lp->rm9200_txq[desc].skb);
lp->rm9200_txq[desc].skb = NULL;
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_bytes += lp->skb_length;
dev->stats.tx_bytes += lp->rm9200_txq[desc].size;
}
netif_wake_queue(dev);
}
Expand Down

0 comments on commit 73d7422

Please sign in to comment.