aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/skge.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r--drivers/net/skge.c80
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
90static int skge_up(struct net_device *dev); 90static int skge_up(struct net_device *dev);
91static int skge_down(struct net_device *dev); 91static int skge_down(struct net_device *dev);
92static void skge_phy_reset(struct skge_port *skge);
92static void skge_tx_clean(struct skge_port *skge); 93static void skge_tx_clean(struct skge_port *skge);
93static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 94static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
94static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 95static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
95static void genesis_get_stats(struct skge_port *skge, u64 *data); 96static void genesis_get_stats(struct skge_port *skge, u64 *data);
96static void yukon_get_stats(struct skge_port *skge, u64 *data); 97static void yukon_get_stats(struct skge_port *skge, u64 *data);
97static void yukon_init(struct skge_hw *hw, int port); 98static void yukon_init(struct skge_hw *hw, int port);
98static void yukon_reset(struct skge_hw *hw, int port);
99static void genesis_mac_init(struct skge_hw *hw, int port); 99static void genesis_mac_init(struct skge_hw *hw, int port);
100static void genesis_reset(struct skge_hw *hw, int port);
101static void genesis_link_up(struct skge_port *skge); 100static 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)
431static int skge_nway_reset(struct net_device *dev) 432static 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
2012static 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 */
2024static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 2032static 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
2415static int skge_change_mtu(struct net_device *dev, int new_mtu) 2428static 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;