diff options
Diffstat (limited to 'drivers/net/arm/ixp4xx_eth.c')
-rw-r--r-- | drivers/net/arm/ixp4xx_eth.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 448487e22fa3..672c9626b9ca 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c | |||
@@ -338,12 +338,12 @@ static int ixp4xx_mdio_register(void) | |||
338 | if (cpu_is_ixp43x()) { | 338 | if (cpu_is_ixp43x()) { |
339 | /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ | 339 | /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ |
340 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) | 340 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) |
341 | return -ENOSYS; | 341 | return -ENODEV; |
342 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; | 342 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; |
343 | } else { | 343 | } else { |
344 | /* All MII PHY accesses use NPE-B Ethernet registers */ | 344 | /* All MII PHY accesses use NPE-B Ethernet registers */ |
345 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) | 345 | if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) |
346 | return -ENOSYS; | 346 | return -ENODEV; |
347 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; | 347 | mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; |
348 | } | 348 | } |
349 | 349 | ||
@@ -456,7 +456,8 @@ static inline void queue_put_desc(unsigned int queue, u32 phys, | |||
456 | debug_desc(phys, desc); | 456 | debug_desc(phys, desc); |
457 | BUG_ON(phys & 0x1F); | 457 | BUG_ON(phys & 0x1F); |
458 | qmgr_put_entry(queue, phys); | 458 | qmgr_put_entry(queue, phys); |
459 | BUG_ON(qmgr_stat_overflow(queue)); | 459 | /* Don't check for queue overflow here, we've allocated sufficient |
460 | length and queues >= 32 don't support this check anyway. */ | ||
460 | } | 461 | } |
461 | 462 | ||
462 | 463 | ||
@@ -512,8 +513,8 @@ static int eth_poll(struct napi_struct *napi, int budget) | |||
512 | #endif | 513 | #endif |
513 | napi_complete(napi); | 514 | napi_complete(napi); |
514 | qmgr_enable_irq(rxq); | 515 | qmgr_enable_irq(rxq); |
515 | if (!qmgr_stat_empty(rxq) && | 516 | if (!qmgr_stat_nearly_empty(rxq) && |
516 | napi_reschedule(napi)) { | 517 | napi_reschedule(napi)) { /* really empty in fact */ |
517 | #if DEBUG_RX | 518 | #if DEBUG_RX |
518 | printk(KERN_DEBUG "%s: eth_poll" | 519 | printk(KERN_DEBUG "%s: eth_poll" |
519 | " napi_reschedule successed\n", | 520 | " napi_reschedule successed\n", |
@@ -630,7 +631,8 @@ static void eth_txdone_irq(void *unused) | |||
630 | port->tx_buff_tab[n_desc] = NULL; | 631 | port->tx_buff_tab[n_desc] = NULL; |
631 | } | 632 | } |
632 | 633 | ||
633 | start = qmgr_stat_empty(port->plat->txreadyq); | 634 | /* really empty in fact */ |
635 | start = qmgr_stat_nearly_empty(port->plat->txreadyq); | ||
634 | queue_put_desc(port->plat->txreadyq, phys, desc); | 636 | queue_put_desc(port->plat->txreadyq, phys, desc); |
635 | if (start) { | 637 | if (start) { |
636 | #if DEBUG_TX | 638 | #if DEBUG_TX |
@@ -708,13 +710,14 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
708 | queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc); | 710 | queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc); |
709 | dev->trans_start = jiffies; | 711 | dev->trans_start = jiffies; |
710 | 712 | ||
711 | if (qmgr_stat_empty(txreadyq)) { | 713 | if (qmgr_stat_nearly_empty(txreadyq)) { /* really empty in fact */ |
712 | #if DEBUG_TX | 714 | #if DEBUG_TX |
713 | printk(KERN_DEBUG "%s: eth_xmit queue full\n", dev->name); | 715 | printk(KERN_DEBUG "%s: eth_xmit queue full\n", dev->name); |
714 | #endif | 716 | #endif |
715 | netif_stop_queue(dev); | 717 | netif_stop_queue(dev); |
716 | /* we could miss TX ready interrupt */ | 718 | /* we could miss TX ready interrupt */ |
717 | if (!qmgr_stat_empty(txreadyq)) { | 719 | /* really empty in fact */ |
720 | if (!qmgr_stat_nearly_empty(txreadyq)) { | ||
718 | #if DEBUG_TX | 721 | #if DEBUG_TX |
719 | printk(KERN_DEBUG "%s: eth_xmit ready again\n", | 722 | printk(KERN_DEBUG "%s: eth_xmit ready again\n", |
720 | dev->name); | 723 | dev->name); |
@@ -814,29 +817,29 @@ static int request_queues(struct port *port) | |||
814 | int err; | 817 | int err; |
815 | 818 | ||
816 | err = qmgr_request_queue(RXFREE_QUEUE(port->id), RX_DESCS, 0, 0, | 819 | err = qmgr_request_queue(RXFREE_QUEUE(port->id), RX_DESCS, 0, 0, |
817 | "%s:RX-free", port->netdev->name); | 820 | "%s:RX-free", port->netdev->name); |
818 | if (err) | 821 | if (err) |
819 | return err; | 822 | return err; |
820 | 823 | ||
821 | err = qmgr_request_queue(port->plat->rxq, RX_DESCS, 0, 0, | 824 | err = qmgr_request_queue(port->plat->rxq, RX_DESCS, 0, 0, |
822 | "%s:RX", port->netdev->name); | 825 | "%s:RX", port->netdev->name); |
823 | if (err) | 826 | if (err) |
824 | goto rel_rxfree; | 827 | goto rel_rxfree; |
825 | 828 | ||
826 | err = qmgr_request_queue(TX_QUEUE(port->id), TX_DESCS, 0, 0, | 829 | err = qmgr_request_queue(TX_QUEUE(port->id), TX_DESCS, 0, 0, |
827 | "%s:TX", port->netdev->name); | 830 | "%s:TX", port->netdev->name); |
828 | if (err) | 831 | if (err) |
829 | goto rel_rx; | 832 | goto rel_rx; |
830 | 833 | ||
831 | err = qmgr_request_queue(port->plat->txreadyq, TX_DESCS, 0, 0, | 834 | err = qmgr_request_queue(port->plat->txreadyq, TX_DESCS, 0, 0, |
832 | "%s:TX-ready", port->netdev->name); | 835 | "%s:TX-ready", port->netdev->name); |
833 | if (err) | 836 | if (err) |
834 | goto rel_tx; | 837 | goto rel_tx; |
835 | 838 | ||
836 | /* TX-done queue handles skbs sent out by the NPEs */ | 839 | /* TX-done queue handles skbs sent out by the NPEs */ |
837 | if (!ports_open) { | 840 | if (!ports_open) { |
838 | err = qmgr_request_queue(TXDONE_QUEUE, TXDONE_QUEUE_LEN, 0, 0, | 841 | err = qmgr_request_queue(TXDONE_QUEUE, TXDONE_QUEUE_LEN, 0, 0, |
839 | "%s:TX-done", DRV_NAME); | 842 | "%s:TX-done", DRV_NAME); |
840 | if (err) | 843 | if (err) |
841 | goto rel_txready; | 844 | goto rel_txready; |
842 | } | 845 | } |
@@ -1174,7 +1177,7 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1174 | regs_phys = IXP4XX_EthC_BASE_PHYS; | 1177 | regs_phys = IXP4XX_EthC_BASE_PHYS; |
1175 | break; | 1178 | break; |
1176 | default: | 1179 | default: |
1177 | err = -ENOSYS; | 1180 | err = -ENODEV; |
1178 | goto err_free; | 1181 | goto err_free; |
1179 | } | 1182 | } |
1180 | 1183 | ||
@@ -1189,15 +1192,10 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1189 | goto err_free; | 1192 | goto err_free; |
1190 | } | 1193 | } |
1191 | 1194 | ||
1192 | if (register_netdev(dev)) { | ||
1193 | err = -EIO; | ||
1194 | goto err_npe_rel; | ||
1195 | } | ||
1196 | |||
1197 | port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name); | 1195 | port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name); |
1198 | if (!port->mem_res) { | 1196 | if (!port->mem_res) { |
1199 | err = -EBUSY; | 1197 | err = -EBUSY; |
1200 | goto err_unreg; | 1198 | goto err_npe_rel; |
1201 | } | 1199 | } |
1202 | 1200 | ||
1203 | port->plat = plat; | 1201 | port->plat = plat; |
@@ -1215,20 +1213,25 @@ static int __devinit eth_init_one(struct platform_device *pdev) | |||
1215 | snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy); | 1213 | snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy); |
1216 | port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, | 1214 | port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, |
1217 | PHY_INTERFACE_MODE_MII); | 1215 | PHY_INTERFACE_MODE_MII); |
1218 | if (IS_ERR(port->phydev)) { | 1216 | if ((err = IS_ERR(port->phydev))) |
1219 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | 1217 | goto err_free_mem; |
1220 | return PTR_ERR(port->phydev); | ||
1221 | } | ||
1222 | 1218 | ||
1223 | port->phydev->irq = PHY_POLL; | 1219 | port->phydev->irq = PHY_POLL; |
1224 | 1220 | ||
1221 | if ((err = register_netdev(dev))) | ||
1222 | goto err_phy_dis; | ||
1223 | |||
1225 | printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, | 1224 | printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, |
1226 | npe_name(port->npe)); | 1225 | npe_name(port->npe)); |
1227 | 1226 | ||
1228 | return 0; | 1227 | return 0; |
1229 | 1228 | ||
1230 | err_unreg: | 1229 | err_phy_dis: |
1231 | unregister_netdev(dev); | 1230 | phy_disconnect(port->phydev); |
1231 | err_free_mem: | ||
1232 | npe_port_tab[NPE_ID(port->id)] = NULL; | ||
1233 | platform_set_drvdata(pdev, NULL); | ||
1234 | release_resource(port->mem_res); | ||
1232 | err_npe_rel: | 1235 | err_npe_rel: |
1233 | npe_release(port->npe); | 1236 | npe_release(port->npe); |
1234 | err_free: | 1237 | err_free: |
@@ -1242,6 +1245,7 @@ static int __devexit eth_remove_one(struct platform_device *pdev) | |||
1242 | struct port *port = netdev_priv(dev); | 1245 | struct port *port = netdev_priv(dev); |
1243 | 1246 | ||
1244 | unregister_netdev(dev); | 1247 | unregister_netdev(dev); |
1248 | phy_disconnect(port->phydev); | ||
1245 | npe_port_tab[NPE_ID(port->id)] = NULL; | 1249 | npe_port_tab[NPE_ID(port->id)] = NULL; |
1246 | platform_set_drvdata(pdev, NULL); | 1250 | platform_set_drvdata(pdev, NULL); |
1247 | npe_release(port->npe); | 1251 | npe_release(port->npe); |