e1000e: add support for new 82574L part
[linux-2.6-block.git] / drivers / net / e1000e / ethtool.c
index a89498dcb6368f600809360bf01bac6daac38b3c..52b762eb17458985c670705507667c1958db8816 100644 (file)
@@ -568,6 +568,7 @@ static int e1000_set_eeprom(struct net_device *netdev,
         * and flush shadow RAM for 82573 controllers
         */
        if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) ||
+                              (hw->mac.type == e1000_82574) ||
                               (hw->mac.type == e1000_82573)))
                e1000e_update_nvm_checksum(hw);
 
@@ -779,6 +780,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
                toggle = 0x7FFFF3FF;
                break;
        case e1000_82573:
+       case e1000_82574:
        case e1000_ich8lan:
        case e1000_ich9lan:
        case e1000_ich10lan:
@@ -887,10 +889,18 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
        u32 shared_int = 1;
        u32 irq = adapter->pdev->irq;
        int i;
+       int ret_val = 0;
+       int int_mode = E1000E_INT_MODE_LEGACY;
 
        *data = 0;
 
-       /* NOTE: we don't test MSI interrupts here, yet */
+       /* NOTE: we don't test MSI/MSI-X interrupts here, yet */
+       if (adapter->int_mode == E1000E_INT_MODE_MSIX) {
+               int_mode = adapter->int_mode;
+               e1000e_reset_interrupt_capability(adapter);
+               adapter->int_mode = E1000E_INT_MODE_LEGACY;
+               e1000e_set_interrupt_capability(adapter);
+       }
        /* Hook up test interrupt handler just for this test */
        if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
                         netdev)) {
@@ -898,7 +908,8 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
        } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED,
                 netdev->name, netdev)) {
                *data = 1;
-               return -1;
+               ret_val = -1;
+               goto out;
        }
        e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared"));
 
@@ -988,7 +999,14 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
        /* Unhook test interrupt handler */
        free_irq(irq, netdev);
 
-       return *data;
+out:
+       if (int_mode == E1000E_INT_MODE_MSIX) {
+               e1000e_reset_interrupt_capability(adapter);
+               adapter->int_mode = int_mode;
+               e1000e_set_interrupt_capability(adapter);
+       }
+
+       return ret_val;
 }
 
 static void e1000_free_desc_rings(struct e1000_adapter *adapter)
@@ -1769,11 +1787,13 @@ static void e1000_led_blink_callback(unsigned long data)
 static int e1000_phys_id(struct net_device *netdev, u32 data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
 
        if (!data)
                data = INT_MAX;
 
-       if (adapter->hw.phy.type == e1000_phy_ife) {
+       if ((hw->phy.type == e1000_phy_ife) ||
+           (hw->mac.type == e1000_82574)) {
                if (!adapter->blink_timer.function) {
                        init_timer(&adapter->blink_timer);
                        adapter->blink_timer.function =
@@ -1783,16 +1803,16 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
                mod_timer(&adapter->blink_timer, jiffies);
                msleep_interruptible(data * 1000);
                del_timer_sync(&adapter->blink_timer);
-               e1e_wphy(&adapter->hw,
-                                   IFE_PHY_SPECIAL_CONTROL_LED, 0);
+               if (hw->phy.type == e1000_phy_ife)
+                       e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
        } else {
-               e1000e_blink_led(&adapter->hw);
+               e1000e_blink_led(hw);
                msleep_interruptible(data * 1000);
        }
 
-       adapter->hw.mac.ops.led_off(&adapter->hw);
+       hw->mac.ops.led_off(hw);
        clear_bit(E1000_LED_ON, &adapter->led_status);
-       adapter->hw.mac.ops.cleanup_led(&adapter->hw);
+       hw->mac.ops.cleanup_led(hw);
 
        return 0;
 }