diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sky2.c | 84 |
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 */ | ||
485 | static 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 | |||
484 | static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | 492 | static 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 | ||
1016 | err_out: | 1024 | err_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) | |||
2389 | static int sky2_nway_reset(struct net_device *dev) | 2414 | static 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 | ||
2496 | static void sky2_set_multicast(struct net_device *dev) | 2515 | static 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 | } |