Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 35204
b: refs/heads/master
c: 120cd57
h: refs/heads/master
v: v3
  • Loading branch information
Jesse Brandeburg authored and Auke Kok committed Aug 31, 2006
1 parent 60961f6 commit d771fcb
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 90 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1db2740d78c74eb11c4d0906047d9c13229a89a4
refs/heads/master: 120cd57644f85b280b538ee403423641167913a9
3 changes: 2 additions & 1 deletion trunk/drivers/net/e1000/e1000.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ struct e1000_adapter {
uint32_t bd_number;
uint32_t rx_buffer_len;
uint32_t wol;
uint32_t ksp3_port_a;
uint32_t smartspeed;
uint32_t en_mng_pt;
uint16_t link_speed;
Expand Down Expand Up @@ -341,7 +340,9 @@ struct e1000_adapter {
boolean_t tso_force;
#endif
boolean_t smart_power_down; /* phy smart power down */
boolean_t quad_port_a;
unsigned long flags;
uint32_t eeprom_wol;
};

enum e1000_state_t {
Expand Down
166 changes: 91 additions & 75 deletions trunk/drivers/net/e1000/e1000_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1675,67 +1675,99 @@ e1000_diag_test(struct net_device *netdev,
msleep_interruptible(4 * 1000);
}

static void
e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
int retval = 1; /* fail by default */

switch (adapter->hw.device_id) {
case E1000_DEV_ID_82542:
switch (hw->device_id) {
case E1000_DEV_ID_82543GC_FIBER:
case E1000_DEV_ID_82543GC_COPPER:
case E1000_DEV_ID_82544EI_FIBER:
case E1000_DEV_ID_82546EB_QUAD_COPPER:
case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82546GB_QUAD_COPPER:
case E1000_DEV_ID_82546GB_PCIE:
/* these don't support WoL at all */
wol->supported = 0;
wol->wolopts = 0;
return;

case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
/* device id 10B5 port-A supports wol */
if (!adapter->ksp3_port_a) {
wol->supported = 0;
return;
}
/* KSP3 does not suppport UCAST wake-ups for any interface */
wol->supported = WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;

if (adapter->wol & E1000_WUFC_EX)
DPRINTK(DRV, ERR, "Interface does not support "
"directed (unicast) frame wake-up packets\n");
wol->wolopts = 0;
goto do_defaults;

break;
case E1000_DEV_ID_82546EB_FIBER:
case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82571EB_FIBER:
/* Wake events only supported on port A for dual fiber */
case E1000_DEV_ID_82571EB_SERDES:
case E1000_DEV_ID_82571EB_COPPER:
/* Wake events not supported on port B */
if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
wol->supported = 0;
wol->wolopts = 0;
return;
break;
}
/* Fall Through */

/* return success for non excluded adapter ports */
retval = 0;
break;
case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
/* quad port adapters only support WoL on port A */
if (!adapter->quad_port_a) {
wol->supported = 0;
break;
}
/* return success for non excluded adapter ports */
retval = 0;
break;
default:
wol->supported = WAKE_UCAST | WAKE_MCAST |
WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0;
/* dual port cards only support WoL on port A from now on
* unless it was enabled in the eeprom for port B
* so exclude FUNC_1 ports from having WoL enabled */
if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1 &&
!adapter->eeprom_wol) {
wol->supported = 0;
break;
}

do_defaults:
if (adapter->wol & E1000_WUFC_EX)
wol->wolopts |= WAKE_UCAST;
if (adapter->wol & E1000_WUFC_MC)
wol->wolopts |= WAKE_MCAST;
if (adapter->wol & E1000_WUFC_BC)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & E1000_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
retval = 0;
}

return retval;
}

static void
e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct e1000_adapter *adapter = netdev_priv(netdev);

wol->supported = WAKE_UCAST | WAKE_MCAST |
WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0;

/* this function will set ->supported = 0 and return 1 if wol is not
* supported by this hardware */
if (e1000_wol_exclusion(adapter, wol))
return;

/* apply any specific unsupported masks here */
switch (adapter->hw.device_id) {
case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
/* KSP3 does not suppport UCAST wake-ups */
wol->supported &= ~WAKE_UCAST;

if (adapter->wol & E1000_WUFC_EX)
DPRINTK(DRV, ERR, "Interface does not support "
"directed (unicast) frame wake-up packets\n");
break;
default:
break;
}

if (adapter->wol & E1000_WUFC_EX)
wol->wolopts |= WAKE_UCAST;
if (adapter->wol & E1000_WUFC_MC)
wol->wolopts |= WAKE_MCAST;
if (adapter->wol & E1000_WUFC_BC)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & E1000_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;

return;
}

static int
Expand All @@ -1744,52 +1776,36 @@ e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;

switch (adapter->hw.device_id) {
case E1000_DEV_ID_82542:
case E1000_DEV_ID_82543GC_FIBER:
case E1000_DEV_ID_82543GC_COPPER:
case E1000_DEV_ID_82544EI_FIBER:
case E1000_DEV_ID_82546EB_QUAD_COPPER:
case E1000_DEV_ID_82546GB_QUAD_COPPER:
case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82545EM_COPPER:
if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP;

if (e1000_wol_exclusion(adapter, wol))
return wol->wolopts ? -EOPNOTSUPP : 0;

switch (hw->device_id) {
case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
/* device id 10B5 port-A supports wol */
if (!adapter->ksp3_port_a)
return wol->wolopts ? -EOPNOTSUPP : 0;

if (wol->wolopts & WAKE_UCAST) {
DPRINTK(DRV, ERR, "Interface does not support "
"directed (unicast) frame wake-up packets\n");
return -EOPNOTSUPP;
}

case E1000_DEV_ID_82546EB_FIBER:
case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82571EB_FIBER:
/* Wake events only supported on port A for dual fiber */
if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
return wol->wolopts ? -EOPNOTSUPP : 0;
/* Fall Through */

break;
default:
if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP;

adapter->wol = 0;

if (wol->wolopts & WAKE_UCAST)
adapter->wol |= E1000_WUFC_EX;
if (wol->wolopts & WAKE_MCAST)
adapter->wol |= E1000_WUFC_MC;
if (wol->wolopts & WAKE_BCAST)
adapter->wol |= E1000_WUFC_BC;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= E1000_WUFC_MAG;
break;
}

/* these settings will always override what we currently have */
adapter->wol = 0;

if (wol->wolopts & WAKE_UCAST)
adapter->wol |= E1000_WUFC_EX;
if (wol->wolopts & WAKE_MCAST)
adapter->wol |= E1000_WUFC_MC;
if (wol->wolopts & WAKE_BCAST)
adapter->wol |= E1000_WUFC_BC;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= E1000_WUFC_MAG;

return 0;
}

Expand Down
47 changes: 34 additions & 13 deletions trunk/drivers/net/e1000/e1000_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,9 +681,9 @@ e1000_probe(struct pci_dev *pdev,
unsigned long flash_start, flash_len;

static int cards_found = 0;
static int e1000_ksp3_port_a = 0; /* global ksp3 port a indication */
static int global_quad_port_a = 0; /* global ksp3 port a indication */
int i, err, pci_using_dac;
uint16_t eeprom_data;
uint16_t eeprom_data = 0;
uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
if ((err = pci_enable_device(pdev)))
return err;
Expand Down Expand Up @@ -786,15 +786,6 @@ e1000_probe(struct pci_dev *pdev,
if (e1000_check_phy_reset_block(&adapter->hw))
DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");

/* if ksp3, indicate if it's port a being setup */
if (pdev->device == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 &&
e1000_ksp3_port_a == 0)
adapter->ksp3_port_a = 1;
e1000_ksp3_port_a++;
/* Reset for multiple KP3 adapters */
if (e1000_ksp3_port_a == 4)
e1000_ksp3_port_a = 0;

if (adapter->hw.mac_type >= e1000_82543) {
netdev->features = NETIF_F_SG |
NETIF_F_HW_CSUM |
Expand Down Expand Up @@ -913,7 +904,37 @@ e1000_probe(struct pci_dev *pdev,
break;
}
if (eeprom_data & eeprom_apme_mask)
adapter->wol |= E1000_WUFC_MAG;
adapter->eeprom_wol |= E1000_WUFC_MAG;

/* now that we have the eeprom settings, apply the special cases
* where the eeprom may be wrong or the board simply won't support
* wake on lan on a particular port */
switch (pdev->device) {
case E1000_DEV_ID_82546GB_PCIE:
adapter->eeprom_wol = 0;
break;
case E1000_DEV_ID_82546EB_FIBER:
case E1000_DEV_ID_82546GB_FIBER:
case E1000_DEV_ID_82571EB_FIBER:
/* Wake events only supported on port A for dual fiber
* regardless of eeprom setting */
if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
adapter->eeprom_wol = 0;
break;
case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
/* if quad port adapter, disable WoL on all but port A */
if (global_quad_port_a != 0)
adapter->eeprom_wol = 0;
else
adapter->quad_port_a = 1;
/* Reset for multiple quad port adapters */
if (++global_quad_port_a == 4)
global_quad_port_a = 0;
break;
}

/* initialize the wol settings based on the eeprom settings */
adapter->wol = adapter->eeprom_wol;

/* print bus type/speed/width info */
{
Expand Down Expand Up @@ -4635,7 +4656,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
e1000_set_multi(netdev);

/* turn on all-multi mode if wake on multicast is enabled */
if (adapter->wol & E1000_WUFC_MC) {
if (wufc & E1000_WUFC_MC) {
rctl = E1000_READ_REG(&adapter->hw, RCTL);
rctl |= E1000_RCTL_MPE;
E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
Expand Down

0 comments on commit d771fcb

Please sign in to comment.