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