aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c84
1 files changed, 52 insertions, 32 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7af72cdd473c..1d183d5177a1 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -481,6 +481,14 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
481 gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); 481 gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
482} 482}
483 483
484/* Force a renegotiation */
485static void sky2_phy_reinit(struct sky2_port *sky2)
486{
487 down(&sky2->phy_sema);
488 sky2_phy_init(sky2->hw, sky2->port);
489 up(&sky2->phy_sema);
490}
491
484static void sky2_mac_init(struct sky2_hw *hw, unsigned port) 492static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
485{ 493{
486 struct sky2_port *sky2 = netdev_priv(hw->dev[port]); 494 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
@@ -1014,18 +1022,22 @@ static int sky2_up(struct net_device *dev)
1014 return 0; 1022 return 0;
1015 1023
1016err_out: 1024err_out:
1017 if (sky2->rx_le) 1025 if (sky2->rx_le) {
1018 pci_free_consistent(hw->pdev, RX_LE_BYTES, 1026 pci_free_consistent(hw->pdev, RX_LE_BYTES,
1019 sky2->rx_le, sky2->rx_le_map); 1027 sky2->rx_le, sky2->rx_le_map);
1020 if (sky2->tx_le) 1028 sky2->rx_le = NULL;
1029 }
1030 if (sky2->tx_le) {
1021 pci_free_consistent(hw->pdev, 1031 pci_free_consistent(hw->pdev,
1022 TX_RING_SIZE * sizeof(struct sky2_tx_le), 1032 TX_RING_SIZE * sizeof(struct sky2_tx_le),
1023 sky2->tx_le, sky2->tx_le_map); 1033 sky2->tx_le, sky2->tx_le_map);
1024 if (sky2->tx_ring) 1034 sky2->tx_le = NULL;
1025 kfree(sky2->tx_ring); 1035 }
1026 if (sky2->rx_ring) 1036 kfree(sky2->tx_ring);
1027 kfree(sky2->rx_ring); 1037 kfree(sky2->rx_ring);
1028 1038
1039 sky2->tx_ring = NULL;
1040 sky2->rx_ring = NULL;
1029 return err; 1041 return err;
1030} 1042}
1031 1043
@@ -1291,6 +1303,10 @@ static int sky2_down(struct net_device *dev)
1291 unsigned port = sky2->port; 1303 unsigned port = sky2->port;
1292 u16 ctrl; 1304 u16 ctrl;
1293 1305
1306 /* Never really got started! */
1307 if (!sky2->tx_le)
1308 return 0;
1309
1294 if (netif_msg_ifdown(sky2)) 1310 if (netif_msg_ifdown(sky2))
1295 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); 1311 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
1296 1312
@@ -1365,6 +1381,12 @@ static int sky2_down(struct net_device *dev)
1365 sky2->tx_le, sky2->tx_le_map); 1381 sky2->tx_le, sky2->tx_le_map);
1366 kfree(sky2->tx_ring); 1382 kfree(sky2->tx_ring);
1367 1383
1384 sky2->tx_le = NULL;
1385 sky2->rx_le = NULL;
1386
1387 sky2->rx_ring = NULL;
1388 sky2->tx_ring = NULL;
1389
1368 return 0; 1390 return 0;
1369} 1391}
1370 1392
@@ -1636,12 +1658,17 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1636 sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); 1658 sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
1637 1659
1638 err = sky2_rx_start(sky2); 1660 err = sky2_rx_start(sky2);
1639 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
1640
1641 netif_poll_disable(hw->dev[0]);
1642 netif_wake_queue(dev);
1643 sky2_write32(hw, B0_IMSK, hw->intr_mask); 1661 sky2_write32(hw, B0_IMSK, hw->intr_mask);
1644 1662
1663 if (err)
1664 dev_close(dev);
1665 else {
1666 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
1667
1668 netif_poll_enable(hw->dev[0]);
1669 netif_wake_queue(dev);
1670 }
1671
1645 return err; 1672 return err;
1646} 1673}
1647 1674
@@ -2315,10 +2342,8 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
2315 sky2->autoneg = ecmd->autoneg; 2342 sky2->autoneg = ecmd->autoneg;
2316 sky2->advertising = ecmd->advertising; 2343 sky2->advertising = ecmd->advertising;
2317 2344
2318 if (netif_running(dev)) { 2345 if (netif_running(dev))
2319 sky2_down(dev); 2346 sky2_phy_reinit(sky2);
2320 sky2_up(dev);
2321 }
2322 2347
2323 return 0; 2348 return 0;
2324} 2349}
@@ -2389,17 +2414,11 @@ static u32 sky2_get_msglevel(struct net_device *netdev)
2389static int sky2_nway_reset(struct net_device *dev) 2414static int sky2_nway_reset(struct net_device *dev)
2390{ 2415{
2391 struct sky2_port *sky2 = netdev_priv(dev); 2416 struct sky2_port *sky2 = netdev_priv(dev);
2392 struct sky2_hw *hw = sky2->hw;
2393 2417
2394 if (sky2->autoneg != AUTONEG_ENABLE) 2418 if (sky2->autoneg != AUTONEG_ENABLE)
2395 return -EINVAL; 2419 return -EINVAL;
2396 2420
2397 netif_stop_queue(dev); 2421 sky2_phy_reinit(sky2);
2398
2399 down(&sky2->phy_sema);
2400 sky2_phy_reset(hw, sky2->port);
2401 sky2_phy_init(hw, sky2->port);
2402 up(&sky2->phy_sema);
2403 2422
2404 return 0; 2423 return 0;
2405} 2424}
@@ -2477,20 +2496,20 @@ static int sky2_set_mac_address(struct net_device *dev, void *p)
2477{ 2496{
2478 struct sky2_port *sky2 = netdev_priv(dev); 2497 struct sky2_port *sky2 = netdev_priv(dev);
2479 struct sockaddr *addr = p; 2498 struct sockaddr *addr = p;
2480 int err = 0;
2481 2499
2482 if (!is_valid_ether_addr(addr->sa_data)) 2500 if (!is_valid_ether_addr(addr->sa_data))
2483 return -EADDRNOTAVAIL; 2501 return -EADDRNOTAVAIL;
2484 2502
2485 sky2_down(dev);
2486 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 2503 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
2487 memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8, 2504 memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8,
2488 dev->dev_addr, ETH_ALEN); 2505 dev->dev_addr, ETH_ALEN);
2489 memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8, 2506 memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8,
2490 dev->dev_addr, ETH_ALEN); 2507 dev->dev_addr, ETH_ALEN);
2491 if (dev->flags & IFF_UP) 2508
2492 err = sky2_up(dev); 2509 if (netif_running(dev))
2493 return err; 2510 sky2_phy_reinit(sky2);
2511
2512 return 0;
2494} 2513}
2495 2514
2496static void sky2_set_multicast(struct net_device *dev) 2515static void sky2_set_multicast(struct net_device *dev)
@@ -2648,10 +2667,7 @@ static int sky2_set_pauseparam(struct net_device *dev,
2648 sky2->tx_pause = ecmd->tx_pause != 0; 2667 sky2->tx_pause = ecmd->tx_pause != 0;
2649 sky2->rx_pause = ecmd->rx_pause != 0; 2668 sky2->rx_pause = ecmd->rx_pause != 0;
2650 2669
2651 if (netif_running(dev)) { 2670 sky2_phy_reinit(sky2);
2652 sky2_down(dev);
2653 err = sky2_up(dev);
2654 }
2655 2671
2656 return err; 2672 return err;
2657} 2673}
@@ -2813,8 +2829,11 @@ static int sky2_set_ringparam(struct net_device *dev,
2813 sky2->rx_pending = ering->rx_pending; 2829 sky2->rx_pending = ering->rx_pending;
2814 sky2->tx_pending = ering->tx_pending; 2830 sky2->tx_pending = ering->tx_pending;
2815 2831
2816 if (netif_running(dev)) 2832 if (netif_running(dev)) {
2817 err = sky2_up(dev); 2833 err = sky2_up(dev);
2834 if (err)
2835 dev_close(dev);
2836 }
2818 2837
2819 return err; 2838 return err;
2820} 2839}
@@ -3195,7 +3214,8 @@ static int sky2_resume(struct pci_dev *pdev)
3195 if (dev) { 3214 if (dev) {
3196 if (netif_running(dev)) { 3215 if (netif_running(dev)) {
3197 netif_device_attach(dev); 3216 netif_device_attach(dev);
3198 sky2_up(dev); 3217 if (sky2_up(dev))
3218 dev_close(dev);
3199 } 3219 }
3200 } 3220 }
3201 } 3221 }