net: use netdev_mc_count and netdev_mc_empty when appropriate
[safe/jmp/linux-2.6] / drivers / net / arm / ixp4xx_eth.c
index 9cc4347..1a5f78b 100644 (file)
@@ -322,7 +322,7 @@ static int ixp4xx_mdio_write(struct mii_bus *bus, int phy_id, int location,
        ret = ixp4xx_mdio_cmd(bus, phy_id, location, 1, val);
        spin_unlock_irqrestore(&mdio_lock, flags);
 #if DEBUG_MDIO
-       printk(KERN_DEBUG "%s #%i: MII read [%i] <- 0x%X, err = %i\n",
+       printk(KERN_DEBUG "%s #%i: MII write [%i] <- 0x%X, err = %i\n",
               bus->name, phy_id, location, val, ret);
 #endif
        return ret;
@@ -338,12 +338,12 @@ static int ixp4xx_mdio_register(void)
        if (cpu_is_ixp43x()) {
                /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
                if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
-                       return -ENOSYS;
+                       return -ENODEV;
                mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
        } else {
                /* All MII PHY accesses use NPE-B Ethernet registers */
                if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
-                       return -ENOSYS;
+                       return -ENODEV;
                mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
        }
 
@@ -456,7 +456,8 @@ static inline void queue_put_desc(unsigned int queue, u32 phys,
        debug_desc(phys, desc);
        BUG_ON(phys & 0x1F);
        qmgr_put_entry(queue, phys);
-       BUG_ON(qmgr_stat_overflow(queue));
+       /* Don't check for queue overflow here, we've allocated sufficient
+          length and queues >= 32 don't support this check anyway. */
 }
 
 
@@ -482,7 +483,7 @@ static void eth_rx_irq(void *pdev)
        printk(KERN_DEBUG "%s: eth_rx_irq\n", dev->name);
 #endif
        qmgr_disable_irq(port->plat->rxq);
-       netif_rx_schedule(&port->napi);
+       napi_schedule(&port->napi);
 }
 
 static int eth_poll(struct napi_struct *napi, int budget)
@@ -507,16 +508,16 @@ static int eth_poll(struct napi_struct *napi, int budget)
 
                if ((n = queue_get_desc(rxq, port, 0)) < 0) {
 #if DEBUG_RX
-                       printk(KERN_DEBUG "%s: eth_poll netif_rx_complete\n",
+                       printk(KERN_DEBUG "%s: eth_poll napi_complete\n",
                               dev->name);
 #endif
-                       netif_rx_complete(napi);
+                       napi_complete(napi);
                        qmgr_enable_irq(rxq);
-                       if (!qmgr_stat_empty(rxq) &&
-                           netif_rx_reschedule(napi)) {
+                       if (!qmgr_stat_below_low_watermark(rxq) &&
+                           napi_reschedule(napi)) { /* not empty again */
 #if DEBUG_RX
                                printk(KERN_DEBUG "%s: eth_poll"
-                                      " netif_rx_reschedule successed\n",
+                                      " napi_reschedule successed\n",
                                       dev->name);
 #endif
                                qmgr_disable_irq(rxq);
@@ -561,8 +562,8 @@ static int eth_poll(struct napi_struct *napi, int budget)
                dma_unmap_single(&dev->dev, desc->data - NET_IP_ALIGN,
                                 RX_BUFF_SIZE, DMA_FROM_DEVICE);
 #else
-               dma_sync_single(&dev->dev, desc->data - NET_IP_ALIGN,
-                               RX_BUFF_SIZE, DMA_FROM_DEVICE);
+               dma_sync_single_for_cpu(&dev->dev, desc->data - NET_IP_ALIGN,
+                                       RX_BUFF_SIZE, DMA_FROM_DEVICE);
                memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
                              ALIGN(NET_IP_ALIGN + desc->pkt_len, 4) / 4);
 #endif
@@ -630,9 +631,9 @@ static void eth_txdone_irq(void *unused)
                        port->tx_buff_tab[n_desc] = NULL;
                }
 
-               start = qmgr_stat_empty(port->plat->txreadyq);
+               start = qmgr_stat_below_low_watermark(port->plat->txreadyq);
                queue_put_desc(port->plat->txreadyq, phys, desc);
-               if (start) {
+               if (start) { /* TX-ready queue was empty */
 #if DEBUG_TX
                        printk(KERN_DEBUG "%s: eth_txdone_irq xmit ready\n",
                               port->netdev->name);
@@ -708,13 +709,14 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
        queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc);
        dev->trans_start = jiffies;
 
-       if (qmgr_stat_empty(txreadyq)) {
+       if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */
 #if DEBUG_TX
                printk(KERN_DEBUG "%s: eth_xmit queue full\n", dev->name);
 #endif
                netif_stop_queue(dev);
                /* we could miss TX ready interrupt */
-               if (!qmgr_stat_empty(txreadyq)) {
+               /* really empty in fact */
+               if (!qmgr_stat_below_low_watermark(txreadyq)) {
 #if DEBUG_TX
                        printk(KERN_DEBUG "%s: eth_xmit ready again\n",
                               dev->name);
@@ -735,7 +737,7 @@ static void eth_set_mcast_list(struct net_device *dev)
        struct port *port = netdev_priv(dev);
        struct dev_mc_list *mclist = dev->mc_list;
        u8 diffs[ETH_ALEN], *addr;
-       int cnt = dev->mc_count, i;
+       int cnt = netdev_mc_count(dev), i;
 
        if ((dev->flags & IFF_PROMISC) || !mclist || !cnt) {
                __raw_writel(DEFAULT_RX_CNTRL0 & ~RX_CNTRL0_ADDR_FLTR_EN,
@@ -800,7 +802,7 @@ static int ixp4xx_nway_reset(struct net_device *dev)
        return phy_start_aneg(port->phydev);
 }
 
-static struct ethtool_ops ixp4xx_ethtool_ops = {
+static const struct ethtool_ops ixp4xx_ethtool_ops = {
        .get_drvinfo = ixp4xx_get_drvinfo,
        .get_settings = ixp4xx_get_settings,
        .set_settings = ixp4xx_set_settings,
@@ -814,29 +816,29 @@ static int request_queues(struct port *port)
        int err;
 
        err = qmgr_request_queue(RXFREE_QUEUE(port->id), RX_DESCS, 0, 0,
-                           "%s:RX-free", port->netdev->name);
+                                "%s:RX-free", port->netdev->name);
        if (err)
                return err;
 
        err = qmgr_request_queue(port->plat->rxq, RX_DESCS, 0, 0,
-                           "%s:RX", port->netdev->name);
+                                "%s:RX", port->netdev->name);
        if (err)
                goto rel_rxfree;
 
        err = qmgr_request_queue(TX_QUEUE(port->id), TX_DESCS, 0, 0,
-                           "%s:TX", port->netdev->name);
+                                "%s:TX", port->netdev->name);
        if (err)
                goto rel_rx;
 
        err = qmgr_request_queue(port->plat->txreadyq, TX_DESCS, 0, 0,
-                           "%s:TX-ready", port->netdev->name);
+                                "%s:TX-ready", port->netdev->name);
        if (err)
                goto rel_tx;
 
        /* TX-done queue handles skbs sent out by the NPEs */
        if (!ports_open) {
                err = qmgr_request_queue(TXDONE_QUEUE, TXDONE_QUEUE_LEN, 0, 0,
-                                   "%s:TX-done", DRV_NAME);
+                                        "%s:TX-done", DRV_NAME);
                if (err)
                        goto rel_txready;
        }
@@ -1045,7 +1047,7 @@ static int eth_open(struct net_device *dev)
        }
        ports_open++;
        /* we may already have RX data, enables IRQ */
-       netif_rx_schedule(&port->napi);
+       napi_schedule(&port->napi);
        return 0;
 }
 
@@ -1140,7 +1142,9 @@ static const struct net_device_ops ixp4xx_netdev_ops = {
        .ndo_start_xmit = eth_xmit,
        .ndo_set_multicast_list = eth_set_mcast_list,
        .ndo_do_ioctl = eth_ioctl,
-
+       .ndo_change_mtu = eth_change_mtu,
+       .ndo_set_mac_address = eth_mac_addr,
+       .ndo_validate_addr = eth_validate_addr,
 };
 
 static int __devinit eth_init_one(struct platform_device *pdev)
@@ -1149,7 +1153,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
        struct net_device *dev;
        struct eth_plat_info *plat = pdev->dev.platform_data;
        u32 regs_phys;
-       char phy_id[BUS_ID_SIZE];
+       char phy_id[MII_BUS_ID_SIZE + 3];
        int err;
 
        if (!(dev = alloc_etherdev(sizeof(struct port))))
@@ -1174,7 +1178,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
                regs_phys  = IXP4XX_EthC_BASE_PHYS;
                break;
        default:
-               err = -ENOSYS;
+               err = -ENODEV;
                goto err_free;
        }
 
@@ -1189,15 +1193,10 @@ static int __devinit eth_init_one(struct platform_device *pdev)
                goto err_free;
        }
 
-       if (register_netdev(dev)) {
-               err = -EIO;
-               goto err_npe_rel;
-       }
-
        port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name);
        if (!port->mem_res) {
                err = -EBUSY;
-               goto err_unreg;
+               goto err_npe_rel;
        }
 
        port->plat = plat;
@@ -1212,23 +1211,28 @@ static int __devinit eth_init_one(struct platform_device *pdev)
        __raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
        udelay(50);
 
-       snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
+       snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy);
        port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
                                   PHY_INTERFACE_MODE_MII);
-       if (IS_ERR(port->phydev)) {
-               printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
-               return PTR_ERR(port->phydev);
-       }
+       if ((err = IS_ERR(port->phydev)))
+               goto err_free_mem;
 
        port->phydev->irq = PHY_POLL;
 
+       if ((err = register_netdev(dev)))
+               goto err_phy_dis;
+
        printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy,
               npe_name(port->npe));
 
        return 0;
 
-err_unreg:
-       unregister_netdev(dev);
+err_phy_dis:
+       phy_disconnect(port->phydev);
+err_free_mem:
+       npe_port_tab[NPE_ID(port->id)] = NULL;
+       platform_set_drvdata(pdev, NULL);
+       release_resource(port->mem_res);
 err_npe_rel:
        npe_release(port->npe);
 err_free:
@@ -1242,6 +1246,7 @@ static int __devexit eth_remove_one(struct platform_device *pdev)
        struct port *port = netdev_priv(dev);
 
        unregister_netdev(dev);
+       phy_disconnect(port->phydev);
        npe_port_tab[NPE_ID(port->id)] = NULL;
        platform_set_drvdata(pdev, NULL);
        npe_release(port->npe);