kernel: add missing config symbol
[15.05/openwrt.git] / target / linux / generic / patches-3.18 / 077-02-bgmac-implement-GRO-and-use-build_skb.patch
1 From: Felix Fietkau <nbd@openwrt.org>
2 Date: Mon, 23 Mar 2015 02:41:25 +0100
3 Subject: [PATCH] bgmac: implement GRO and use build_skb
4
5 This improves performance for routing and local rx
6
7 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
8 ---
9
10 --- a/drivers/net/ethernet/broadcom/bgmac.c
11 +++ b/drivers/net/ethernet/broadcom/bgmac.c
12 @@ -276,31 +276,31 @@ static int bgmac_dma_rx_skb_for_slot(str
13                                      struct bgmac_slot_info *slot)
14  {
15         struct device *dma_dev = bgmac->core->dma_dev;
16 -       struct sk_buff *skb;
17         dma_addr_t dma_addr;
18         struct bgmac_rx_header *rx;
19 +       void *buf;
20  
21         /* Alloc skb */
22 -       skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
23 -       if (!skb)
24 +       buf = netdev_alloc_frag(BGMAC_RX_ALLOC_SIZE);
25 +       if (!buf)
26                 return -ENOMEM;
27  
28         /* Poison - if everything goes fine, hardware will overwrite it */
29 -       rx = (struct bgmac_rx_header *)skb->data;
30 +       rx = buf;
31         rx->len = cpu_to_le16(0xdead);
32         rx->flags = cpu_to_le16(0xbeef);
33  
34         /* Map skb for the DMA */
35 -       dma_addr = dma_map_single(dma_dev, skb->data,
36 -                                 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
37 +       dma_addr = dma_map_single(dma_dev, buf, BGMAC_RX_BUF_SIZE,
38 +                                 DMA_FROM_DEVICE);
39         if (dma_mapping_error(dma_dev, dma_addr)) {
40                 bgmac_err(bgmac, "DMA mapping error\n");
41 -               dev_kfree_skb(skb);
42 +               put_page(virt_to_head_page(buf));
43                 return -ENOMEM;
44         }
45  
46         /* Update the slot */
47 -       slot->skb = skb;
48 +       slot->buf = buf;
49         slot->dma_addr = dma_addr;
50  
51         return 0;
52 @@ -343,8 +343,9 @@ static int bgmac_dma_rx_read(struct bgma
53         while (ring->start != ring->end) {
54                 struct device *dma_dev = bgmac->core->dma_dev;
55                 struct bgmac_slot_info *slot = &ring->slots[ring->start];
56 -               struct sk_buff *skb = slot->skb;
57 -               struct bgmac_rx_header *rx;
58 +               struct bgmac_rx_header *rx = slot->buf;
59 +               struct sk_buff *skb;
60 +               void *buf = slot->buf;
61                 u16 len, flags;
62  
63                 /* Unmap buffer to make it accessible to the CPU */
64 @@ -352,7 +353,6 @@ static int bgmac_dma_rx_read(struct bgma
65                                         BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
66  
67                 /* Get info from the header */
68 -               rx = (struct bgmac_rx_header *)skb->data;
69                 len = le16_to_cpu(rx->len);
70                 flags = le16_to_cpu(rx->flags);
71  
72 @@ -393,12 +393,13 @@ static int bgmac_dma_rx_read(struct bgma
73                         dma_unmap_single(dma_dev, old_dma_addr,
74                                          BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
75  
76 +                       skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE);
77                         skb_put(skb, BGMAC_RX_FRAME_OFFSET + len);
78                         skb_pull(skb, BGMAC_RX_FRAME_OFFSET);
79  
80                         skb_checksum_none_assert(skb);
81                         skb->protocol = eth_type_trans(skb, bgmac->net_dev);
82 -                       netif_receive_skb(skb);
83 +                       napi_gro_receive(&bgmac->napi, skb);
84                         handled++;
85                 } while (0);
86  
87 @@ -434,12 +435,11 @@ static bool bgmac_dma_unaligned(struct b
88         return false;
89  }
90  
91 -static void bgmac_dma_ring_free(struct bgmac *bgmac,
92 -                               struct bgmac_dma_ring *ring)
93 +static void bgmac_dma_tx_ring_free(struct bgmac *bgmac,
94 +                                  struct bgmac_dma_ring *ring)
95  {
96         struct device *dma_dev = bgmac->core->dma_dev;
97         struct bgmac_slot_info *slot;
98 -       int size;
99         int i;
100  
101         for (i = 0; i < ring->num_slots; i++) {
102 @@ -451,23 +451,55 @@ static void bgmac_dma_ring_free(struct b
103                         dev_kfree_skb(slot->skb);
104                 }
105         }
106 +}
107 +
108 +static void bgmac_dma_rx_ring_free(struct bgmac *bgmac,
109 +                                  struct bgmac_dma_ring *ring)
110 +{
111 +       struct device *dma_dev = bgmac->core->dma_dev;
112 +       struct bgmac_slot_info *slot;
113 +       int i;
114 +
115 +       for (i = 0; i < ring->num_slots; i++) {
116 +               slot = &ring->slots[i];
117 +               if (!slot->buf)
118 +                       continue;
119  
120 -       if (ring->cpu_base) {
121 -               /* Free ring of descriptors */
122 -               size = ring->num_slots * sizeof(struct bgmac_dma_desc);
123 -               dma_free_coherent(dma_dev, size, ring->cpu_base,
124 -                                 ring->dma_base);
125 +               if (slot->dma_addr)
126 +                       dma_unmap_single(dma_dev, slot->dma_addr,
127 +                                        BGMAC_RX_BUF_SIZE,
128 +                                        DMA_FROM_DEVICE);
129 +               put_page(virt_to_head_page(slot->buf));
130         }
131  }
132  
133 +static void bgmac_dma_ring_desc_free(struct bgmac *bgmac,
134 +                                    struct bgmac_dma_ring *ring)
135 +{
136 +       struct device *dma_dev = bgmac->core->dma_dev;
137 +       int size;
138 +
139 +       if (!ring->cpu_base)
140 +           return;
141 +
142 +       /* Free ring of descriptors */
143 +       size = ring->num_slots * sizeof(struct bgmac_dma_desc);
144 +       dma_free_coherent(dma_dev, size, ring->cpu_base,
145 +                         ring->dma_base);
146 +}
147 +
148  static void bgmac_dma_free(struct bgmac *bgmac)
149  {
150         int i;
151  
152 -       for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
153 -               bgmac_dma_ring_free(bgmac, &bgmac->tx_ring[i]);
154 -       for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
155 -               bgmac_dma_ring_free(bgmac, &bgmac->rx_ring[i]);
156 +       for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
157 +               bgmac_dma_tx_ring_free(bgmac, &bgmac->tx_ring[i]);
158 +               bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]);
159 +       }
160 +       for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
161 +               bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]);
162 +               bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]);
163 +       }
164  }
165  
166  static int bgmac_dma_alloc(struct bgmac *bgmac)
167 --- a/drivers/net/ethernet/broadcom/bgmac.h
168 +++ b/drivers/net/ethernet/broadcom/bgmac.h
169 @@ -362,6 +362,8 @@
170  #define BGMAC_RX_FRAME_OFFSET                  30              /* There are 2 unused bytes between header and real data */
171  #define BGMAC_RX_MAX_FRAME_SIZE                        1536            /* Copied from b44/tg3 */
172  #define BGMAC_RX_BUF_SIZE                      (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
173 +#define BGMAC_RX_ALLOC_SIZE                    (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE) + \
174 +                                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
175  
176  #define BGMAC_BFL_ENETROBO                     0x0010          /* has ephy roboswitch spi */
177  #define BGMAC_BFL_ENETADM                      0x0080          /* has ADMtek switch */
178 @@ -383,7 +385,10 @@
179  #define ETHER_MAX_LEN   1518
180  
181  struct bgmac_slot_info {
182 -       struct sk_buff *skb;
183 +       union {
184 +               struct sk_buff *skb;
185 +               void *buf;
186 +       };
187         dma_addr_t dma_addr;
188  };
189