Changeset 19310


Ignore:
Timestamp:
05/28/12 13:53:33 (12 months ago)
Author:
BrainSlayer
Message:

improve rx performance of the ethernet driver by using build_skb to deliver a cache-hot skb to the network stack

Location:
src/linux/universal
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-3.2/drivers/net/ethernet/ag71xx/ag71xx.h

    r19303 r19310  
    5151 
    5252#define AG71XX_TX_MTU_LEN       1540 
    53 #define AG71XX_RX_PKT_RESERVE   64 
    5453#define AG71XX_RX_PKT_SIZE      \ 
    55         (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     54        (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     55#define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) 
    5656 
    5757#define AG71XX_TX_RING_SIZE_DEFAULT     64 
     
    6262 
    6363#ifdef CONFIG_AG71XX_DEBUG 
    64 #define DBG(fmt, args...)       printk(KERN_DEBUG fmt, ## args) 
     64#define DBG(fmt, args...)       pr_debug(fmt, ## args) 
    6565#else 
    6666#define DBG(fmt, args...)       do {} while (0) 
     
    8686 
    8787struct ag71xx_buf { 
    88         struct sk_buff          *skb; 
     88        union { 
     89                struct sk_buff  *skb; 
     90                void            *rx_buf; 
     91        }; 
    8992        struct ag71xx_desc      *desc; 
    9093        dma_addr_t              dma_addr; 
  • src/linux/universal/linux-3.2/drivers/net/ethernet/ag71xx/ag71xx_main.c

    r18801 r19310  
    190190 
    191191        for (i = 0; i < ring->size; i++) 
    192                 if (ring->buf[i].skb) { 
     192                if (ring->buf[i].rx_buf) { 
    193193                        dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, 
    194                                          AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
    195                         kfree_skb(ring->buf[i].skb); 
     194                                         AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     195                        kfree(ring->buf[i].rx_buf); 
    196196                } 
    197197} 
    198198 
    199 static int ag71xx_rx_reserve(struct ag71xx *ag) 
    200 { 
    201         int reserve = 0; 
    202  
    203         if (ag71xx_get_pdata(ag)->is_ar724x) { 
    204                 if (!ag71xx_has_ar8216(ag)) 
    205                         reserve = 2; 
    206  
    207                 if (ag->phy_dev) 
    208                         reserve += 4 - (ag->phy_dev->pkt_align % 4); 
    209  
    210                 reserve %= 4; 
    211         } 
    212  
    213         return reserve + AG71XX_RX_PKT_RESERVE; 
    214 } 
    215  
     199static int ag71xx_buffer_offset(struct ag71xx *ag) 
     200{ 
     201        int offset = NET_SKB_PAD; 
     202 
     203        /* 
     204         * On AR71xx/AR91xx packets must be 4-byte aligned. 
     205         * 
     206         * When using builtin AR8216 support, hardware adds a 2-byte header, 
     207         * so we don't need any extra alignment in that case. 
     208         */ 
     209        if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) 
     210                return offset; 
     211 
     212        return offset + NET_IP_ALIGN; 
     213} 
     214 
     215static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, 
     216                               int offset) 
     217{ 
     218        void *data; 
     219 
     220        data = kmalloc(AG71XX_RX_BUF_SIZE + 
     221                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), 
     222                       GFP_ATOMIC); 
     223        if (!data) 
     224                return false; 
     225 
     226        buf->rx_buf = data; 
     227        buf->dma_addr = dma_map_single(&ag->dev->dev, data, 
     228                                       AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     229        buf->desc->data = (u32) buf->dma_addr + offset; 
     230        return true; 
     231} 
    216232 
    217233static int ag71xx_ring_rx_init(struct ag71xx *ag) 
    218234{ 
    219235        struct ag71xx_ring *ring = &ag->rx_ring; 
    220         unsigned int reserve = ag71xx_rx_reserve(ag); 
    221236        unsigned int i; 
    222237        int ret; 
     238        int offset = ag71xx_buffer_offset(ag); 
    223239 
    224240        ret = 0; 
     
    233249 
    234250        for (i = 0; i < ring->size; i++) { 
    235                 struct sk_buff *skb; 
    236                 dma_addr_t dma_addr; 
    237  
    238                 skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    239                 if (!skb) { 
     251                if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { 
    240252                        ret = -ENOMEM; 
    241253                        break; 
    242254                } 
    243255 
    244                 skb->dev = ag->dev; 
    245                 skb_reserve(skb, reserve); 
    246  
    247                 dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    248                                           AG71XX_RX_PKT_SIZE, 
    249                                           DMA_FROM_DEVICE); 
    250                 ring->buf[i].skb = skb; 
    251                 ring->buf[i].dma_addr = dma_addr; 
    252                 ring->buf[i].desc->data = (u32) dma_addr; 
    253256                ring->buf[i].desc->ctrl = DESC_EMPTY; 
    254257        } 
     
    266269{ 
    267270        struct ag71xx_ring *ring = &ag->rx_ring; 
    268         unsigned int reserve = ag71xx_rx_reserve(ag); 
    269271        unsigned int count; 
     272        int offset = ag71xx_buffer_offset(ag); 
    270273 
    271274        count = 0; 
     
    275278                i = ring->dirty % ring->size; 
    276279 
    277                 if (ring->buf[i].skb == NULL) { 
    278                         dma_addr_t dma_addr; 
    279                         struct sk_buff *skb; 
    280  
    281                         skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    282                         if (skb == NULL) 
    283                                 break; 
    284  
    285                         skb_reserve(skb, reserve); 
    286                         skb->dev = ag->dev; 
    287  
    288                         dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    289                                                   AG71XX_RX_PKT_SIZE, 
    290                                                   DMA_FROM_DEVICE); 
    291  
    292                         ring->buf[i].skb = skb; 
    293                         ring->buf[i].dma_addr = dma_addr; 
    294                         ring->buf[i].desc->data = (u32) dma_addr; 
    295                 } 
     280                if (!ring->buf[i].rx_buf && 
     281                    !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) 
     282                        break; 
    296283 
    297284                ring->buf[i].desc->ctrl = DESC_EMPTY; 
     
    872859        struct net_device *dev = ag->dev; 
    873860        struct ag71xx_ring *ring = &ag->rx_ring; 
     861        int offset = ag71xx_buffer_offset(ag); 
    874862        int done = 0; 
    875863 
     
    894882                ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
    895883 
    896                 skb = ring->buf[i].skb; 
    897884                pktlen = ag71xx_desc_pktlen(desc); 
    898885                pktlen -= ETH_FCS_LEN; 
    899886 
    900887                dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, 
    901                                  AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
     888                                 AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
    902889 
    903890                dev->last_rx = jiffies; 
     
    905892                dev->stats.rx_bytes += pktlen; 
    906893 
     894                skb = build_skb(ring->buf[i].rx_buf); 
     895                if (!skb) { 
     896                        kfree(ring->buf[i].rx_buf); 
     897                        goto next; 
     898                } 
     899 
     900                skb_reserve(skb, offset); 
    907901                skb_put(skb, pktlen); 
     902 
    908903                if (ag71xx_has_ar8216(ag)) 
    909904                        err = ag71xx_remove_ar8216_header(ag, skb, pktlen); 
     
    915910                        skb->dev = dev; 
    916911                        skb->ip_summed = CHECKSUM_NONE; 
    917                         if (ag->phy_dev) { 
    918                                 ag->phy_dev->netif_receive_skb(skb); 
    919                         } else { 
    920                                 skb->protocol = eth_type_trans(skb, dev); 
    921                                 netif_receive_skb(skb); 
    922                         } 
     912                        skb->protocol = eth_type_trans(skb, dev); 
     913                        netif_receive_skb(skb); 
    923914                } 
    924915 
    925                 ring->buf[i].skb = NULL; 
     916next: 
     917                ring->buf[i].rx_buf = NULL; 
    926918                done++; 
    927919 
     
    957949 
    958950        rx_ring = &ag->rx_ring; 
    959         if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) 
     951        if (rx_ring->buf[rx_ring->dirty % rx_ring->size].rx_buf == NULL) 
    960952                goto oom; 
    961953 
  • src/linux/universal/linux-3.2/drivers/net/ethernet/ag934x/ag71xx.h

    r19303 r19310  
    5151 
    5252#define AG71XX_TX_MTU_LEN       1540 
    53 #define AG71XX_RX_PKT_RESERVE   64 
    5453#define AG71XX_RX_PKT_SIZE      \ 
    55         (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     54        (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     55#define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) 
    5656 
    5757#define AG71XX_TX_RING_SIZE_DEFAULT     64 
     
    6262 
    6363#ifdef CONFIG_AG71XX_DEBUG 
    64 #define DBG(fmt, args...)       printk(KERN_DEBUG fmt, ## args) 
     64#define DBG(fmt, args...)       pr_debug(fmt, ## args) 
    6565#else 
    6666#define DBG(fmt, args...)       do {} while (0) 
     
    8686 
    8787struct ag71xx_buf { 
    88         struct sk_buff          *skb; 
     88        union { 
     89                struct sk_buff  *skb; 
     90                void            *rx_buf; 
     91        }; 
    8992        struct ag71xx_desc      *desc; 
    9093        dma_addr_t              dma_addr; 
  • src/linux/universal/linux-3.2/drivers/net/ethernet/ag934x/ag71xx_main.c

    r18801 r19310  
    190190 
    191191        for (i = 0; i < ring->size; i++) 
    192                 if (ring->buf[i].skb) { 
     192                if (ring->buf[i].rx_buf) { 
    193193                        dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, 
    194                                          AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
    195                         kfree_skb(ring->buf[i].skb); 
     194                                         AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     195                        kfree(ring->buf[i].rx_buf); 
    196196                } 
    197197} 
    198198 
    199 static int ag71xx_rx_reserve(struct ag71xx *ag) 
    200 { 
    201         int reserve = 0; 
    202  
    203         if (ag71xx_get_pdata(ag)->is_ar724x) { 
    204                 if (!ag71xx_has_ar8216(ag)) 
    205                         reserve = 2; 
    206  
    207                 if (ag->phy_dev) 
    208                         reserve += 4 - (ag->phy_dev->pkt_align % 4); 
    209  
    210                 reserve %= 4; 
    211         } 
    212  
    213         return reserve + AG71XX_RX_PKT_RESERVE; 
    214 } 
    215  
     199static int ag71xx_buffer_offset(struct ag71xx *ag) 
     200{ 
     201        int offset = NET_SKB_PAD; 
     202 
     203        /* 
     204         * On AR71xx/AR91xx packets must be 4-byte aligned. 
     205         * 
     206         * When using builtin AR8216 support, hardware adds a 2-byte header, 
     207         * so we don't need any extra alignment in that case. 
     208         */ 
     209        if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) 
     210                return offset; 
     211 
     212        return offset + NET_IP_ALIGN; 
     213} 
     214 
     215static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, 
     216                               int offset) 
     217{ 
     218        void *data; 
     219 
     220        data = kmalloc(AG71XX_RX_BUF_SIZE + 
     221                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), 
     222                       GFP_ATOMIC); 
     223        if (!data) 
     224                return false; 
     225 
     226        buf->rx_buf = data; 
     227        buf->dma_addr = dma_map_single(&ag->dev->dev, data, 
     228                                       AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     229        buf->desc->data = (u32) buf->dma_addr + offset; 
     230        return true; 
     231} 
    216232 
    217233static int ag71xx_ring_rx_init(struct ag71xx *ag) 
    218234{ 
    219235        struct ag71xx_ring *ring = &ag->rx_ring; 
    220         unsigned int reserve = ag71xx_rx_reserve(ag); 
    221236        unsigned int i; 
    222237        int ret; 
     238        int offset = ag71xx_buffer_offset(ag); 
    223239 
    224240        ret = 0; 
     
    233249 
    234250        for (i = 0; i < ring->size; i++) { 
    235                 struct sk_buff *skb; 
    236                 dma_addr_t dma_addr; 
    237  
    238                 skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    239                 if (!skb) { 
     251                if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { 
    240252                        ret = -ENOMEM; 
    241253                        break; 
    242254                } 
    243255 
    244                 skb->dev = ag->dev; 
    245                 skb_reserve(skb, reserve); 
    246  
    247                 dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    248                                           AG71XX_RX_PKT_SIZE, 
    249                                           DMA_FROM_DEVICE); 
    250                 ring->buf[i].skb = skb; 
    251                 ring->buf[i].dma_addr = dma_addr; 
    252                 ring->buf[i].desc->data = (u32) dma_addr; 
    253256                ring->buf[i].desc->ctrl = DESC_EMPTY; 
    254257        } 
     
    266269{ 
    267270        struct ag71xx_ring *ring = &ag->rx_ring; 
    268         unsigned int reserve = ag71xx_rx_reserve(ag); 
    269271        unsigned int count; 
     272        int offset = ag71xx_buffer_offset(ag); 
    270273 
    271274        count = 0; 
     
    275278                i = ring->dirty % ring->size; 
    276279 
    277                 if (ring->buf[i].skb == NULL) { 
    278                         dma_addr_t dma_addr; 
    279                         struct sk_buff *skb; 
    280  
    281                         skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    282                         if (skb == NULL) 
    283                                 break; 
    284  
    285                         skb_reserve(skb, reserve); 
    286                         skb->dev = ag->dev; 
    287  
    288                         dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    289                                                   AG71XX_RX_PKT_SIZE, 
    290                                                   DMA_FROM_DEVICE); 
    291  
    292                         ring->buf[i].skb = skb; 
    293                         ring->buf[i].dma_addr = dma_addr; 
    294                         ring->buf[i].desc->data = (u32) dma_addr; 
    295                 } 
     280                if (!ring->buf[i].rx_buf && 
     281                    !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) 
     282                        break; 
    296283 
    297284                ring->buf[i].desc->ctrl = DESC_EMPTY; 
     
    872859        struct net_device *dev = ag->dev; 
    873860        struct ag71xx_ring *ring = &ag->rx_ring; 
     861        int offset = ag71xx_buffer_offset(ag); 
    874862        int done = 0; 
    875863 
     
    894882                ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
    895883 
    896                 skb = ring->buf[i].skb; 
    897884                pktlen = ag71xx_desc_pktlen(desc); 
    898885                pktlen -= ETH_FCS_LEN; 
    899886 
    900887                dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, 
    901                                  AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
     888                                 AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
    902889 
    903890                dev->last_rx = jiffies; 
     
    905892                dev->stats.rx_bytes += pktlen; 
    906893 
     894                skb = build_skb(ring->buf[i].rx_buf); 
     895                if (!skb) { 
     896                        kfree(ring->buf[i].rx_buf); 
     897                        goto next; 
     898                } 
     899 
     900                skb_reserve(skb, offset); 
    907901                skb_put(skb, pktlen); 
     902 
    908903                if (ag71xx_has_ar8216(ag)) 
    909904                        err = ag71xx_remove_ar8216_header(ag, skb, pktlen); 
     
    915910                        skb->dev = dev; 
    916911                        skb->ip_summed = CHECKSUM_NONE; 
    917                         if (ag->phy_dev) { 
    918                                 ag->phy_dev->netif_receive_skb(skb); 
    919                         } else { 
    920                                 skb->protocol = eth_type_trans(skb, dev); 
    921                                 netif_receive_skb(skb); 
    922                         } 
     912                        skb->protocol = eth_type_trans(skb, dev); 
     913                        netif_receive_skb(skb); 
    923914                } 
    924915 
    925                 ring->buf[i].skb = NULL; 
     916next: 
     917                ring->buf[i].rx_buf = NULL; 
    926918                done++; 
    927919 
     
    957949 
    958950        rx_ring = &ag->rx_ring; 
    959         if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) 
     951        if (rx_ring->buf[rx_ring->dirty % rx_ring->size].rx_buf == NULL) 
    960952                goto oom; 
    961953 
  • src/linux/universal/linux-3.3/drivers/net/ethernet/ag71xx/ag71xx.h

    r19303 r19310  
    5151 
    5252#define AG71XX_TX_MTU_LEN       1540 
    53 #define AG71XX_RX_PKT_RESERVE   64 
    5453#define AG71XX_RX_PKT_SIZE      \ 
    55         (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     54        (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     55#define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) 
    5656 
    5757#define AG71XX_TX_RING_SIZE_DEFAULT     64 
     
    6262 
    6363#ifdef CONFIG_AG71XX_DEBUG 
    64 #define DBG(fmt, args...)       printk(KERN_DEBUG fmt, ## args) 
     64#define DBG(fmt, args...)       pr_debug(fmt, ## args) 
    6565#else 
    6666#define DBG(fmt, args...)       do {} while (0) 
     
    8686 
    8787struct ag71xx_buf { 
    88         struct sk_buff          *skb; 
     88        union { 
     89                struct sk_buff  *skb; 
     90                void            *rx_buf; 
     91        }; 
    8992        struct ag71xx_desc      *desc; 
    9093        dma_addr_t              dma_addr; 
  • src/linux/universal/linux-3.3/drivers/net/ethernet/ag71xx/ag71xx_main.c

    r18801 r19310  
    190190 
    191191        for (i = 0; i < ring->size; i++) 
    192                 if (ring->buf[i].skb) { 
     192                if (ring->buf[i].rx_buf) { 
    193193                        dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, 
    194                                          AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
    195                         kfree_skb(ring->buf[i].skb); 
     194                                         AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     195                        kfree(ring->buf[i].rx_buf); 
    196196                } 
    197197} 
    198198 
    199 static int ag71xx_rx_reserve(struct ag71xx *ag) 
    200 { 
    201         int reserve = 0; 
    202  
    203         if (ag71xx_get_pdata(ag)->is_ar724x) { 
    204                 if (!ag71xx_has_ar8216(ag)) 
    205                         reserve = 2; 
    206  
    207                 if (ag->phy_dev) 
    208                         reserve += 4 - (ag->phy_dev->pkt_align % 4); 
    209  
    210                 reserve %= 4; 
    211         } 
    212  
    213         return reserve + AG71XX_RX_PKT_RESERVE; 
    214 } 
    215  
     199static int ag71xx_buffer_offset(struct ag71xx *ag) 
     200{ 
     201        int offset = NET_SKB_PAD; 
     202 
     203        /* 
     204         * On AR71xx/AR91xx packets must be 4-byte aligned. 
     205         * 
     206         * When using builtin AR8216 support, hardware adds a 2-byte header, 
     207         * so we don't need any extra alignment in that case. 
     208         */ 
     209        if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) 
     210                return offset; 
     211 
     212        return offset + NET_IP_ALIGN; 
     213} 
     214 
     215static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, 
     216                               int offset) 
     217{ 
     218        void *data; 
     219 
     220        data = kmalloc(AG71XX_RX_BUF_SIZE + 
     221                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), 
     222                       GFP_ATOMIC); 
     223        if (!data) 
     224                return false; 
     225 
     226        buf->rx_buf = data; 
     227        buf->dma_addr = dma_map_single(&ag->dev->dev, data, 
     228                                       AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     229        buf->desc->data = (u32) buf->dma_addr + offset; 
     230        return true; 
     231} 
    216232 
    217233static int ag71xx_ring_rx_init(struct ag71xx *ag) 
    218234{ 
    219235        struct ag71xx_ring *ring = &ag->rx_ring; 
    220         unsigned int reserve = ag71xx_rx_reserve(ag); 
    221236        unsigned int i; 
    222237        int ret; 
     238        int offset = ag71xx_buffer_offset(ag); 
    223239 
    224240        ret = 0; 
     
    233249 
    234250        for (i = 0; i < ring->size; i++) { 
    235                 struct sk_buff *skb; 
    236                 dma_addr_t dma_addr; 
    237  
    238                 skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    239                 if (!skb) { 
     251                if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { 
    240252                        ret = -ENOMEM; 
    241253                        break; 
    242254                } 
    243255 
    244                 skb->dev = ag->dev; 
    245                 skb_reserve(skb, reserve); 
    246  
    247                 dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    248                                           AG71XX_RX_PKT_SIZE, 
    249                                           DMA_FROM_DEVICE); 
    250                 ring->buf[i].skb = skb; 
    251                 ring->buf[i].dma_addr = dma_addr; 
    252                 ring->buf[i].desc->data = (u32) dma_addr; 
    253256                ring->buf[i].desc->ctrl = DESC_EMPTY; 
    254257        } 
     
    266269{ 
    267270        struct ag71xx_ring *ring = &ag->rx_ring; 
    268         unsigned int reserve = ag71xx_rx_reserve(ag); 
    269271        unsigned int count; 
     272        int offset = ag71xx_buffer_offset(ag); 
    270273 
    271274        count = 0; 
     
    275278                i = ring->dirty % ring->size; 
    276279 
    277                 if (ring->buf[i].skb == NULL) { 
    278                         dma_addr_t dma_addr; 
    279                         struct sk_buff *skb; 
    280  
    281                         skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    282                         if (skb == NULL) 
    283                                 break; 
    284  
    285                         skb_reserve(skb, reserve); 
    286                         skb->dev = ag->dev; 
    287  
    288                         dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    289                                                   AG71XX_RX_PKT_SIZE, 
    290                                                   DMA_FROM_DEVICE); 
    291  
    292                         ring->buf[i].skb = skb; 
    293                         ring->buf[i].dma_addr = dma_addr; 
    294                         ring->buf[i].desc->data = (u32) dma_addr; 
    295                 } 
     280                if (!ring->buf[i].rx_buf && 
     281                    !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) 
     282                        break; 
    296283 
    297284                ring->buf[i].desc->ctrl = DESC_EMPTY; 
     
    872859        struct net_device *dev = ag->dev; 
    873860        struct ag71xx_ring *ring = &ag->rx_ring; 
     861        int offset = ag71xx_buffer_offset(ag); 
    874862        int done = 0; 
    875863 
     
    894882                ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
    895883 
    896                 skb = ring->buf[i].skb; 
    897884                pktlen = ag71xx_desc_pktlen(desc); 
    898885                pktlen -= ETH_FCS_LEN; 
    899886 
    900887                dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, 
    901                                  AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
     888                                 AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
    902889 
    903890                dev->last_rx = jiffies; 
     
    905892                dev->stats.rx_bytes += pktlen; 
    906893 
     894                skb = build_skb(ring->buf[i].rx_buf); 
     895                if (!skb) { 
     896                        kfree(ring->buf[i].rx_buf); 
     897                        goto next; 
     898                } 
     899 
     900                skb_reserve(skb, offset); 
    907901                skb_put(skb, pktlen); 
     902 
    908903                if (ag71xx_has_ar8216(ag)) 
    909904                        err = ag71xx_remove_ar8216_header(ag, skb, pktlen); 
     
    915910                        skb->dev = dev; 
    916911                        skb->ip_summed = CHECKSUM_NONE; 
    917                         if (ag->phy_dev) { 
    918                                 ag->phy_dev->netif_receive_skb(skb); 
    919                         } else { 
    920                                 skb->protocol = eth_type_trans(skb, dev); 
    921                                 netif_receive_skb(skb); 
    922                         } 
     912                        skb->protocol = eth_type_trans(skb, dev); 
     913                        netif_receive_skb(skb); 
    923914                } 
    924915 
    925                 ring->buf[i].skb = NULL; 
     916next: 
     917                ring->buf[i].rx_buf = NULL; 
    926918                done++; 
    927919 
     
    957949 
    958950        rx_ring = &ag->rx_ring; 
    959         if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) 
     951        if (rx_ring->buf[rx_ring->dirty % rx_ring->size].rx_buf == NULL) 
    960952                goto oom; 
    961953 
  • src/linux/universal/linux-3.3/drivers/net/ethernet/ag934x/ag71xx.h

    r19303 r19310  
    5151 
    5252#define AG71XX_TX_MTU_LEN       1540 
    53 #define AG71XX_RX_PKT_RESERVE   64 
    5453#define AG71XX_RX_PKT_SIZE      \ 
    55         (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     54        (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     55#define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) 
    5656 
    5757#define AG71XX_TX_RING_SIZE_DEFAULT     64 
     
    6262 
    6363#ifdef CONFIG_AG71XX_DEBUG 
    64 #define DBG(fmt, args...)       printk(KERN_DEBUG fmt, ## args) 
     64#define DBG(fmt, args...)       pr_debug(fmt, ## args) 
    6565#else 
    6666#define DBG(fmt, args...)       do {} while (0) 
     
    8686 
    8787struct ag71xx_buf { 
    88         struct sk_buff          *skb; 
     88        union { 
     89                struct sk_buff  *skb; 
     90                void            *rx_buf; 
     91        }; 
    8992        struct ag71xx_desc      *desc; 
    9093        dma_addr_t              dma_addr; 
  • src/linux/universal/linux-3.3/drivers/net/ethernet/ag934x/ag71xx_main.c

    r18801 r19310  
    190190 
    191191        for (i = 0; i < ring->size; i++) 
    192                 if (ring->buf[i].skb) { 
     192                if (ring->buf[i].rx_buf) { 
    193193                        dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, 
    194                                          AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
    195                         kfree_skb(ring->buf[i].skb); 
     194                                         AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     195                        kfree(ring->buf[i].rx_buf); 
    196196                } 
    197197} 
    198198 
    199 static int ag71xx_rx_reserve(struct ag71xx *ag) 
    200 { 
    201         int reserve = 0; 
    202  
    203         if (ag71xx_get_pdata(ag)->is_ar724x) { 
    204                 if (!ag71xx_has_ar8216(ag)) 
    205                         reserve = 2; 
    206  
    207                 if (ag->phy_dev) 
    208                         reserve += 4 - (ag->phy_dev->pkt_align % 4); 
    209  
    210                 reserve %= 4; 
    211         } 
    212  
    213         return reserve + AG71XX_RX_PKT_RESERVE; 
    214 } 
    215  
     199static int ag71xx_buffer_offset(struct ag71xx *ag) 
     200{ 
     201        int offset = NET_SKB_PAD; 
     202 
     203        /* 
     204         * On AR71xx/AR91xx packets must be 4-byte aligned. 
     205         * 
     206         * When using builtin AR8216 support, hardware adds a 2-byte header, 
     207         * so we don't need any extra alignment in that case. 
     208         */ 
     209        if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) 
     210                return offset; 
     211 
     212        return offset + NET_IP_ALIGN; 
     213} 
     214 
     215static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, 
     216                               int offset) 
     217{ 
     218        void *data; 
     219 
     220        data = kmalloc(AG71XX_RX_BUF_SIZE + 
     221                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), 
     222                       GFP_ATOMIC); 
     223        if (!data) 
     224                return false; 
     225 
     226        buf->rx_buf = data; 
     227        buf->dma_addr = dma_map_single(&ag->dev->dev, data, 
     228                                       AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     229        buf->desc->data = (u32) buf->dma_addr + offset; 
     230        return true; 
     231} 
    216232 
    217233static int ag71xx_ring_rx_init(struct ag71xx *ag) 
    218234{ 
    219235        struct ag71xx_ring *ring = &ag->rx_ring; 
    220         unsigned int reserve = ag71xx_rx_reserve(ag); 
    221236        unsigned int i; 
    222237        int ret; 
     238        int offset = ag71xx_buffer_offset(ag); 
    223239 
    224240        ret = 0; 
     
    233249 
    234250        for (i = 0; i < ring->size; i++) { 
    235                 struct sk_buff *skb; 
    236                 dma_addr_t dma_addr; 
    237  
    238                 skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    239                 if (!skb) { 
     251                if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { 
    240252                        ret = -ENOMEM; 
    241253                        break; 
    242254                } 
    243255 
    244                 skb->dev = ag->dev; 
    245                 skb_reserve(skb, reserve); 
    246  
    247                 dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    248                                           AG71XX_RX_PKT_SIZE, 
    249                                           DMA_FROM_DEVICE); 
    250                 ring->buf[i].skb = skb; 
    251                 ring->buf[i].dma_addr = dma_addr; 
    252                 ring->buf[i].desc->data = (u32) dma_addr; 
    253256                ring->buf[i].desc->ctrl = DESC_EMPTY; 
    254257        } 
     
    266269{ 
    267270        struct ag71xx_ring *ring = &ag->rx_ring; 
    268         unsigned int reserve = ag71xx_rx_reserve(ag); 
    269271        unsigned int count; 
     272        int offset = ag71xx_buffer_offset(ag); 
    270273 
    271274        count = 0; 
     
    275278                i = ring->dirty % ring->size; 
    276279 
    277                 if (ring->buf[i].skb == NULL) { 
    278                         dma_addr_t dma_addr; 
    279                         struct sk_buff *skb; 
    280  
    281                         skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    282                         if (skb == NULL) 
    283                                 break; 
    284  
    285                         skb_reserve(skb, reserve); 
    286                         skb->dev = ag->dev; 
    287  
    288                         dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    289                                                   AG71XX_RX_PKT_SIZE, 
    290                                                   DMA_FROM_DEVICE); 
    291  
    292                         ring->buf[i].skb = skb; 
    293                         ring->buf[i].dma_addr = dma_addr; 
    294                         ring->buf[i].desc->data = (u32) dma_addr; 
    295                 } 
     280                if (!ring->buf[i].rx_buf && 
     281                    !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) 
     282                        break; 
    296283 
    297284                ring->buf[i].desc->ctrl = DESC_EMPTY; 
     
    872859        struct net_device *dev = ag->dev; 
    873860        struct ag71xx_ring *ring = &ag->rx_ring; 
     861        int offset = ag71xx_buffer_offset(ag); 
    874862        int done = 0; 
    875863 
     
    894882                ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
    895883 
    896                 skb = ring->buf[i].skb; 
    897884                pktlen = ag71xx_desc_pktlen(desc); 
    898885                pktlen -= ETH_FCS_LEN; 
    899886 
    900887                dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, 
    901                                  AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
     888                                 AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
    902889 
    903890                dev->last_rx = jiffies; 
     
    905892                dev->stats.rx_bytes += pktlen; 
    906893 
     894                skb = build_skb(ring->buf[i].rx_buf); 
     895                if (!skb) { 
     896                        kfree(ring->buf[i].rx_buf); 
     897                        goto next; 
     898                } 
     899 
     900                skb_reserve(skb, offset); 
    907901                skb_put(skb, pktlen); 
     902 
    908903                if (ag71xx_has_ar8216(ag)) 
    909904                        err = ag71xx_remove_ar8216_header(ag, skb, pktlen); 
     
    915910                        skb->dev = dev; 
    916911                        skb->ip_summed = CHECKSUM_NONE; 
    917                         if (ag->phy_dev) { 
    918                                 ag->phy_dev->netif_receive_skb(skb); 
    919                         } else { 
    920                                 skb->protocol = eth_type_trans(skb, dev); 
    921                                 netif_receive_skb(skb); 
    922                         } 
     912                        skb->protocol = eth_type_trans(skb, dev); 
     913                        netif_receive_skb(skb); 
    923914                } 
    924915 
    925                 ring->buf[i].skb = NULL; 
     916next: 
     917                ring->buf[i].rx_buf = NULL; 
    926918                done++; 
    927919 
     
    957949 
    958950        rx_ring = &ag->rx_ring; 
    959         if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) 
     951        if (rx_ring->buf[rx_ring->dirty % rx_ring->size].rx_buf == NULL) 
    960952                goto oom; 
    961953 
  • src/linux/universal/linux-3.4/drivers/net/ethernet/ag71xx/ag71xx.h

    r19303 r19310  
    5151 
    5252#define AG71XX_TX_MTU_LEN       1540 
    53 #define AG71XX_RX_PKT_RESERVE   64 
    5453#define AG71XX_RX_PKT_SIZE      \ 
    55         (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     54        (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     55#define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) 
    5656 
    5757#define AG71XX_TX_RING_SIZE_DEFAULT     64 
     
    6262 
    6363#ifdef CONFIG_AG71XX_DEBUG 
    64 #define DBG(fmt, args...)       printk(KERN_DEBUG fmt, ## args) 
     64#define DBG(fmt, args...)       pr_debug(fmt, ## args) 
    6565#else 
    6666#define DBG(fmt, args...)       do {} while (0) 
     
    8686 
    8787struct ag71xx_buf { 
    88         struct sk_buff          *skb; 
     88        union { 
     89                struct sk_buff  *skb; 
     90                void            *rx_buf; 
     91        }; 
    8992        struct ag71xx_desc      *desc; 
    9093        dma_addr_t              dma_addr; 
  • src/linux/universal/linux-3.4/drivers/net/ethernet/ag71xx/ag71xx_main.c

    r19285 r19310  
    190190 
    191191        for (i = 0; i < ring->size; i++) 
    192                 if (ring->buf[i].skb) { 
     192                if (ring->buf[i].rx_buf) { 
    193193                        dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, 
    194                                          AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
    195                         kfree_skb(ring->buf[i].skb); 
     194                                         AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     195                        kfree(ring->buf[i].rx_buf); 
    196196                } 
    197197} 
    198198 
    199 static int ag71xx_rx_reserve(struct ag71xx *ag) 
    200 { 
    201         int reserve = 0; 
    202  
    203         if (ag71xx_get_pdata(ag)->is_ar724x) { 
    204                 if (!ag71xx_has_ar8216(ag)) 
    205                         reserve = 2; 
    206  
    207                 if (ag->phy_dev) 
    208                         reserve += 4 - (ag->phy_dev->pkt_align % 4); 
    209  
    210                 reserve %= 4; 
    211         } 
    212  
    213         return reserve + AG71XX_RX_PKT_RESERVE; 
    214 } 
    215  
     199static int ag71xx_buffer_offset(struct ag71xx *ag) 
     200{ 
     201        int offset = NET_SKB_PAD; 
     202 
     203        /* 
     204         * On AR71xx/AR91xx packets must be 4-byte aligned. 
     205         * 
     206         * When using builtin AR8216 support, hardware adds a 2-byte header, 
     207         * so we don't need any extra alignment in that case. 
     208         */ 
     209        if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) 
     210                return offset; 
     211 
     212        return offset + NET_IP_ALIGN; 
     213} 
     214 
     215static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, 
     216                               int offset) 
     217{ 
     218        void *data; 
     219 
     220        data = kmalloc(AG71XX_RX_BUF_SIZE + 
     221                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), 
     222                       GFP_ATOMIC); 
     223        if (!data) 
     224                return false; 
     225 
     226        buf->rx_buf = data; 
     227        buf->dma_addr = dma_map_single(&ag->dev->dev, data, 
     228                                       AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     229        buf->desc->data = (u32) buf->dma_addr + offset; 
     230        return true; 
     231} 
    216232 
    217233static int ag71xx_ring_rx_init(struct ag71xx *ag) 
    218234{ 
    219235        struct ag71xx_ring *ring = &ag->rx_ring; 
    220         unsigned int reserve = ag71xx_rx_reserve(ag); 
    221236        unsigned int i; 
    222237        int ret; 
     238        int offset = ag71xx_buffer_offset(ag); 
    223239 
    224240        ret = 0; 
     
    233249 
    234250        for (i = 0; i < ring->size; i++) { 
    235                 struct sk_buff *skb; 
    236                 dma_addr_t dma_addr; 
    237  
    238                 skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    239                 if (!skb) { 
     251                if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { 
    240252                        ret = -ENOMEM; 
    241253                        break; 
    242254                } 
    243255 
    244                 skb->dev = ag->dev; 
    245                 skb_reserve(skb, reserve); 
    246  
    247                 dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    248                                           AG71XX_RX_PKT_SIZE, 
    249                                           DMA_FROM_DEVICE); 
    250                 ring->buf[i].skb = skb; 
    251                 ring->buf[i].dma_addr = dma_addr; 
    252                 ring->buf[i].desc->data = (u32) dma_addr; 
    253256                ring->buf[i].desc->ctrl = DESC_EMPTY; 
    254257        } 
     
    266269{ 
    267270        struct ag71xx_ring *ring = &ag->rx_ring; 
    268         unsigned int reserve = ag71xx_rx_reserve(ag); 
    269271        unsigned int count; 
     272        int offset = ag71xx_buffer_offset(ag); 
    270273 
    271274        count = 0; 
     
    275278                i = ring->dirty % ring->size; 
    276279 
    277                 if (ring->buf[i].skb == NULL) { 
    278                         dma_addr_t dma_addr; 
    279                         struct sk_buff *skb; 
    280  
    281                         skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    282                         if (skb == NULL) 
    283                                 break; 
    284  
    285                         skb_reserve(skb, reserve); 
    286                         skb->dev = ag->dev; 
    287  
    288                         dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    289                                                   AG71XX_RX_PKT_SIZE, 
    290                                                   DMA_FROM_DEVICE); 
    291  
    292                         ring->buf[i].skb = skb; 
    293                         ring->buf[i].dma_addr = dma_addr; 
    294                         ring->buf[i].desc->data = (u32) dma_addr; 
    295                 } 
     280                if (!ring->buf[i].rx_buf && 
     281                    !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) 
     282                        break; 
    296283 
    297284                ring->buf[i].desc->ctrl = DESC_EMPTY; 
     
    872859        struct net_device *dev = ag->dev; 
    873860        struct ag71xx_ring *ring = &ag->rx_ring; 
     861        int offset = ag71xx_buffer_offset(ag); 
    874862        int done = 0; 
    875863 
     
    894882                ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
    895883 
    896                 skb = ring->buf[i].skb; 
    897884                pktlen = ag71xx_desc_pktlen(desc); 
    898885                pktlen -= ETH_FCS_LEN; 
    899886 
    900887                dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, 
    901                                  AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
     888                                 AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
    902889 
    903890                dev->last_rx = jiffies; 
     
    905892                dev->stats.rx_bytes += pktlen; 
    906893 
     894                skb = build_skb(ring->buf[i].rx_buf); 
     895                if (!skb) { 
     896                        kfree(ring->buf[i].rx_buf); 
     897                        goto next; 
     898                } 
     899 
     900                skb_reserve(skb, offset); 
    907901                skb_put(skb, pktlen); 
     902 
    908903                if (ag71xx_has_ar8216(ag)) 
    909904                        err = ag71xx_remove_ar8216_header(ag, skb, pktlen); 
     
    915910                        skb->dev = dev; 
    916911                        skb->ip_summed = CHECKSUM_NONE; 
    917                         if (ag->phy_dev) { 
    918                                 ag->phy_dev->netif_receive_skb(skb); 
    919                         } else { 
    920                                 skb->protocol = eth_type_trans(skb, dev); 
    921                                 netif_receive_skb(skb); 
    922                         } 
     912                        skb->protocol = eth_type_trans(skb, dev); 
     913                        netif_receive_skb(skb); 
    923914                } 
    924915 
    925                 ring->buf[i].skb = NULL; 
     916next: 
     917                ring->buf[i].rx_buf = NULL; 
    926918                done++; 
    927919 
     
    957949 
    958950        rx_ring = &ag->rx_ring; 
    959         if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) 
     951        if (rx_ring->buf[rx_ring->dirty % rx_ring->size].rx_buf == NULL) 
    960952                goto oom; 
    961953 
  • src/linux/universal/linux-3.4/drivers/net/ethernet/ag934x/ag71xx.h

    r19303 r19310  
    5151 
    5252#define AG71XX_TX_MTU_LEN       1540 
    53 #define AG71XX_RX_PKT_RESERVE   64 
    5453#define AG71XX_RX_PKT_SIZE      \ 
    55         (AG71XX_RX_PKT_RESERVE + ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     54        (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 
     55#define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) 
    5656 
    5757#define AG71XX_TX_RING_SIZE_DEFAULT     64 
     
    6262 
    6363#ifdef CONFIG_AG71XX_DEBUG 
    64 #define DBG(fmt, args...)       printk(KERN_DEBUG fmt, ## args) 
     64#define DBG(fmt, args...)       pr_debug(fmt, ## args) 
    6565#else 
    6666#define DBG(fmt, args...)       do {} while (0) 
     
    8686 
    8787struct ag71xx_buf { 
    88         struct sk_buff          *skb; 
     88        union { 
     89                struct sk_buff  *skb; 
     90                void            *rx_buf; 
     91        }; 
    8992        struct ag71xx_desc      *desc; 
    9093        dma_addr_t              dma_addr; 
  • src/linux/universal/linux-3.4/drivers/net/ethernet/ag934x/ag71xx_main.c

    r19285 r19310  
    190190 
    191191        for (i = 0; i < ring->size; i++) 
    192                 if (ring->buf[i].skb) { 
     192                if (ring->buf[i].rx_buf) { 
    193193                        dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, 
    194                                          AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
    195                         kfree_skb(ring->buf[i].skb); 
     194                                         AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     195                        kfree(ring->buf[i].rx_buf); 
    196196                } 
    197197} 
    198198 
    199 static int ag71xx_rx_reserve(struct ag71xx *ag) 
    200 { 
    201         int reserve = 0; 
    202  
    203         if (ag71xx_get_pdata(ag)->is_ar724x) { 
    204                 if (!ag71xx_has_ar8216(ag)) 
    205                         reserve = 2; 
    206  
    207                 if (ag->phy_dev) 
    208                         reserve += 4 - (ag->phy_dev->pkt_align % 4); 
    209  
    210                 reserve %= 4; 
    211         } 
    212  
    213         return reserve + AG71XX_RX_PKT_RESERVE; 
    214 } 
    215  
     199static int ag71xx_buffer_offset(struct ag71xx *ag) 
     200{ 
     201        int offset = NET_SKB_PAD; 
     202 
     203        /* 
     204         * On AR71xx/AR91xx packets must be 4-byte aligned. 
     205         * 
     206         * When using builtin AR8216 support, hardware adds a 2-byte header, 
     207         * so we don't need any extra alignment in that case. 
     208         */ 
     209        if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) 
     210                return offset; 
     211 
     212        return offset + NET_IP_ALIGN; 
     213} 
     214 
     215static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, 
     216                               int offset) 
     217{ 
     218        void *data; 
     219 
     220        data = kmalloc(AG71XX_RX_BUF_SIZE + 
     221                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), 
     222                       GFP_ATOMIC); 
     223        if (!data) 
     224                return false; 
     225 
     226        buf->rx_buf = data; 
     227        buf->dma_addr = dma_map_single(&ag->dev->dev, data, 
     228                                       AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
     229        buf->desc->data = (u32) buf->dma_addr + offset; 
     230        return true; 
     231} 
    216232 
    217233static int ag71xx_ring_rx_init(struct ag71xx *ag) 
    218234{ 
    219235        struct ag71xx_ring *ring = &ag->rx_ring; 
    220         unsigned int reserve = ag71xx_rx_reserve(ag); 
    221236        unsigned int i; 
    222237        int ret; 
     238        int offset = ag71xx_buffer_offset(ag); 
    223239 
    224240        ret = 0; 
     
    233249 
    234250        for (i = 0; i < ring->size; i++) { 
    235                 struct sk_buff *skb; 
    236                 dma_addr_t dma_addr; 
    237  
    238                 skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    239                 if (!skb) { 
     251                if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { 
    240252                        ret = -ENOMEM; 
    241253                        break; 
    242254                } 
    243255 
    244                 skb->dev = ag->dev; 
    245                 skb_reserve(skb, reserve); 
    246  
    247                 dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    248                                           AG71XX_RX_PKT_SIZE, 
    249                                           DMA_FROM_DEVICE); 
    250                 ring->buf[i].skb = skb; 
    251                 ring->buf[i].dma_addr = dma_addr; 
    252                 ring->buf[i].desc->data = (u32) dma_addr; 
    253256                ring->buf[i].desc->ctrl = DESC_EMPTY; 
    254257        } 
     
    266269{ 
    267270        struct ag71xx_ring *ring = &ag->rx_ring; 
    268         unsigned int reserve = ag71xx_rx_reserve(ag); 
    269271        unsigned int count; 
     272        int offset = ag71xx_buffer_offset(ag); 
    270273 
    271274        count = 0; 
     
    275278                i = ring->dirty % ring->size; 
    276279 
    277                 if (ring->buf[i].skb == NULL) { 
    278                         dma_addr_t dma_addr; 
    279                         struct sk_buff *skb; 
    280  
    281                         skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE + reserve); 
    282                         if (skb == NULL) 
    283                                 break; 
    284  
    285                         skb_reserve(skb, reserve); 
    286                         skb->dev = ag->dev; 
    287  
    288                         dma_addr = dma_map_single(&ag->dev->dev, skb->data, 
    289                                                   AG71XX_RX_PKT_SIZE, 
    290                                                   DMA_FROM_DEVICE); 
    291  
    292                         ring->buf[i].skb = skb; 
    293                         ring->buf[i].dma_addr = dma_addr; 
    294                         ring->buf[i].desc->data = (u32) dma_addr; 
    295                 } 
     280                if (!ring->buf[i].rx_buf && 
     281                    !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) 
     282                        break; 
    296283 
    297284                ring->buf[i].desc->ctrl = DESC_EMPTY; 
     
    872859        struct net_device *dev = ag->dev; 
    873860        struct ag71xx_ring *ring = &ag->rx_ring; 
     861        int offset = ag71xx_buffer_offset(ag); 
    874862        int done = 0; 
    875863 
     
    894882                ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 
    895883 
    896                 skb = ring->buf[i].skb; 
    897884                pktlen = ag71xx_desc_pktlen(desc); 
    898885                pktlen -= ETH_FCS_LEN; 
    899886 
    900887                dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, 
    901                                  AG71XX_RX_PKT_SIZE, DMA_FROM_DEVICE); 
     888                                 AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 
    902889 
    903890                dev->last_rx = jiffies; 
     
    905892                dev->stats.rx_bytes += pktlen; 
    906893 
     894                skb = build_skb(ring->buf[i].rx_buf); 
     895                if (!skb) { 
     896                        kfree(ring->buf[i].rx_buf); 
     897                        goto next; 
     898                } 
     899 
     900                skb_reserve(skb, offset); 
    907901                skb_put(skb, pktlen); 
     902 
    908903                if (ag71xx_has_ar8216(ag)) 
    909904                        err = ag71xx_remove_ar8216_header(ag, skb, pktlen); 
     
    915910                        skb->dev = dev; 
    916911                        skb->ip_summed = CHECKSUM_NONE; 
    917                         if (ag->phy_dev) { 
    918                                 ag->phy_dev->netif_receive_skb(skb); 
    919                         } else { 
    920                                 skb->protocol = eth_type_trans(skb, dev); 
    921                                 netif_receive_skb(skb); 
    922                         } 
     912                        skb->protocol = eth_type_trans(skb, dev); 
     913                        netif_receive_skb(skb); 
    923914                } 
    924915 
    925                 ring->buf[i].skb = NULL; 
     916next: 
     917                ring->buf[i].rx_buf = NULL; 
    926918                done++; 
    927919 
     
    957949 
    958950        rx_ring = &ag->rx_ring; 
    959         if (rx_ring->buf[rx_ring->dirty % rx_ring->size].skb == NULL) 
     951        if (rx_ring->buf[rx_ring->dirty % rx_ring->size].rx_buf == NULL) 
    960952                goto oom; 
    961953 
Note: See TracChangeset for help on using the changeset viewer.