--- a/drivers/net/bcm63xx_enet.c 2009-07-31 22:06:20.000000000 +0200 +++ b/drivers/net/bcm63xx_enet.c 2009-08-05 10:02:28.000000000 +0200 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "bcm63xx_enet.h" @@ -91,7 +90,7 @@ if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII) break; udelay(1); - } while (limit-- >= 0); + } while (limit-- > 0); return (limit < 0) ? 1 : 0; } @@ -321,7 +320,7 @@ if (len < copybreak) { struct sk_buff *nskb; - nskb = netdev_alloc_skb(dev, len + 2); + nskb = netdev_alloc_skb(dev, len + NET_IP_ALIGN); if (!nskb) { /* forget packet, just rearm desc */ priv->stats.rx_dropped++; @@ -452,11 +451,7 @@ /* no more packet in rx/tx queue, remove device from poll * queue */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) - netif_rx_complete(dev, napi); -#else napi_complete(napi); -#endif /* restore rx/tx interrupt */ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, @@ -508,11 +503,7 @@ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) - netif_rx_schedule(dev, &priv->napi); -#else napi_schedule(&priv->napi); -#endif return IRQ_HANDLED; } @@ -764,11 +755,11 @@ pr_info("%s: link %s", dev->name, phydev->link ? "UP" : "DOWN"); if (phydev->link) - printk(" - %d/%s - flow control %s", phydev->speed, + pr_cont(" - %d/%s - flow control %s", phydev->speed, DUPLEX_FULL == phydev->duplex ? "full" : "half", phydev->pause == 1 ? "rx&tx" : "off"); - printk("\n"); + pr_cont("\n"); } } @@ -782,6 +773,7 @@ priv = netdev_priv(dev); bcm_enet_set_duplex(priv, priv->force_duplex_full); bcm_enet_set_flow(priv, priv->pause_rx, priv->pause_tx); + netif_carrier_on(dev); pr_info("%s: link forced UP - %d/%s - flow control %s/%s\n", dev->name, @@ -800,21 +792,18 @@ struct sockaddr addr; struct device *kdev; struct phy_device *phydev; - int irq_requested, i, ret; + int i, ret; unsigned int size; - char phy_id[BUS_ID_SIZE]; + char phy_id[MII_BUS_ID_SIZE + 3]; void *p; u32 val; priv = netdev_priv(dev); - priv->rx_desc_cpu = priv->tx_desc_cpu = NULL; - priv->rx_skb = priv->tx_skb = NULL; - kdev = &priv->pdev->dev; if (priv->has_phy) { /* connect to PHY */ - snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->mac_id ? "1" : "0", priv->phy_id); phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0, @@ -854,23 +843,19 @@ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); - irq_requested = 0; ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); if (ret) - goto out; - irq_requested++; + goto out_phy_disconnect; ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev); if (ret) - goto out; - irq_requested++; + goto out_freeirq; ret = request_irq(priv->irq_tx, bcm_enet_isr_dma, IRQF_DISABLED, dev->name, dev); if (ret) - goto out; - irq_requested++; + goto out_freeirq_rx; /* initialize perfect match registers */ for (i = 0; i < 4; i++) { @@ -888,7 +873,7 @@ if (!p) { dev_err(kdev, "cannot allocate rx ring %u\n", size); ret = -ENOMEM; - goto out; + goto out_freeirq_tx; } memset(p, 0, size); @@ -901,7 +886,7 @@ if (!p) { dev_err(kdev, "cannot allocate tx ring\n"); ret = -ENOMEM; - goto out; + goto out_free_rx_ring; } memset(p, 0, size); @@ -913,7 +898,7 @@ if (!priv->tx_skb) { dev_err(kdev, "cannot allocate rx skb queue\n"); ret = -ENOMEM; - goto out; + goto out_free_tx_ring; } priv->tx_desc_count = priv->tx_ring_size; @@ -927,7 +912,7 @@ if (!priv->rx_skb) { dev_err(kdev, "cannot allocate rx skb queue\n"); ret = -ENOMEM; - goto out; + goto out_free_tx_skb; } priv->rx_desc_count = 0; @@ -1012,13 +997,6 @@ return 0; out: - phy_disconnect(priv->phydev); - if (irq_requested > 2) - free_irq(priv->irq_tx, dev); - if (irq_requested > 1) - free_irq(priv->irq_rx, dev); - if (irq_requested > 0) - free_irq(dev->irq, dev); for (i = 0; i < priv->rx_ring_size; i++) { struct bcm_enet_desc *desc; @@ -1030,14 +1008,31 @@ DMA_FROM_DEVICE); kfree_skb(priv->rx_skb[i]); } - if (priv->rx_desc_cpu) - dma_free_coherent(kdev, priv->rx_desc_alloc_size, - priv->rx_desc_cpu, priv->rx_desc_dma); - if (priv->tx_desc_cpu) - dma_free_coherent(kdev, priv->tx_desc_alloc_size, - priv->tx_desc_cpu, priv->tx_desc_dma); kfree(priv->rx_skb); + +out_free_tx_skb: kfree(priv->tx_skb); + +out_free_tx_ring: + dma_free_coherent(kdev, priv->tx_desc_alloc_size, + priv->tx_desc_cpu, priv->tx_desc_dma); + +out_free_rx_ring: + dma_free_coherent(kdev, priv->rx_desc_alloc_size, + priv->rx_desc_cpu, priv->rx_desc_dma); + +out_freeirq_tx: + free_irq(priv->irq_tx, dev); + +out_freeirq_rx: + free_irq(priv->irq_rx, dev); + +out_freeirq: + free_irq(dev->irq, dev); + +out_phy_disconnect: + phy_disconnect(priv->phydev); + return ret; } @@ -1606,6 +1601,20 @@ enet_writel(priv, val, ENET_MIBCTL_REG); } +static const struct net_device_ops bcm_enet_ops = { + .ndo_open = bcm_enet_open, + .ndo_stop = bcm_enet_stop, + .ndo_start_xmit = bcm_enet_start_xmit, + .ndo_get_stats = bcm_enet_get_stats, + .ndo_set_mac_address = bcm_enet_set_mac_address, + .ndo_set_multicast_list = bcm_enet_set_multicast_list, + .ndo_do_ioctl = bcm_enet_ioctl, + .ndo_change_mtu = bcm_enet_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = bcm_enet_netpoll, +#endif +}; + /* * allocate netdevice, request register memory and register device. */ @@ -1618,15 +1627,13 @@ struct mii_bus *bus; const char *clk_name; unsigned int iomem_size; - int i, ret, mdio_registered, mem_requested; + int i, ret; /* stop if shared driver failed, assume driver->probe will be * called in the same order we register devices (correct ?) */ if (!bcm_enet_shared_base) return -ENODEV; - mdio_registered = mem_requested = 0; - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1); @@ -1648,14 +1655,13 @@ iomem_size = res_mem->end - res_mem->start + 1; if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) { ret = -EBUSY; - goto err; + goto out; } - mem_requested = 1; priv->base = ioremap(res_mem->start, iomem_size); if (priv->base == NULL) { ret = -ENOMEM; - goto err; + goto out_release_mem; } dev->irq = priv->irq = res_irq->start; priv->irq_rx = res_irq_rx->start; @@ -1676,8 +1682,7 @@ priv->mac_clk = clk_get(&pdev->dev, clk_name); if (IS_ERR(priv->mac_clk)) { ret = PTR_ERR(priv->mac_clk); - priv->mac_clk = NULL; - goto err; + goto out_unmap; } clk_enable(priv->mac_clk); @@ -1706,7 +1711,7 @@ if (IS_ERR(priv->phy_clk)) { ret = PTR_ERR(priv->phy_clk); priv->phy_clk = NULL; - goto err; + goto out_put_clk_mac; } clk_enable(priv->phy_clk); } @@ -1716,13 +1721,16 @@ /* MII bus registration */ if (priv->has_phy) { - bus = &priv->mii_bus; + + priv->mii_bus = mdiobus_alloc(); + if (!priv->mii_bus) { + ret = -ENOMEM; + goto out_uninit_hw; + } + + bus = priv->mii_bus; bus->name = "bcm63xx_enet MII bus"; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) - bus->dev = &pdev->dev; -#else bus->parent = &pdev->dev; -#endif bus->priv = priv; bus->read = bcm_enet_mdio_read_phylib; bus->write = bcm_enet_mdio_write_phylib; @@ -1736,7 +1744,7 @@ bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); if (!bus->irq) { ret = -ENOMEM; - goto err; + goto out_free_mdio; } if (priv->has_phy_interrupt) @@ -1747,9 +1755,8 @@ ret = mdiobus_register(bus); if (ret) { dev_err(&pdev->dev, "unable to register mdio bus\n"); - goto err; + goto out_free_mdio; } - mdio_registered = 1; } else { /* run platform code to initialize PHY device */ @@ -1757,7 +1764,7 @@ pd->mii_config(dev, 1, bcm_enet_mdio_read_mii, bcm_enet_mdio_write_mii)) { dev_err(&pdev->dev, "unable to configure mdio bus\n"); - goto err; + goto out_uninit_hw; } } @@ -1777,51 +1784,50 @@ enet_writel(priv, 0, ENET_MIB_REG(i)); /* register netdevice */ - dev->open = bcm_enet_open; - dev->stop = bcm_enet_stop; - dev->hard_start_xmit = bcm_enet_start_xmit; - dev->get_stats = bcm_enet_get_stats; - dev->set_mac_address = bcm_enet_set_mac_address; - dev->set_multicast_list = bcm_enet_set_multicast_list; + dev->netdev_ops = &bcm_enet_ops; netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16); - dev->do_ioctl = bcm_enet_ioctl; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = bcm_enet_netpoll; -#endif - dev->change_mtu = bcm_enet_change_mtu; SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops); - SET_NETDEV_DEV(dev, &pdev->dev); ret = register_netdev(dev); if (ret) - goto err; + goto out_unregister_mdio; + netif_carrier_off(dev); platform_set_drvdata(pdev, dev); priv->pdev = pdev; priv->net_dev = dev; + SET_NETDEV_DEV(dev, &pdev->dev); return 0; -err: - if (mem_requested) - release_mem_region(res_mem->start, iomem_size); - if (mdio_registered) - mdiobus_unregister(&priv->mii_bus); - kfree(priv->mii_bus.irq); - if (priv->mac_clk) { - clk_disable(priv->mac_clk); - clk_put(priv->mac_clk); +out_unregister_mdio: + if (priv->mii_bus) { + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); } + +out_free_mdio: + if (priv->mii_bus) + mdiobus_free(priv->mii_bus); + +out_uninit_hw: + /* turn off mdc clock */ + enet_writel(priv, 0, ENET_MIISC_REG); if (priv->phy_clk) { clk_disable(priv->phy_clk); clk_put(priv->phy_clk); } - if (priv->base) { - /* turn off mdc clock */ - enet_writel(priv, 0, ENET_MIISC_REG); - iounmap(priv->base); - } + +out_put_clk_mac: + clk_disable(priv->mac_clk); + clk_put(priv->mac_clk); + +out_unmap: + iounmap(priv->base); + +out_release_mem: + release_mem_region(res_mem->start, iomem_size); out: free_netdev(dev); return ret; @@ -1846,8 +1852,9 @@ enet_writel(priv, 0, ENET_MIISC_REG); if (priv->has_phy) { - mdiobus_unregister(&priv->mii_bus); - kfree(priv->mii_bus.irq); + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); + mdiobus_free(priv->mii_bus); } else { struct bcm63xx_enet_platform_data *pd; @@ -1870,7 +1877,6 @@ clk_disable(priv->mac_clk); clk_put(priv->mac_clk); - platform_set_drvdata(pdev, NULL); free_netdev(dev); return 0; } --- a/drivers/net/bcm63xx_enet.h 2009-06-07 11:25:51.000000000 +0200 +++ b/drivers/net/bcm63xx_enet.h 2009-08-05 10:02:28.000000000 +0200 @@ -258,7 +258,7 @@ int phy_interrupt; /* used when a phy is connected (phylib used) */ - struct mii_bus mii_bus; + struct mii_bus *mii_bus; struct phy_device *phydev; int old_link; int old_duplex;