aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/arm/ixp4xx_eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/arm/ixp4xx_eth.c')
-rw-r--r--drivers/net/arm/ixp4xx_eth.c56
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
1230err_unreg: 1229err_phy_dis:
1231 unregister_netdev(dev); 1230 phy_disconnect(port->phydev);
1231err_free_mem:
1232 npe_port_tab[NPE_ID(port->id)] = NULL;
1233 platform_set_drvdata(pdev, NULL);
1234 release_resource(port->mem_res);
1232err_npe_rel: 1235err_npe_rel:
1233 npe_release(port->npe); 1236 npe_release(port->npe);
1234err_free: 1237err_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);