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.c81
1 files changed, 50 insertions, 31 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 00d683063c01..b538e3038058 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -25,6 +25,7 @@
25 */ 25 */
26 26
27#include <linux/config.h> 27#include <linux/config.h>
28#include <linux/in.h>
28#include <linux/kernel.h> 29#include <linux/kernel.h>
29#include <linux/module.h> 30#include <linux/module.h>
30#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
@@ -43,7 +44,7 @@
43#include "skge.h" 44#include "skge.h"
44 45
45#define DRV_NAME "skge" 46#define DRV_NAME "skge"
46#define DRV_VERSION "1.2" 47#define DRV_VERSION "1.3"
47#define PFX DRV_NAME " " 48#define PFX DRV_NAME " "
48 49
49#define DEFAULT_TX_RING_SIZE 128 50#define DEFAULT_TX_RING_SIZE 128
@@ -88,15 +89,14 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
88 89
89static int skge_up(struct net_device *dev); 90static int skge_up(struct net_device *dev);
90static int skge_down(struct net_device *dev); 91static int skge_down(struct net_device *dev);
92static void skge_phy_reset(struct skge_port *skge);
91static void skge_tx_clean(struct skge_port *skge); 93static void skge_tx_clean(struct skge_port *skge);
92static 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);
93static 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);
94static void genesis_get_stats(struct skge_port *skge, u64 *data); 96static void genesis_get_stats(struct skge_port *skge, u64 *data);
95static void yukon_get_stats(struct skge_port *skge, u64 *data); 97static void yukon_get_stats(struct skge_port *skge, u64 *data);
96static void yukon_init(struct skge_hw *hw, int port); 98static void yukon_init(struct skge_hw *hw, int port);
97static void yukon_reset(struct skge_hw *hw, int port);
98static void genesis_mac_init(struct skge_hw *hw, int port); 99static void genesis_mac_init(struct skge_hw *hw, int port);
99static void genesis_reset(struct skge_hw *hw, int port);
100static void genesis_link_up(struct skge_port *skge); 100static void genesis_link_up(struct skge_port *skge);
101 101
102/* Avoid conditionals by using array */ 102/* Avoid conditionals by using array */
@@ -276,10 +276,9 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
276 skge->autoneg = ecmd->autoneg; 276 skge->autoneg = ecmd->autoneg;
277 skge->advertising = ecmd->advertising; 277 skge->advertising = ecmd->advertising;
278 278
279 if (netif_running(dev)) { 279 if (netif_running(dev))
280 skge_down(dev); 280 skge_phy_reset(skge);
281 skge_up(dev); 281
282 }
283 return (0); 282 return (0);
284} 283}
285 284
@@ -399,6 +398,7 @@ static int skge_set_ring_param(struct net_device *dev,
399 struct ethtool_ringparam *p) 398 struct ethtool_ringparam *p)
400{ 399{
401 struct skge_port *skge = netdev_priv(dev); 400 struct skge_port *skge = netdev_priv(dev);
401 int err;
402 402
403 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 ||
404 p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE) 404 p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
@@ -409,7 +409,9 @@ static int skge_set_ring_param(struct net_device *dev,
409 409
410 if (netif_running(dev)) { 410 if (netif_running(dev)) {
411 skge_down(dev); 411 skge_down(dev);
412 skge_up(dev); 412 err = skge_up(dev);
413 if (err)
414 dev_close(dev);
413 } 415 }
414 416
415 return 0; 417 return 0;
@@ -430,21 +432,11 @@ static void skge_set_msglevel(struct net_device *netdev, u32 value)
430static int skge_nway_reset(struct net_device *dev) 432static int skge_nway_reset(struct net_device *dev)
431{ 433{
432 struct skge_port *skge = netdev_priv(dev); 434 struct skge_port *skge = netdev_priv(dev);
433 struct skge_hw *hw = skge->hw;
434 int port = skge->port;
435 435
436 if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev)) 436 if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev))
437 return -EINVAL; 437 return -EINVAL;
438 438
439 spin_lock_bh(&hw->phy_lock); 439 skge_phy_reset(skge);
440 if (hw->chip_id == CHIP_ID_GENESIS) {
441 genesis_reset(hw, port);
442 genesis_mac_init(hw, port);
443 } else {
444 yukon_reset(hw, port);
445 yukon_init(hw, port);
446 }
447 spin_unlock_bh(&hw->phy_lock);
448 return 0; 440 return 0;
449} 441}
450 442
@@ -516,10 +508,8 @@ static int skge_set_pauseparam(struct net_device *dev,
516 else 508 else
517 skge->flow_control = FLOW_MODE_NONE; 509 skge->flow_control = FLOW_MODE_NONE;
518 510
519 if (netif_running(dev)) { 511 if (netif_running(dev))
520 skge_down(dev); 512 skge_phy_reset(skge);
521 skge_up(dev);
522 }
523 return 0; 513 return 0;
524} 514}
525 515
@@ -2019,6 +2009,25 @@ static void yukon_phy_intr(struct skge_port *skge)
2019 /* XXX restart autonegotiation? */ 2009 /* XXX restart autonegotiation? */
2020} 2010}
2021 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
2022/* Basic MII support */ 2031/* Basic MII support */
2023static 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)
2024{ 2033{
@@ -2187,6 +2196,7 @@ static int skge_up(struct net_device *dev)
2187 kfree(skge->rx_ring.start); 2196 kfree(skge->rx_ring.start);
2188 free_pci_mem: 2197 free_pci_mem:
2189 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;
2190 2200
2191 return err; 2201 return err;
2192} 2202}
@@ -2197,6 +2207,9 @@ static int skge_down(struct net_device *dev)
2197 struct skge_hw *hw = skge->hw; 2207 struct skge_hw *hw = skge->hw;
2198 int port = skge->port; 2208 int port = skge->port;
2199 2209
2210 if (skge->mem == NULL)
2211 return 0;
2212
2200 if (netif_msg_ifdown(skge)) 2213 if (netif_msg_ifdown(skge))
2201 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); 2214 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
2202 2215
@@ -2253,6 +2266,7 @@ static int skge_down(struct net_device *dev)
2253 kfree(skge->rx_ring.start); 2266 kfree(skge->rx_ring.start);
2254 kfree(skge->tx_ring.start); 2267 kfree(skge->tx_ring.start);
2255 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;
2256 return 0; 2270 return 0;
2257} 2271}
2258 2272
@@ -2413,18 +2427,23 @@ static void skge_tx_timeout(struct net_device *dev)
2413 2427
2414static int skge_change_mtu(struct net_device *dev, int new_mtu) 2428static int skge_change_mtu(struct net_device *dev, int new_mtu)
2415{ 2429{
2416 int err = 0; 2430 int err;
2417 int running = netif_running(dev);
2418 2431
2419 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) 2432 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
2420 return -EINVAL; 2433 return -EINVAL;
2421 2434
2435 if (!netif_running(dev)) {
2436 dev->mtu = new_mtu;
2437 return 0;
2438 }
2439
2440 skge_down(dev);
2422 2441
2423 if (running)
2424 skge_down(dev);
2425 dev->mtu = new_mtu; 2442 dev->mtu = new_mtu;
2426 if (running) 2443
2427 skge_up(dev); 2444 err = skge_up(dev);
2445 if (err)
2446 dev_close(dev);
2428 2447
2429 return err; 2448 return err;
2430} 2449}
@@ -3398,8 +3417,8 @@ static int skge_resume(struct pci_dev *pdev)
3398 struct net_device *dev = hw->dev[i]; 3417 struct net_device *dev = hw->dev[i];
3399 if (dev) { 3418 if (dev) {
3400 netif_device_attach(dev); 3419 netif_device_attach(dev);
3401 if (netif_running(dev)) 3420 if (netif_running(dev) && skge_up(dev))
3402 skge_up(dev); 3421 dev_close(dev);
3403 } 3422 }
3404 } 3423 }
3405 return 0; 3424 return 0;