Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / net / ixgb / ixgb_ethtool.c
index e3ba141..d38ade5 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   This program is free software; you can redistribute it and/or modify it 
   under the terms of the GNU General Public License as published by the Free 
@@ -63,6 +63,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
        {"tx_dropped", IXGB_STAT(net_stats.tx_dropped)},
        {"multicast", IXGB_STAT(net_stats.multicast)},
        {"collisions", IXGB_STAT(net_stats.collisions)},
+
 /*     { "rx_length_errors", IXGB_STAT(net_stats.rx_length_errors) },  */
        {"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)},
        {"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)},
@@ -97,9 +98,10 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
 static int
 ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
+
        ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
-       ecmd->advertising = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
+       ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
        ecmd->port = PORT_FIBRE;
        ecmd->transceiver = XCVR_EXTERNAL;
 
@@ -118,7 +120,8 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 static int
 ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
+
        if(ecmd->autoneg == AUTONEG_ENABLE ||
           ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
                return -EINVAL;
@@ -127,6 +130,12 @@ ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                ixgb_down(adapter, TRUE);
                ixgb_reset(adapter);
                ixgb_up(adapter);
+               /* be optimistic about our link, since we were up before */
+               adapter->link_speed = 10000;
+               adapter->link_duplex = FULL_DUPLEX;
+               netif_carrier_on(netdev);
+               netif_wake_queue(netdev);
+               
        } else
                ixgb_reset(adapter);
 
@@ -137,7 +146,7 @@ static void
 ixgb_get_pauseparam(struct net_device *netdev,
                         struct ethtool_pauseparam *pause)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        struct ixgb_hw *hw = &adapter->hw;
        
        pause->autoneg = AUTONEG_DISABLE;
@@ -156,7 +165,7 @@ static int
 ixgb_set_pauseparam(struct net_device *netdev,
                         struct ethtool_pauseparam *pause)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        struct ixgb_hw *hw = &adapter->hw;
        
        if(pause->autoneg == AUTONEG_ENABLE)
@@ -174,6 +183,11 @@ ixgb_set_pauseparam(struct net_device *netdev,
        if(netif_running(adapter->netdev)) {
                ixgb_down(adapter, TRUE);
                ixgb_up(adapter);
+               /* be optimistic about our link, since we were up before */
+               adapter->link_speed = 10000;
+               adapter->link_duplex = FULL_DUPLEX;
+               netif_carrier_on(netdev);
+               netif_wake_queue(netdev);
        } else
                ixgb_reset(adapter);
                
@@ -183,19 +197,26 @@ ixgb_set_pauseparam(struct net_device *netdev,
 static uint32_t
 ixgb_get_rx_csum(struct net_device *netdev)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
+
        return adapter->rx_csum;
 }
 
 static int
 ixgb_set_rx_csum(struct net_device *netdev, uint32_t data)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
+
        adapter->rx_csum = data;
 
        if(netif_running(netdev)) {
                ixgb_down(adapter,TRUE);
                ixgb_up(adapter);
+               /* be optimistic about our link, since we were up before */
+               adapter->link_speed = 10000;
+               adapter->link_duplex = FULL_DUPLEX;
+               netif_carrier_on(netdev);
+               netif_wake_queue(netdev);
        } else
                ixgb_reset(adapter);
        return 0;
@@ -243,13 +264,16 @@ static void
 ixgb_get_regs(struct net_device *netdev,
                   struct ethtool_regs *regs, void *p)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        struct ixgb_hw *hw = &adapter->hw;
        uint32_t *reg = p;
        uint32_t *reg_start = reg;
        uint8_t i;
 
-       regs->version = (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
+       /* the 1 (one) below indicates an attempt at versioning, if the
+        * interface in ethtool or the driver changes, this 1 should be
+        * incremented */
+       regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
 
        /* General Registers */
        *reg++ = IXGB_READ_REG(hw, CTRL0);      /*   0 */
@@ -278,7 +302,8 @@ ixgb_get_regs(struct net_device *netdev,
        *reg++ = IXGB_READ_REG(hw, RAIDC);      /*  19 */
        *reg++ = IXGB_READ_REG(hw, RXCSUM);     /*  20 */
 
-       for (i = 0; i < IXGB_RAR_ENTRIES; i++) {
+       /* there are 16 RAR entries in hardware, we only use 3 */
+       for(i = 0; i < 16; i++) {
                *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
                *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
        }
@@ -386,7 +411,7 @@ static int
 ixgb_get_eeprom(struct net_device *netdev,
                  struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        struct ixgb_hw *hw = &adapter->hw;
        uint16_t *eeprom_buff;
        int i, max_len, first_word, last_word;
@@ -434,7 +459,7 @@ static int
 ixgb_set_eeprom(struct net_device *netdev,
                  struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        struct ixgb_hw *hw = &adapter->hw;
        uint16_t *eeprom_buff;
        void *ptr;
@@ -492,7 +517,7 @@ static void
 ixgb_get_drvinfo(struct net_device *netdev,
                   struct ethtool_drvinfo *drvinfo)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
 
        strncpy(drvinfo->driver,  ixgb_driver_name, 32);
        strncpy(drvinfo->version, ixgb_driver_version, 32);
@@ -507,7 +532,7 @@ static void
 ixgb_get_ringparam(struct net_device *netdev,
                struct ethtool_ringparam *ring)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        struct ixgb_desc_ring *txdr = &adapter->tx_ring;
        struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
 
@@ -525,7 +550,7 @@ static int
 ixgb_set_ringparam(struct net_device *netdev,
                struct ethtool_ringparam *ring)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        struct ixgb_desc_ring *txdr = &adapter->tx_ring;
        struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
        struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
@@ -568,6 +593,11 @@ ixgb_set_ringparam(struct net_device *netdev,
                adapter->tx_ring = tx_new;
                if((err = ixgb_up(adapter)))
                        return err;
+               /* be optimistic about our link, since we were up before */
+               adapter->link_speed = 10000;
+               adapter->link_duplex = FULL_DUPLEX;
+               netif_carrier_on(netdev);
+               netif_wake_queue(netdev);
        }
 
        return 0;
@@ -602,7 +632,7 @@ ixgb_led_blink_callback(unsigned long data)
 static int
 ixgb_phys_id(struct net_device *netdev, uint32_t data)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
 
        if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
                data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
@@ -615,11 +645,10 @@ ixgb_phys_id(struct net_device *netdev, uint32_t data)
 
        mod_timer(&adapter->blink_timer, jiffies);
 
-       set_current_state(TASK_INTERRUPTIBLE);
-       if(data)
-               schedule_timeout(data * HZ);
+       if (data)
+               schedule_timeout_interruptible(data * HZ);
        else
-               schedule_timeout(MAX_SCHEDULE_TIMEOUT);
+               schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
 
        del_timer_sync(&adapter->blink_timer);
        ixgb_led_off(&adapter->hw);
@@ -638,7 +667,7 @@ static void
 ixgb_get_ethtool_stats(struct net_device *netdev, 
                struct ethtool_stats *stats, uint64_t *data)
 {
-       struct ixgb_adapter *adapter = netdev->priv;
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
        int i;
 
        ixgb_update_stats(adapter);
@@ -665,7 +694,7 @@ ixgb_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
        }
 }
 
-struct ethtool_ops ixgb_ethtool_ops = {
+static struct ethtool_ops ixgb_ethtool_ops = {
        .get_settings = ixgb_get_settings,
        .set_settings = ixgb_set_settings,
        .get_drvinfo = ixgb_get_drvinfo,
@@ -693,6 +722,7 @@ struct ethtool_ops ixgb_ethtool_ops = {
        .phys_id = ixgb_phys_id,
        .get_stats_count = ixgb_get_stats_count,
        .get_ethtool_stats = ixgb_get_ethtool_stats,
+       .get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 void ixgb_set_ethtool_ops(struct net_device *netdev)