do *not* enable CONFIG_PCI in generic config, but on targets where it makes sense...
[openwrt.git] / target / linux / brcm63xx / patches-2.6.30 / 060-bcm63xx_enet_upstream_fixes.patch
1 --- a/drivers/net/bcm63xx_enet.c        2009-07-31 22:06:20.000000000 +0200
2 +++ b/drivers/net/bcm63xx_enet.c        2009-08-05 10:02:28.000000000 +0200
3 @@ -28,7 +28,6 @@
4  #include <linux/dma-mapping.h>
5  #include <linux/platform_device.h>
6  #include <linux/if_vlan.h>
7 -#include <linux/version.h>
8  
9  #include <bcm63xx_dev_enet.h>
10  #include "bcm63xx_enet.h"
11 @@ -91,7 +90,7 @@
12                 if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
13                         break;
14                 udelay(1);
15 -       } while (limit-- >= 0);
16 +       } while (limit-- > 0);
17  
18         return (limit < 0) ? 1 : 0;
19  }
20 @@ -321,7 +320,7 @@
21                 if (len < copybreak) {
22                         struct sk_buff *nskb;
23  
24 -                       nskb = netdev_alloc_skb(dev, len + 2);
25 +                       nskb = netdev_alloc_skb(dev, len + NET_IP_ALIGN);
26                         if (!nskb) {
27                                 /* forget packet, just rearm desc */
28                                 priv->stats.rx_dropped++;
29 @@ -452,11 +451,7 @@
30  
31         /* no more packet in rx/tx queue, remove device from poll
32          * queue */
33 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
34 -       netif_rx_complete(dev, napi);
35 -#else
36         napi_complete(napi);
37 -#endif
38  
39         /* restore rx/tx interrupt */
40         enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
41 @@ -508,11 +503,7 @@
42         enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
43         enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
44  
45 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
46 -       netif_rx_schedule(dev, &priv->napi);
47 -#else
48         napi_schedule(&priv->napi);
49 -#endif
50  
51         return IRQ_HANDLED;
52  }
53 @@ -764,11 +755,11 @@
54                 pr_info("%s: link %s", dev->name, phydev->link ?
55                         "UP" : "DOWN");
56                 if (phydev->link)
57 -                       printk(" - %d/%s - flow control %s", phydev->speed,
58 +                       pr_cont(" - %d/%s - flow control %s", phydev->speed,
59                                DUPLEX_FULL == phydev->duplex ? "full" : "half",
60                                phydev->pause == 1 ? "rx&tx" : "off");
61  
62 -               printk("\n");
63 +               pr_cont("\n");
64         }
65  }
66  
67 @@ -782,6 +773,7 @@
68         priv = netdev_priv(dev);
69         bcm_enet_set_duplex(priv, priv->force_duplex_full);
70         bcm_enet_set_flow(priv, priv->pause_rx, priv->pause_tx);
71 +       netif_carrier_on(dev);
72  
73         pr_info("%s: link forced UP - %d/%s - flow control %s/%s\n",
74                 dev->name,
75 @@ -800,21 +792,18 @@
76         struct sockaddr addr;
77         struct device *kdev;
78         struct phy_device *phydev;
79 -       int irq_requested, i, ret;
80 +       int i, ret;
81         unsigned int size;
82 -       char phy_id[BUS_ID_SIZE];
83 +       char phy_id[MII_BUS_ID_SIZE + 3];
84         void *p;
85         u32 val;
86  
87         priv = netdev_priv(dev);
88 -       priv->rx_desc_cpu = priv->tx_desc_cpu = NULL;
89 -       priv->rx_skb = priv->tx_skb = NULL;
90 -
91         kdev = &priv->pdev->dev;
92  
93         if (priv->has_phy) {
94                 /* connect to PHY */
95 -               snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT,
96 +               snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
97                          priv->mac_id ? "1" : "0", priv->phy_id);
98  
99                 phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0,
100 @@ -854,23 +843,19 @@
101         enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
102         enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
103  
104 -       irq_requested = 0;
105         ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
106         if (ret)
107 -               goto out;
108 -       irq_requested++;
109 +               goto out_phy_disconnect;
110  
111         ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
112                           IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev);
113         if (ret)
114 -               goto out;
115 -       irq_requested++;
116 +               goto out_freeirq;
117  
118         ret = request_irq(priv->irq_tx, bcm_enet_isr_dma,
119                           IRQF_DISABLED, dev->name, dev);
120         if (ret)
121 -               goto out;
122 -       irq_requested++;
123 +               goto out_freeirq_rx;
124  
125         /* initialize perfect match registers */
126         for (i = 0; i < 4; i++) {
127 @@ -888,7 +873,7 @@
128         if (!p) {
129                 dev_err(kdev, "cannot allocate rx ring %u\n", size);
130                 ret = -ENOMEM;
131 -               goto out;
132 +               goto out_freeirq_tx;
133         }
134  
135         memset(p, 0, size);
136 @@ -901,7 +886,7 @@
137         if (!p) {
138                 dev_err(kdev, "cannot allocate tx ring\n");
139                 ret = -ENOMEM;
140 -               goto out;
141 +               goto out_free_rx_ring;
142         }
143  
144         memset(p, 0, size);
145 @@ -913,7 +898,7 @@
146         if (!priv->tx_skb) {
147                 dev_err(kdev, "cannot allocate rx skb queue\n");
148                 ret = -ENOMEM;
149 -               goto out;
150 +               goto out_free_tx_ring;
151         }
152  
153         priv->tx_desc_count = priv->tx_ring_size;
154 @@ -927,7 +912,7 @@
155         if (!priv->rx_skb) {
156                 dev_err(kdev, "cannot allocate rx skb queue\n");
157                 ret = -ENOMEM;
158 -               goto out;
159 +               goto out_free_tx_skb;
160         }
161  
162         priv->rx_desc_count = 0;
163 @@ -1012,13 +997,6 @@
164         return 0;
165  
166  out:
167 -       phy_disconnect(priv->phydev);
168 -       if (irq_requested > 2)
169 -               free_irq(priv->irq_tx, dev);
170 -       if (irq_requested > 1)
171 -               free_irq(priv->irq_rx, dev);
172 -       if (irq_requested > 0)
173 -               free_irq(dev->irq, dev);
174         for (i = 0; i < priv->rx_ring_size; i++) {
175                 struct bcm_enet_desc *desc;
176  
177 @@ -1030,14 +1008,31 @@
178                                  DMA_FROM_DEVICE);
179                 kfree_skb(priv->rx_skb[i]);
180         }
181 -       if (priv->rx_desc_cpu)
182 -               dma_free_coherent(kdev, priv->rx_desc_alloc_size,
183 -                                 priv->rx_desc_cpu, priv->rx_desc_dma);
184 -       if (priv->tx_desc_cpu)
185 -               dma_free_coherent(kdev, priv->tx_desc_alloc_size,
186 -                                 priv->tx_desc_cpu, priv->tx_desc_dma);
187         kfree(priv->rx_skb);
188 +
189 +out_free_tx_skb:
190         kfree(priv->tx_skb);
191 +
192 +out_free_tx_ring:
193 +       dma_free_coherent(kdev, priv->tx_desc_alloc_size,
194 +                         priv->tx_desc_cpu, priv->tx_desc_dma);
195 +
196 +out_free_rx_ring:
197 +       dma_free_coherent(kdev, priv->rx_desc_alloc_size,
198 +                         priv->rx_desc_cpu, priv->rx_desc_dma);
199 +
200 +out_freeirq_tx:
201 +       free_irq(priv->irq_tx, dev);
202 +
203 +out_freeirq_rx:
204 +       free_irq(priv->irq_rx, dev);
205 +
206 +out_freeirq:
207 +       free_irq(dev->irq, dev);
208 +
209 +out_phy_disconnect:
210 +       phy_disconnect(priv->phydev);
211 +
212         return ret;
213  }
214  
215 @@ -1606,6 +1601,20 @@
216         enet_writel(priv, val, ENET_MIBCTL_REG);
217  }
218  
219 +static const struct net_device_ops bcm_enet_ops = {
220 +       .ndo_open               = bcm_enet_open,
221 +       .ndo_stop               = bcm_enet_stop,
222 +       .ndo_start_xmit         = bcm_enet_start_xmit,
223 +       .ndo_get_stats          = bcm_enet_get_stats,
224 +       .ndo_set_mac_address    = bcm_enet_set_mac_address,
225 +       .ndo_set_multicast_list = bcm_enet_set_multicast_list,
226 +       .ndo_do_ioctl           = bcm_enet_ioctl,
227 +       .ndo_change_mtu         = bcm_enet_change_mtu,
228 +#ifdef CONFIG_NET_POLL_CONTROLLER
229 +       .ndo_poll_controller = bcm_enet_netpoll,
230 +#endif
231 +};
232 +
233  /*
234   * allocate netdevice, request register memory and register device.
235   */
236 @@ -1618,15 +1627,13 @@
237         struct mii_bus *bus;
238         const char *clk_name;
239         unsigned int iomem_size;
240 -       int i, ret, mdio_registered, mem_requested;
241 +       int i, ret;
242  
243         /* stop if shared driver failed, assume driver->probe will be
244          * called in the same order we register devices (correct ?) */
245         if (!bcm_enet_shared_base)
246                 return -ENODEV;
247  
248 -       mdio_registered = mem_requested = 0;
249 -
250         res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
251         res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
252         res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
253 @@ -1648,14 +1655,13 @@
254         iomem_size = res_mem->end - res_mem->start + 1;
255         if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) {
256                 ret = -EBUSY;
257 -               goto err;
258 +               goto out;
259         }
260 -       mem_requested = 1;
261  
262         priv->base = ioremap(res_mem->start, iomem_size);
263         if (priv->base == NULL) {
264                 ret = -ENOMEM;
265 -               goto err;
266 +               goto out_release_mem;
267         }
268         dev->irq = priv->irq = res_irq->start;
269         priv->irq_rx = res_irq_rx->start;
270 @@ -1676,8 +1682,7 @@
271         priv->mac_clk = clk_get(&pdev->dev, clk_name);
272         if (IS_ERR(priv->mac_clk)) {
273                 ret = PTR_ERR(priv->mac_clk);
274 -               priv->mac_clk = NULL;
275 -               goto err;
276 +               goto out_unmap;
277         }
278         clk_enable(priv->mac_clk);
279  
280 @@ -1706,7 +1711,7 @@
281                 if (IS_ERR(priv->phy_clk)) {
282                         ret = PTR_ERR(priv->phy_clk);
283                         priv->phy_clk = NULL;
284 -                       goto err;
285 +                       goto out_put_clk_mac;
286                 }
287                 clk_enable(priv->phy_clk);
288         }
289 @@ -1716,13 +1721,16 @@
290  
291         /* MII bus registration */
292         if (priv->has_phy) {
293 -               bus = &priv->mii_bus;
294 +
295 +               priv->mii_bus = mdiobus_alloc();
296 +               if (!priv->mii_bus) {
297 +                       ret = -ENOMEM;
298 +                       goto out_uninit_hw;
299 +               }
300 +
301 +               bus = priv->mii_bus;
302                 bus->name = "bcm63xx_enet MII bus";
303 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
304 -               bus->dev = &pdev->dev;
305 -#else
306                 bus->parent = &pdev->dev;
307 -#endif
308                 bus->priv = priv;
309                 bus->read = bcm_enet_mdio_read_phylib;
310                 bus->write = bcm_enet_mdio_write_phylib;
311 @@ -1736,7 +1744,7 @@
312                 bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
313                 if (!bus->irq) {
314                         ret = -ENOMEM;
315 -                       goto err;
316 +                       goto out_free_mdio;
317                 }
318  
319                 if (priv->has_phy_interrupt)
320 @@ -1747,9 +1755,8 @@
321                 ret = mdiobus_register(bus);
322                 if (ret) {
323                         dev_err(&pdev->dev, "unable to register mdio bus\n");
324 -                       goto err;
325 +                       goto out_free_mdio;
326                 }
327 -               mdio_registered = 1;
328         } else {
329  
330                 /* run platform code to initialize PHY device */
331 @@ -1757,7 +1764,7 @@
332                     pd->mii_config(dev, 1, bcm_enet_mdio_read_mii,
333                                    bcm_enet_mdio_write_mii)) {
334                         dev_err(&pdev->dev, "unable to configure mdio bus\n");
335 -                       goto err;
336 +                       goto out_uninit_hw;
337                 }
338         }
339  
340 @@ -1777,51 +1784,50 @@
341                 enet_writel(priv, 0, ENET_MIB_REG(i));
342  
343         /* register netdevice */
344 -       dev->open = bcm_enet_open;
345 -       dev->stop = bcm_enet_stop;
346 -       dev->hard_start_xmit = bcm_enet_start_xmit;
347 -       dev->get_stats = bcm_enet_get_stats;
348 -       dev->set_mac_address = bcm_enet_set_mac_address;
349 -       dev->set_multicast_list = bcm_enet_set_multicast_list;
350 +       dev->netdev_ops = &bcm_enet_ops;
351         netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
352 -       dev->do_ioctl = bcm_enet_ioctl;
353 -#ifdef CONFIG_NET_POLL_CONTROLLER
354 -       dev->poll_controller = bcm_enet_netpoll;
355 -#endif
356 -       dev->change_mtu = bcm_enet_change_mtu;
357  
358         SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops);
359 -       SET_NETDEV_DEV(dev, &pdev->dev);
360  
361         ret = register_netdev(dev);
362         if (ret)
363 -               goto err;
364 +               goto out_unregister_mdio;
365  
366 +       netif_carrier_off(dev);
367         platform_set_drvdata(pdev, dev);
368         priv->pdev = pdev;
369         priv->net_dev = dev;
370 +       SET_NETDEV_DEV(dev, &pdev->dev);
371  
372         return 0;
373  
374 -err:
375 -       if (mem_requested)
376 -               release_mem_region(res_mem->start, iomem_size);
377 -       if (mdio_registered)
378 -               mdiobus_unregister(&priv->mii_bus);
379 -       kfree(priv->mii_bus.irq);
380 -       if (priv->mac_clk) {
381 -               clk_disable(priv->mac_clk);
382 -               clk_put(priv->mac_clk);
383 +out_unregister_mdio:
384 +       if (priv->mii_bus) {
385 +               mdiobus_unregister(priv->mii_bus);
386 +               kfree(priv->mii_bus->irq);
387         }
388 +
389 +out_free_mdio:
390 +       if (priv->mii_bus)
391 +               mdiobus_free(priv->mii_bus);
392 +
393 +out_uninit_hw:
394 +       /* turn off mdc clock */
395 +       enet_writel(priv, 0, ENET_MIISC_REG);
396         if (priv->phy_clk) {
397                 clk_disable(priv->phy_clk);
398                 clk_put(priv->phy_clk);
399         }
400 -       if (priv->base) {
401 -               /* turn off mdc clock */
402 -               enet_writel(priv, 0, ENET_MIISC_REG);
403 -               iounmap(priv->base);
404 -       }
405 +
406 +out_put_clk_mac:
407 +       clk_disable(priv->mac_clk);
408 +       clk_put(priv->mac_clk);
409 +
410 +out_unmap:
411 +       iounmap(priv->base);
412 +
413 +out_release_mem:
414 +       release_mem_region(res_mem->start, iomem_size);
415  out:
416         free_netdev(dev);
417         return ret;
418 @@ -1846,8 +1852,9 @@
419         enet_writel(priv, 0, ENET_MIISC_REG);
420  
421         if (priv->has_phy) {
422 -               mdiobus_unregister(&priv->mii_bus);
423 -               kfree(priv->mii_bus.irq);
424 +               mdiobus_unregister(priv->mii_bus);
425 +               kfree(priv->mii_bus->irq);
426 +               mdiobus_free(priv->mii_bus);
427         } else {
428                 struct bcm63xx_enet_platform_data *pd;
429  
430 @@ -1870,7 +1877,6 @@
431         clk_disable(priv->mac_clk);
432         clk_put(priv->mac_clk);
433  
434 -       platform_set_drvdata(pdev, NULL);
435         free_netdev(dev);
436         return 0;
437  }
438 --- a/drivers/net/bcm63xx_enet.h        2009-06-07 11:25:51.000000000 +0200
439 +++ b/drivers/net/bcm63xx_enet.h        2009-08-05 10:02:28.000000000 +0200
440 @@ -258,7 +258,7 @@
441         int phy_interrupt;
442  
443         /* used when a phy is connected (phylib used) */
444 -       struct mii_bus mii_bus;
445 +       struct mii_bus *mii_bus;
446         struct phy_device *phydev;
447         int old_link;
448         int old_duplex;