Changeset 42433


Ignore:
Timestamp:
2014-09-07T11:46:39+02:00 (3 years ago)
Author:
nbd
Message:

ar71xx: merge ethernet tx descriptor splitting from trunk (as of r42429) to fix ar716x performance issues

Signed-off-by: Felix Fietkau <nbd@…>

Location:
branches/barrier_breaker/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/barrier_breaker/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h

    r39144 r42433  
    5353#define AG71XX_TX_MTU_LEN       1540 
    5454 
    55 #define AG71XX_TX_RING_SIZE_DEFAULT     32 
     55#define AG71XX_TX_RING_SPLIT            512 
     56#define AG71XX_TX_RING_DS_PER_PKT       DIV_ROUND_UP(AG71XX_TX_MTU_LEN, \ 
     57                                                     AG71XX_TX_RING_SPLIT) 
     58#define AG71XX_TX_RING_SIZE_DEFAULT     48 
    5659#define AG71XX_RX_RING_SIZE_DEFAULT     128 
    5760 
    58 #define AG71XX_TX_RING_SIZE_MAX         32 
     61#define AG71XX_TX_RING_SIZE_MAX         48 
    5962#define AG71XX_RX_RING_SIZE_MAX         128 
    6063 
     
    100103        u8                      *descs_cpu; 
    101104        dma_addr_t              descs_dma; 
    102         unsigned int            desc_size; 
     105        u16                     desc_split; 
     106        u16                     desc_size; 
    103107        unsigned int            curr; 
    104108        unsigned int            dirty; 
  • branches/barrier_breaker/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c

    r30405 r42433  
    7676        er->rx_mini_pending = 0; 
    7777        er->rx_jumbo_pending = 0; 
     78 
     79        if (ag->tx_ring.desc_split) 
     80                er->tx_pending /= AG71XX_TX_RING_DS_PER_PKT; 
    7881} 
    7982 
     
    104107        } 
    105108 
     109        if (ag->tx_ring.desc_split) 
     110                tx_size *= AG71XX_TX_RING_DS_PER_PKT; 
     111 
    106112        ag->tx_ring.size = tx_size; 
    107113        ag->rx_ring.size = rx_size; 
  • branches/barrier_breaker/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c

    r39219 r42433  
    537537        u32 ifctl; 
    538538        u32 fifo5; 
     539        u32 fifo3; 
    539540 
    540541        if (!ag->link) { 
     
    577578 
    578579        if (pdata->is_ar91xx) 
    579                 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); 
     580                fifo3 = 0x00780fff; 
    580581        else if (pdata->is_ar724x) 
    581                 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); 
     582                fifo3 = pdata->fifo_cfg3; 
    582583        else 
    583                 ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); 
     584                fifo3 = 0x008001ff; 
     585 
     586        if (ag->tx_ring.desc_split) { 
     587                fifo3 &= 0xffff; 
     588                fifo3 |= ((2048 - ag->tx_ring.desc_split) / 4) << 16; 
     589        } 
     590 
     591        ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, fifo3); 
    584592 
    585593        if (pdata->set_speed) 
     
    676684} 
    677685 
     686static int ag71xx_fill_dma_desc(struct ag71xx_ring *ring, u32 addr, int len) 
     687{ 
     688        int i; 
     689        struct ag71xx_desc *desc; 
     690        int ndesc = 0; 
     691        int split = ring->desc_split; 
     692 
     693        if (!split) 
     694                split = len; 
     695 
     696        while (len > 0) { 
     697                unsigned int cur_len = len; 
     698 
     699                i = (ring->curr + ndesc) % ring->size; 
     700                desc = ring->buf[i].desc; 
     701 
     702                if (!ag71xx_desc_empty(desc)) 
     703                        return -1; 
     704 
     705                if (cur_len > split) { 
     706                        cur_len = split; 
     707 
     708                        /* 
     709                         * TX will hang if DMA transfers <= 4 bytes, 
     710                         * make sure next segment is more than 4 bytes long. 
     711                         */ 
     712                        if (len <= split + 4) 
     713                                cur_len -= 4; 
     714                } 
     715 
     716                desc->data = addr; 
     717                addr += cur_len; 
     718                len -= cur_len; 
     719 
     720                if (len > 0) 
     721                        cur_len |= DESC_MORE; 
     722 
     723                /* prevent early tx attempt of this descriptor */ 
     724                if (!ndesc) 
     725                        cur_len |= DESC_EMPTY; 
     726 
     727                desc->ctrl = cur_len; 
     728                ndesc++; 
     729        } 
     730 
     731        return ndesc; 
     732} 
     733 
    678734static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, 
    679735                                          struct net_device *dev) 
     
    683739        struct ag71xx_desc *desc; 
    684740        dma_addr_t dma_addr; 
    685         int i; 
     741        int i, n, ring_min; 
     742 
     743        if (ag71xx_has_ar8216(ag)) 
     744                ag71xx_add_ar8216_header(ag, skb); 
     745 
     746        if (skb->len <= 4) { 
     747                DBG("%s: packet len is too small\n", ag->dev->name); 
     748                goto err_drop; 
     749        } 
     750 
     751        dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, 
     752                                  DMA_TO_DEVICE); 
    686753 
    687754        i = ring->curr % ring->size; 
    688755        desc = ring->buf[i].desc; 
    689756 
    690         if (!ag71xx_desc_empty(desc)) 
    691                 goto err_drop; 
    692  
    693         if (ag71xx_has_ar8216(ag)) 
    694                 ag71xx_add_ar8216_header(ag, skb); 
    695  
    696         if (skb->len <= 0) { 
    697                 DBG("%s: packet len is too small\n", ag->dev->name); 
    698                 goto err_drop; 
    699         } 
    700  
    701         dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, 
    702                                   DMA_TO_DEVICE); 
    703  
    704         netdev_sent_queue(dev, skb->len); 
     757        /* setup descriptor fields */ 
     758        n = ag71xx_fill_dma_desc(ring, (u32) dma_addr, skb->len & ag->desc_pktlen_mask); 
     759        if (n < 0) 
     760                goto err_drop_unmap; 
     761 
     762        i = (ring->curr + n - 1) % ring->size; 
    705763        ring->buf[i].len = skb->len; 
    706764        ring->buf[i].skb = skb; 
    707765        ring->buf[i].timestamp = jiffies; 
    708766 
    709         /* setup descriptor fields */ 
    710         desc->data = (u32) dma_addr; 
    711         desc->ctrl = skb->len & ag->desc_pktlen_mask; 
     767        netdev_sent_queue(dev, skb->len); 
     768 
     769        desc->ctrl &= ~DESC_EMPTY; 
     770        ring->curr += n; 
    712771 
    713772        /* flush descriptor */ 
    714773        wmb(); 
    715774 
    716         ring->curr++; 
    717         if (ring->curr == (ring->dirty + ring->size)) { 
    718                 DBG("%s: tx queue full\n", ag->dev->name); 
     775        ring_min = 2; 
     776        if (ring->desc_split) 
     777            ring_min *= AG71XX_TX_RING_DS_PER_PKT; 
     778 
     779        if (ring->curr - ring->dirty >= ring->size - ring_min) { 
     780                DBG("%s: tx queue full\n", dev->name); 
    719781                netif_stop_queue(dev); 
    720782        } 
     
    726788 
    727789        return NETDEV_TX_OK; 
     790 
     791err_drop_unmap: 
     792        dma_unmap_single(&dev->dev, dma_addr, skb->len, DMA_TO_DEVICE); 
    728793 
    729794err_drop: 
     
    844909                struct ag71xx_desc *desc = ring->buf[i].desc; 
    845910                struct sk_buff *skb = ring->buf[i].skb; 
    846                 int len = ring->buf[i].len; 
    847911 
    848912                if (!ag71xx_desc_empty(desc)) { 
     
    855919                ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); 
    856920 
    857                 bytes_compl += len; 
    858                 ag->dev->stats.tx_bytes += len; 
    859                 ag->dev->stats.tx_packets++; 
    860  
    861                 dev_kfree_skb_any(skb); 
    862                 ring->buf[i].skb = NULL; 
     921                if (skb) { 
     922                        dev_kfree_skb_any(skb); 
     923                        ring->buf[i].skb = NULL; 
     924 
     925                        bytes_compl += ring->buf[i].len; 
     926                        sent++; 
     927                } 
    863928 
    864929                ring->dirty++; 
    865                 sent++; 
    866930        } 
    867931 
    868932        DBG("%s: %d packets sent out\n", ag->dev->name, sent); 
     933 
     934        ag->dev->stats.tx_bytes += bytes_compl; 
     935        ag->dev->stats.tx_packets += sent; 
    869936 
    870937        if (!sent) 
     
    11951262        ag->max_frame_len = pdata->max_frame_len; 
    11961263        ag->desc_pktlen_mask = pdata->desc_pktlen_mask; 
     1264 
     1265        if (!pdata->is_ar724x && !pdata->is_ar91xx) { 
     1266                ag->tx_ring.desc_split = AG71XX_TX_RING_SPLIT; 
     1267                ag->tx_ring.size *= AG71XX_TX_RING_DS_PER_PKT; 
     1268        } 
    11971269 
    11981270        ag->stop_desc = dma_alloc_coherent(NULL, 
Note: See TracChangeset for help on using the changeset viewer.