Changeset 31934
- Timestamp:
- 2012-05-28T04:55:59+02:00 (6 years ago)
- Location:
- trunk/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
r31925 r31934 54 54 #define AG71XX_RX_PKT_SIZE \ 55 55 (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) 56 #define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) 56 57 57 58 #define AG71XX_TX_RING_SIZE_DEFAULT 64 … … 86 87 87 88 struct ag71xx_buf { 88 struct sk_buff *skb; 89 union { 90 struct sk_buff *skb; 91 void *rx_buf; 92 }; 89 93 struct ag71xx_desc *desc; 90 94 dma_addr_t dma_addr; -
trunk/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
r31637 r31934 190 190 191 191 for (i = 0; i < ring->size; i++) 192 if (ring->buf[i]. skb) {192 if (ring->buf[i].rx_buf) { 193 193 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); 196 196 } 197 197 } 198 198 199 struct sk_buff *ag71xx_rx_alloc(struct ag71xx *ag) 200 { 199 static int ag71xx_buffer_offset(struct ag71xx *ag) 200 { 201 int offset = NET_SKB_PAD; 202 201 203 /* 202 204 * On AR71xx/AR91xx packets must be 4-byte aligned. … … 206 208 */ 207 209 if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) 208 return netdev_alloc_skb(ag->dev, AG71XX_RX_PKT_SIZE); 209 210 return netdev_alloc_skb_ip_align(ag->dev, AG71XX_RX_PKT_SIZE); 211 } 212 210 return offset; 211 212 return offset + NET_IP_ALIGN; 213 } 214 215 static 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 } 213 232 214 233 static int ag71xx_ring_rx_init(struct ag71xx *ag) … … 217 236 unsigned int i; 218 237 int ret; 238 int offset = ag71xx_buffer_offset(ag); 219 239 220 240 ret = 0; … … 229 249 230 250 for (i = 0; i < ring->size; i++) { 231 struct sk_buff *skb; 232 dma_addr_t dma_addr; 233 234 skb = ag71xx_rx_alloc(ag); 235 if (!skb) { 251 if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { 236 252 ret = -ENOMEM; 237 253 break; 238 254 } 239 255 240 skb->dev = ag->dev;241 dma_addr = dma_map_single(&ag->dev->dev, skb->data,242 AG71XX_RX_PKT_SIZE,243 DMA_FROM_DEVICE);244 ring->buf[i].skb = skb;245 ring->buf[i].dma_addr = dma_addr;246 ring->buf[i].desc->data = (u32) dma_addr;247 256 ring->buf[i].desc->ctrl = DESC_EMPTY; 248 257 } … … 261 270 struct ag71xx_ring *ring = &ag->rx_ring; 262 271 unsigned int count; 272 int offset = ag71xx_buffer_offset(ag); 263 273 264 274 count = 0; … … 268 278 i = ring->dirty % ring->size; 269 279 270 if (ring->buf[i].skb == NULL) { 271 dma_addr_t dma_addr; 272 struct sk_buff *skb; 273 274 skb = ag71xx_rx_alloc(ag); 275 if (skb == NULL) 276 break; 277 278 skb->dev = ag->dev; 279 280 dma_addr = dma_map_single(&ag->dev->dev, skb->data, 281 AG71XX_RX_PKT_SIZE, 282 DMA_FROM_DEVICE); 283 284 ring->buf[i].skb = skb; 285 ring->buf[i].dma_addr = dma_addr; 286 ring->buf[i].desc->data = (u32) dma_addr; 287 } 280 if (!ring->buf[i].rx_buf && 281 !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) 282 break; 288 283 289 284 ring->buf[i].desc->ctrl = DESC_EMPTY; … … 864 859 struct net_device *dev = ag->dev; 865 860 struct ag71xx_ring *ring = &ag->rx_ring; 861 int offset = ag71xx_buffer_offset(ag); 866 862 int done = 0; 867 863 … … 886 882 ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); 887 883 888 skb = ring->buf[i].skb;889 884 pktlen = ag71xx_desc_pktlen(desc); 890 885 pktlen -= ETH_FCS_LEN; 891 886 892 887 dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, 893 AG71XX_RX_ PKT_SIZE, DMA_FROM_DEVICE);888 AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); 894 889 895 890 dev->last_rx = jiffies; … … 897 892 dev->stats.rx_bytes += pktlen; 898 893 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); 899 901 skb_put(skb, pktlen); 902 900 903 if (ag71xx_has_ar8216(ag)) 901 904 err = ag71xx_remove_ar8216_header(ag, skb, pktlen); … … 911 914 } 912 915 913 ring->buf[i].skb = NULL; 916 next: 917 ring->buf[i].rx_buf = NULL; 914 918 done++; 915 919 … … 945 949 946 950 rx_ring = &ag->rx_ring; 947 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) 948 952 goto oom; 949 953
Note: See TracChangeset
for help on using the changeset viewer.