Commit b55ccb35 authored by Jeff Kirsher's avatar Jeff Kirsher Committed by Jeff Garzik

[PATCH] e1000: Fix ASF/AMT for 8257{1|2|3} controllers

The 82573 controller required different logic than 82571|2 controllers.  Corrected the reset logic for 8257{1|2|3} controllers.
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarJohn Ronciak <john.ronciak@intel.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 57128197
...@@ -2982,6 +2982,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw) ...@@ -2982,6 +2982,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
if (hw->mac_type < e1000_82571) if (hw->mac_type < e1000_82571)
msec_delay(10); msec_delay(10);
else
udelay(100);
E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
......
...@@ -320,6 +320,74 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter) ...@@ -320,6 +320,74 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter)
} }
} }
/**
* e1000_release_hw_control - release control of the h/w to f/w
* @adapter: address of board private structure
*
* e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
* For ASF and Pass Through versions of f/w this means that the
* driver is no longer loaded. For AMT version (only with 82573) i
* of the f/w this means that the netowrk i/f is closed.
*
**/
static inline void
e1000_release_hw_control(struct e1000_adapter *adapter)
{
uint32_t ctrl_ext;
uint32_t swsm;
/* Let firmware taken over control of h/w */
switch (adapter->hw.mac_type) {
case e1000_82571:
case e1000_82572:
ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm & ~E1000_SWSM_DRV_LOAD);
default:
break;
}
}
/**
* e1000_get_hw_control - get control of the h/w from f/w
* @adapter: address of board private structure
*
* e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
* For ASF and Pass Through versions of f/w this means that
* the driver is loaded. For AMT version (only with 82573)
* of the f/w this means that the netowrk i/f is open.
*
**/
static inline void
e1000_get_hw_control(struct e1000_adapter *adapter)
{
uint32_t ctrl_ext;
uint32_t swsm;
/* Let firmware know the driver has taken over */
switch (adapter->hw.mac_type) {
case e1000_82571:
case e1000_82572:
ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm | E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
}
int int
e1000_up(struct e1000_adapter *adapter) e1000_up(struct e1000_adapter *adapter)
{ {
...@@ -523,8 +591,6 @@ e1000_probe(struct pci_dev *pdev, ...@@ -523,8 +591,6 @@ e1000_probe(struct pci_dev *pdev,
struct net_device *netdev; struct net_device *netdev;
struct e1000_adapter *adapter; struct e1000_adapter *adapter;
unsigned long mmio_start, mmio_len; unsigned long mmio_start, mmio_len;
uint32_t ctrl_ext;
uint32_t swsm;
static int cards_found = 0; static int cards_found = 0;
int i, err, pci_using_dac; int i, err, pci_using_dac;
...@@ -736,22 +802,13 @@ e1000_probe(struct pci_dev *pdev, ...@@ -736,22 +802,13 @@ e1000_probe(struct pci_dev *pdev,
/* reset the hardware with the new settings */ /* reset the hardware with the new settings */
e1000_reset(adapter); e1000_reset(adapter);
/* Let firmware know the driver has taken over */ /* If the controller is 82573 and f/w is AMT, do not set
switch(adapter->hw.mac_type) { * DRV_LOAD until the interface is up. For all other cases,
case e1000_82571: * let the f/w know that the h/w is now under the control
case e1000_82572: * of the driver. */
ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); if (adapter->hw.mac_type != e1000_82573 ||
E1000_WRITE_REG(&adapter->hw, CTRL_EXT, !e1000_check_mng_mode(&adapter->hw))
ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); e1000_get_hw_control(adapter);
break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm | E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
strcpy(netdev->name, "eth%d"); strcpy(netdev->name, "eth%d");
if((err = register_netdev(netdev))) if((err = register_netdev(netdev)))
...@@ -788,8 +845,7 @@ e1000_remove(struct pci_dev *pdev) ...@@ -788,8 +845,7 @@ e1000_remove(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t ctrl_ext; uint32_t manc;
uint32_t manc, swsm;
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
int i; int i;
#endif #endif
...@@ -805,22 +861,9 @@ e1000_remove(struct pci_dev *pdev) ...@@ -805,22 +861,9 @@ e1000_remove(struct pci_dev *pdev)
} }
} }
switch(adapter->hw.mac_type) { /* Release control of h/w to f/w. If f/w is AMT enabled, this
case e1000_82571: * would have already happened in close and is redundant. */
case e1000_82572: e1000_release_hw_control(adapter);
ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm & ~E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
unregister_netdev(netdev); unregister_netdev(netdev);
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
...@@ -1077,6 +1120,12 @@ e1000_open(struct net_device *netdev) ...@@ -1077,6 +1120,12 @@ e1000_open(struct net_device *netdev)
e1000_update_mng_vlan(adapter); e1000_update_mng_vlan(adapter);
} }
/* If AMT is enabled, let the firmware know that the network
* interface is now open */
if (adapter->hw.mac_type == e1000_82573 &&
e1000_check_mng_mode(&adapter->hw))
e1000_get_hw_control(adapter);
return E1000_SUCCESS; return E1000_SUCCESS;
err_up: err_up:
...@@ -1115,6 +1164,13 @@ e1000_close(struct net_device *netdev) ...@@ -1115,6 +1164,13 @@ e1000_close(struct net_device *netdev)
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) { E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
} }
/* If AMT is enabled, let the firmware know that the network
* interface is now closed */
if (adapter->hw.mac_type == e1000_82573 &&
e1000_check_mng_mode(&adapter->hw))
e1000_release_hw_control(adapter);
return 0; return 0;
} }
...@@ -4182,7 +4238,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -4182,7 +4238,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm; uint32_t ctrl, ctrl_ext, rctl, manc, status;
uint32_t wufc = adapter->wol; uint32_t wufc = adapter->wol;
netif_device_detach(netdev); netif_device_detach(netdev);
...@@ -4251,21 +4307,9 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -4251,21 +4307,9 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
} }
} }
switch(adapter->hw.mac_type) { /* Release control of h/w to f/w. If f/w is AMT enabled, this
case e1000_82571: * would have already happened in close and is redundant. */
case e1000_82572: e1000_release_hw_control(adapter);
ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
break;
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm & ~E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state)); pci_set_power_state(pdev, pci_choose_state(pdev, state));
...@@ -4278,8 +4322,7 @@ e1000_resume(struct pci_dev *pdev) ...@@ -4278,8 +4322,7 @@ e1000_resume(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t manc, ret_val, swsm; uint32_t manc, ret_val;
uint32_t ctrl_ext;
pci_set_power_state(pdev, PCI_D0); pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev); pci_restore_state(pdev);
...@@ -4304,21 +4347,13 @@ e1000_resume(struct pci_dev *pdev) ...@@ -4304,21 +4347,13 @@ e1000_resume(struct pci_dev *pdev)
E1000_WRITE_REG(&adapter->hw, MANC, manc); E1000_WRITE_REG(&adapter->hw, MANC, manc);
} }
switch(adapter->hw.mac_type) { /* If the controller is 82573 and f/w is AMT, do not set
case e1000_82571: * DRV_LOAD until the interface is up. For all other cases,
case e1000_82572: * let the f/w know that the h/w is now under the control
ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); * of the driver. */
E1000_WRITE_REG(&adapter->hw, CTRL_EXT, if (adapter->hw.mac_type != e1000_82573 ||
ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); !e1000_check_mng_mode(&adapter->hw))
break; e1000_get_hw_control(adapter);
case e1000_82573:
swsm = E1000_READ_REG(&adapter->hw, SWSM);
E1000_WRITE_REG(&adapter->hw, SWSM,
swsm | E1000_SWSM_DRV_LOAD);
break;
default:
break;
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment