diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-04 19:31:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-04 19:31:56 -0500 |
commit | d779188d2baf436e67fe8816fca2ef53d246900f (patch) | |
tree | 9bac75842a5611172860feec3c4019ff874a2b89 /drivers/net/skge.c | |
parent | f61ea1b0c825a20a1826bb43a226387091934586 (diff) | |
parent | ac67c6247361b3b8644b34e5301a46d5069c1373 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index d8cc3aea032a..b538e3038058 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include "skge.h" | 44 | #include "skge.h" |
45 | 45 | ||
46 | #define DRV_NAME "skge" | 46 | #define DRV_NAME "skge" |
47 | #define DRV_VERSION "1.2" | 47 | #define DRV_VERSION "1.3" |
48 | #define PFX DRV_NAME " " | 48 | #define PFX DRV_NAME " " |
49 | 49 | ||
50 | #define DEFAULT_TX_RING_SIZE 128 | 50 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -89,15 +89,14 @@ MODULE_DEVICE_TABLE(pci, skge_id_table); | |||
89 | 89 | ||
90 | static int skge_up(struct net_device *dev); | 90 | static int skge_up(struct net_device *dev); |
91 | static int skge_down(struct net_device *dev); | 91 | static int skge_down(struct net_device *dev); |
92 | static void skge_phy_reset(struct skge_port *skge); | ||
92 | static void skge_tx_clean(struct skge_port *skge); | 93 | static void skge_tx_clean(struct skge_port *skge); |
93 | static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 94 | static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
94 | static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 95 | static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
95 | static void genesis_get_stats(struct skge_port *skge, u64 *data); | 96 | static void genesis_get_stats(struct skge_port *skge, u64 *data); |
96 | static void yukon_get_stats(struct skge_port *skge, u64 *data); | 97 | static void yukon_get_stats(struct skge_port *skge, u64 *data); |
97 | static void yukon_init(struct skge_hw *hw, int port); | 98 | static void yukon_init(struct skge_hw *hw, int port); |
98 | static void yukon_reset(struct skge_hw *hw, int port); | ||
99 | static void genesis_mac_init(struct skge_hw *hw, int port); | 99 | static void genesis_mac_init(struct skge_hw *hw, int port); |
100 | static void genesis_reset(struct skge_hw *hw, int port); | ||
101 | static void genesis_link_up(struct skge_port *skge); | 100 | static void genesis_link_up(struct skge_port *skge); |
102 | 101 | ||
103 | /* Avoid conditionals by using array */ | 102 | /* Avoid conditionals by using array */ |
@@ -277,10 +276,9 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
277 | skge->autoneg = ecmd->autoneg; | 276 | skge->autoneg = ecmd->autoneg; |
278 | skge->advertising = ecmd->advertising; | 277 | skge->advertising = ecmd->advertising; |
279 | 278 | ||
280 | if (netif_running(dev)) { | 279 | if (netif_running(dev)) |
281 | skge_down(dev); | 280 | skge_phy_reset(skge); |
282 | skge_up(dev); | 281 | |
283 | } | ||
284 | return (0); | 282 | return (0); |
285 | } | 283 | } |
286 | 284 | ||
@@ -400,6 +398,7 @@ static int skge_set_ring_param(struct net_device *dev, | |||
400 | struct ethtool_ringparam *p) | 398 | struct ethtool_ringparam *p) |
401 | { | 399 | { |
402 | struct skge_port *skge = netdev_priv(dev); | 400 | struct skge_port *skge = netdev_priv(dev); |
401 | int err; | ||
403 | 402 | ||
404 | if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE || | 403 | if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE || |
405 | p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE) | 404 | p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE) |
@@ -410,7 +409,9 @@ static int skge_set_ring_param(struct net_device *dev, | |||
410 | 409 | ||
411 | if (netif_running(dev)) { | 410 | if (netif_running(dev)) { |
412 | skge_down(dev); | 411 | skge_down(dev); |
413 | skge_up(dev); | 412 | err = skge_up(dev); |
413 | if (err) | ||
414 | dev_close(dev); | ||
414 | } | 415 | } |
415 | 416 | ||
416 | return 0; | 417 | return 0; |
@@ -431,21 +432,11 @@ static void skge_set_msglevel(struct net_device *netdev, u32 value) | |||
431 | static int skge_nway_reset(struct net_device *dev) | 432 | static int skge_nway_reset(struct net_device *dev) |
432 | { | 433 | { |
433 | struct skge_port *skge = netdev_priv(dev); | 434 | struct skge_port *skge = netdev_priv(dev); |
434 | struct skge_hw *hw = skge->hw; | ||
435 | int port = skge->port; | ||
436 | 435 | ||
437 | if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev)) | 436 | if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev)) |
438 | return -EINVAL; | 437 | return -EINVAL; |
439 | 438 | ||
440 | spin_lock_bh(&hw->phy_lock); | 439 | skge_phy_reset(skge); |
441 | if (hw->chip_id == CHIP_ID_GENESIS) { | ||
442 | genesis_reset(hw, port); | ||
443 | genesis_mac_init(hw, port); | ||
444 | } else { | ||
445 | yukon_reset(hw, port); | ||
446 | yukon_init(hw, port); | ||
447 | } | ||
448 | spin_unlock_bh(&hw->phy_lock); | ||
449 | return 0; | 440 | return 0; |
450 | } | 441 | } |
451 | 442 | ||
@@ -517,10 +508,8 @@ static int skge_set_pauseparam(struct net_device *dev, | |||
517 | else | 508 | else |
518 | skge->flow_control = FLOW_MODE_NONE; | 509 | skge->flow_control = FLOW_MODE_NONE; |
519 | 510 | ||
520 | if (netif_running(dev)) { | 511 | if (netif_running(dev)) |
521 | skge_down(dev); | 512 | skge_phy_reset(skge); |
522 | skge_up(dev); | ||
523 | } | ||
524 | return 0; | 513 | return 0; |
525 | } | 514 | } |
526 | 515 | ||
@@ -2020,6 +2009,25 @@ static void yukon_phy_intr(struct skge_port *skge) | |||
2020 | /* XXX restart autonegotiation? */ | 2009 | /* XXX restart autonegotiation? */ |
2021 | } | 2010 | } |
2022 | 2011 | ||
2012 | static void skge_phy_reset(struct skge_port *skge) | ||
2013 | { | ||
2014 | struct skge_hw *hw = skge->hw; | ||
2015 | int port = skge->port; | ||
2016 | |||
2017 | netif_stop_queue(skge->netdev); | ||
2018 | netif_carrier_off(skge->netdev); | ||
2019 | |||
2020 | spin_lock_bh(&hw->phy_lock); | ||
2021 | if (hw->chip_id == CHIP_ID_GENESIS) { | ||
2022 | genesis_reset(hw, port); | ||
2023 | genesis_mac_init(hw, port); | ||
2024 | } else { | ||
2025 | yukon_reset(hw, port); | ||
2026 | yukon_init(hw, port); | ||
2027 | } | ||
2028 | spin_unlock_bh(&hw->phy_lock); | ||
2029 | } | ||
2030 | |||
2023 | /* Basic MII support */ | 2031 | /* Basic MII support */ |
2024 | static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 2032 | static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
2025 | { | 2033 | { |
@@ -2188,6 +2196,7 @@ static int skge_up(struct net_device *dev) | |||
2188 | kfree(skge->rx_ring.start); | 2196 | kfree(skge->rx_ring.start); |
2189 | free_pci_mem: | 2197 | free_pci_mem: |
2190 | pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma); | 2198 | pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma); |
2199 | skge->mem = NULL; | ||
2191 | 2200 | ||
2192 | return err; | 2201 | return err; |
2193 | } | 2202 | } |
@@ -2198,6 +2207,9 @@ static int skge_down(struct net_device *dev) | |||
2198 | struct skge_hw *hw = skge->hw; | 2207 | struct skge_hw *hw = skge->hw; |
2199 | int port = skge->port; | 2208 | int port = skge->port; |
2200 | 2209 | ||
2210 | if (skge->mem == NULL) | ||
2211 | return 0; | ||
2212 | |||
2201 | if (netif_msg_ifdown(skge)) | 2213 | if (netif_msg_ifdown(skge)) |
2202 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 2214 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
2203 | 2215 | ||
@@ -2254,6 +2266,7 @@ static int skge_down(struct net_device *dev) | |||
2254 | kfree(skge->rx_ring.start); | 2266 | kfree(skge->rx_ring.start); |
2255 | kfree(skge->tx_ring.start); | 2267 | kfree(skge->tx_ring.start); |
2256 | pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma); | 2268 | pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma); |
2269 | skge->mem = NULL; | ||
2257 | return 0; | 2270 | return 0; |
2258 | } | 2271 | } |
2259 | 2272 | ||
@@ -2414,18 +2427,23 @@ static void skge_tx_timeout(struct net_device *dev) | |||
2414 | 2427 | ||
2415 | static int skge_change_mtu(struct net_device *dev, int new_mtu) | 2428 | static int skge_change_mtu(struct net_device *dev, int new_mtu) |
2416 | { | 2429 | { |
2417 | int err = 0; | 2430 | int err; |
2418 | int running = netif_running(dev); | ||
2419 | 2431 | ||
2420 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 2432 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
2421 | return -EINVAL; | 2433 | return -EINVAL; |
2422 | 2434 | ||
2435 | if (!netif_running(dev)) { | ||
2436 | dev->mtu = new_mtu; | ||
2437 | return 0; | ||
2438 | } | ||
2439 | |||
2440 | skge_down(dev); | ||
2423 | 2441 | ||
2424 | if (running) | ||
2425 | skge_down(dev); | ||
2426 | dev->mtu = new_mtu; | 2442 | dev->mtu = new_mtu; |
2427 | if (running) | 2443 | |
2428 | skge_up(dev); | 2444 | err = skge_up(dev); |
2445 | if (err) | ||
2446 | dev_close(dev); | ||
2429 | 2447 | ||
2430 | return err; | 2448 | return err; |
2431 | } | 2449 | } |
@@ -3399,8 +3417,8 @@ static int skge_resume(struct pci_dev *pdev) | |||
3399 | struct net_device *dev = hw->dev[i]; | 3417 | struct net_device *dev = hw->dev[i]; |
3400 | if (dev) { | 3418 | if (dev) { |
3401 | netif_device_attach(dev); | 3419 | netif_device_attach(dev); |
3402 | if (netif_running(dev)) | 3420 | if (netif_running(dev) && skge_up(dev)) |
3403 | skge_up(dev); | 3421 | dev_close(dev); |
3404 | } | 3422 | } |
3405 | } | 3423 | } |
3406 | return 0; | 3424 | return 0; |