* [PATCH 1/4] e1000e: alternate MAC address support
@ 2007-10-31 22:21 Auke Kok
2007-10-31 22:22 ` [PATCH 2/4] e1000e: Disable L1 ASPM power savings for 82573 mobile variants Auke Kok
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Auke Kok @ 2007-10-31 22:21 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
From: Bill Hayes <bill.hayes@hp.com>
Port alternate MAC address support from the sourceforge
e1000 driver to the upstream e1000e driver.
Signed-off-by: Bill Hayes <bill.hayes@hp.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/e1000e/82571.c | 4 ++++
drivers/net/e1000e/defines.h | 1 +
drivers/net/e1000e/hw.h | 1 +
drivers/net/e1000e/lib.c | 39 +++++++++++++++++++++++++++++++++++++--
4 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 14141a5..b6401ab 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -752,6 +752,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
ew32(IMC, 0xffffffff);
icr = er32(ICR);
+ if (hw->mac.type == e1000_82571 &&
+ hw->dev_spec.e82571.alt_mac_addr_is_present)
+ e1000e_set_laa_state_82571(hw, true);
+
return 0;
}
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index b32ed45..f2175ea 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -557,6 +557,7 @@
#define NVM_INIT_3GIO_3 0x001A
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_CFG 0x0012
+#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 6451578..1bb2052 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -816,6 +816,7 @@ struct e1000_bus_info {
struct e1000_dev_spec_82571 {
bool laa_is_present;
+ bool alt_mac_addr_is_present;
};
struct e1000_shadow_ram {
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 0bdeca3..16f35fa 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -2059,9 +2059,44 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
{
s32 ret_val;
u16 offset, nvm_data, i;
+ u16 mac_addr_offset = 0;
+
+ if (hw->mac.type == e1000_82571) {
+ /* Check for an alternate MAC address. An alternate MAC
+ * address can be setup by pre-boot software and must be
+ * treated like a permanent address and must override the
+ * actual permanent MAC address. */
+ ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+ &mac_addr_offset);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ if (mac_addr_offset == 0xFFFF)
+ mac_addr_offset = 0;
+
+ if (mac_addr_offset) {
+ if (hw->bus.func == E1000_FUNC_1)
+ mac_addr_offset += ETH_ALEN/sizeof(u16);
+
+ /* make sure we have a valid mac address here
+ * before using it */
+ ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
+ &nvm_data);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ if (nvm_data & 0x0001)
+ mac_addr_offset = 0;
+ }
+
+ if (mac_addr_offset)
+ hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
+ }
for (i = 0; i < ETH_ALEN; i += 2) {
- offset = i >> 1;
+ offset = mac_addr_offset + (i >> 1);
ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
@@ -2072,7 +2107,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
}
/* Flip last bit of mac address if we're on second port */
- if (hw->bus.func == E1000_FUNC_1)
+ if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
hw->mac.perm_addr[5] ^= 1;
for (i = 0; i < ETH_ALEN; i++)
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/4] e1000e: Disable L1 ASPM power savings for 82573 mobile variants
2007-10-31 22:21 [PATCH 1/4] e1000e: alternate MAC address support Auke Kok
@ 2007-10-31 22:22 ` Auke Kok
2007-10-31 22:22 ` [PATCH 3/4] e1000/e1000e: Move PCI-Express device IDs over to e1000e Auke Kok
2007-10-31 22:22 ` [PATCH 4/4] ixgbe: Fix copper PHY initialization code Auke Kok
2 siblings, 0 replies; 4+ messages in thread
From: Auke Kok @ 2007-10-31 22:22 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
L1 ASPM link (pci-e link power savings) has significant benefits
(~1W savings when link is active) but unfortunately does not work
correctly on any of the chipsets that have 82573 on mobile platforms
which causes various nuisances:
- eeprom reads return garbage information leading to bad eeprom
checksums
- long ping times (up to 2 seconds)
- complete system hangs (freeze/lockup)
A lot of T60 owners have been plagued by this, but other mobile
solutions also suffer from these symptoms.
Disabling L1 ASPM before we activate the PCI-E link fixes all of
these issues at the cost of some power consumption.
Remove a workaround RDTR adjustment that is no longer needed with
this new one.
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/e1000e/82571.c | 1 -
drivers/net/e1000e/e1000.h | 1 -
drivers/net/e1000e/netdev.c | 30 ++++++++++++++++++++++++++++++
drivers/net/e1000e/param.c | 7 -------
4 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index b6401ab..45f5ee2 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1343,7 +1343,6 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_STATS_ICR_ICT
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
- | FLAG_HAS_ASPM
| FLAG_HAS_ERT
| FLAG_HAS_SWSM_ON_LOAD,
.pba = 20,
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 473f78d..8b88c22 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -288,7 +288,6 @@ struct e1000_info {
#define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5)
#define FLAG_HAS_SWSM_ON_LOAD (1 << 6)
#define FLAG_HAS_JUMBO_FRAMES (1 << 7)
-#define FLAG_HAS_ASPM (1 << 8)
#define FLAG_HAS_STATS_ICR_ICT (1 << 9)
#define FLAG_HAS_STATS_PTC_PRC (1 << 10)
#define FLAG_HAS_SMART_POWER_DOWN (1 << 11)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 4fd2e23..ec427e2 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3511,6 +3511,33 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
+static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+{
+ int pos;
+ u32 cap;
+ u16 val;
+
+ /*
+ * 82573 workaround - disable L1 ASPM on mobile chipsets
+ *
+ * L1 ASPM on various mobile (ich7) chipsets do not behave properly
+ * resulting in lost data or garbage information on the pci-e link
+ * level. This could result in (false) bad EEPROM checksum errors,
+ * long ping times (up to 2s) or even a system freeze/hang.
+ *
+ * Unfortunately this feature saves about 1W power consumption when
+ * active.
+ */
+ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap);
+ pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
+ if (val & 0x2) {
+ dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
+ val &= ~0x2;
+ pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
+ }
+}
+
#ifdef CONFIG_PM
static int e1000_resume(struct pci_dev *pdev)
{
@@ -3521,6 +3548,7 @@ static int e1000_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
+ e1000e_disable_l1aspm(pdev);
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev,
@@ -3621,6 +3649,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ e1000e_disable_l1aspm(pdev);
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
@@ -3722,6 +3751,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ e1000e_disable_l1aspm(pdev);
err = pci_enable_device(pdev);
if (err)
return err;
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 3327892..df266c3 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -262,13 +262,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
.max = MAX_RXDELAY } }
};
- /* modify min and default if 82573 for slow ping w/a,
- * a value greater than 8 needs to be set for RDTR */
- if (adapter->flags & FLAG_HAS_ASPM) {
- opt.def = 32;
- opt.arg.r.min = 8;
- }
-
if (num_RxIntDelay > bd) {
adapter->rx_int_delay = RxIntDelay[bd];
e1000_validate_option(&adapter->rx_int_delay, &opt,
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/4] e1000/e1000e: Move PCI-Express device IDs over to e1000e
2007-10-31 22:21 [PATCH 1/4] e1000e: alternate MAC address support Auke Kok
2007-10-31 22:22 ` [PATCH 2/4] e1000e: Disable L1 ASPM power savings for 82573 mobile variants Auke Kok
@ 2007-10-31 22:22 ` Auke Kok
2007-10-31 22:22 ` [PATCH 4/4] ixgbe: Fix copper PHY initialization code Auke Kok
2 siblings, 0 replies; 4+ messages in thread
From: Auke Kok @ 2007-10-31 22:22 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
e1000e will from now on support the PCI-Express adapters that
previously were supported by e1000. This support means better
performance and easier debugging from now on for both the old
PCI-X/PCI hardware and PCI-Express adapters.
This patch also moves 3 recently merged device IDs over to e1000e
that are identical to quad-port versions of already existing
dual port versions. With this last bit every former e1000 pci-e
device should work now with e1000e.
Here is a brief list of which gigabit driver to use with which
adapter:
e1000:
82540 -> 82547
e1000e:
82571 -> 82573
ich8, ich9 (82562 or 82566)
es2lan (80003eslan)
igb: (not yet merged, only available from e1000.sf.net)
82575
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/e1000/e1000_main.c | 27 ---------------------------
drivers/net/e1000e/82571.c | 6 ++++++
drivers/net/e1000e/hw.h | 3 +++
drivers/net/e1000e/netdev.c | 9 +++------
4 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 72deff0..d1b88e4 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -73,14 +73,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x1026),
INTEL_E1000_ETHERNET_DEVICE(0x1027),
INTEL_E1000_ETHERNET_DEVICE(0x1028),
- INTEL_E1000_ETHERNET_DEVICE(0x1049),
- INTEL_E1000_ETHERNET_DEVICE(0x104A),
- INTEL_E1000_ETHERNET_DEVICE(0x104B),
- INTEL_E1000_ETHERNET_DEVICE(0x104C),
- INTEL_E1000_ETHERNET_DEVICE(0x104D),
- INTEL_E1000_ETHERNET_DEVICE(0x105E),
- INTEL_E1000_ETHERNET_DEVICE(0x105F),
- INTEL_E1000_ETHERNET_DEVICE(0x1060),
INTEL_E1000_ETHERNET_DEVICE(0x1075),
INTEL_E1000_ETHERNET_DEVICE(0x1076),
INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -89,28 +81,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x107A),
INTEL_E1000_ETHERNET_DEVICE(0x107B),
INTEL_E1000_ETHERNET_DEVICE(0x107C),
- INTEL_E1000_ETHERNET_DEVICE(0x107D),
- INTEL_E1000_ETHERNET_DEVICE(0x107E),
- INTEL_E1000_ETHERNET_DEVICE(0x107F),
INTEL_E1000_ETHERNET_DEVICE(0x108A),
- INTEL_E1000_ETHERNET_DEVICE(0x108B),
- INTEL_E1000_ETHERNET_DEVICE(0x108C),
- INTEL_E1000_ETHERNET_DEVICE(0x1096),
- INTEL_E1000_ETHERNET_DEVICE(0x1098),
INTEL_E1000_ETHERNET_DEVICE(0x1099),
- INTEL_E1000_ETHERNET_DEVICE(0x109A),
- INTEL_E1000_ETHERNET_DEVICE(0x10A4),
- INTEL_E1000_ETHERNET_DEVICE(0x10A5),
INTEL_E1000_ETHERNET_DEVICE(0x10B5),
- INTEL_E1000_ETHERNET_DEVICE(0x10B9),
- INTEL_E1000_ETHERNET_DEVICE(0x10BA),
- INTEL_E1000_ETHERNET_DEVICE(0x10BB),
- INTEL_E1000_ETHERNET_DEVICE(0x10BC),
- INTEL_E1000_ETHERNET_DEVICE(0x10C4),
- INTEL_E1000_ETHERNET_DEVICE(0x10C5),
- INTEL_E1000_ETHERNET_DEVICE(0x10D5),
- INTEL_E1000_ETHERNET_DEVICE(0x10D9),
- INTEL_E1000_ETHERNET_DEVICE(0x10DA),
/* required last entry */
{0,}
};
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 45f5ee2..3beace5 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -194,6 +194,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
break;
case E1000_DEV_ID_82571EB_SERDES:
case E1000_DEV_ID_82572EI_SERDES:
+ case E1000_DEV_ID_82571EB_SERDES_DUAL:
+ case E1000_DEV_ID_82571EB_SERDES_QUAD:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
@@ -260,6 +262,7 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
case E1000_DEV_ID_82571EB_QUAD_COPPER:
case E1000_DEV_ID_82571EB_QUAD_FIBER:
case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
+ case E1000_DEV_ID_82571PT_QUAD_COPPER:
adapter->flags |= FLAG_IS_QUAD_PORT;
/* mark the first port */
if (global_quad_port_a == 0)
@@ -285,6 +288,9 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
if (adapter->flags & FLAG_IS_QUAD_PORT &&
(!(adapter->flags & FLAG_IS_QUAD_PORT_A)))
adapter->flags &= ~FLAG_HAS_WOL;
+ /* Does not support WoL on any port */
+ if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
+ adapter->flags &= ~FLAG_HAS_WOL;
break;
case e1000_82573:
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 1bb2052..71f93ce 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -303,8 +303,11 @@ enum e1e_registers {
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
+#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
+#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
+#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index ec427e2..a271112 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4088,16 +4088,15 @@ static struct pci_error_handlers e1000_err_handler = {
};
static struct pci_device_id e1000_pci_tbl[] = {
- /*
- * Support for 82571/2/3, es2lan and ich8 will be phased in
- * stepwise.
-
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
@@ -4120,8 +4119,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
- */
-
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 4/4] ixgbe: Fix copper PHY initialization code
2007-10-31 22:21 [PATCH 1/4] e1000e: alternate MAC address support Auke Kok
2007-10-31 22:22 ` [PATCH 2/4] e1000e: Disable L1 ASPM power savings for 82573 mobile variants Auke Kok
2007-10-31 22:22 ` [PATCH 3/4] e1000/e1000e: Move PCI-Express device IDs over to e1000e Auke Kok
@ 2007-10-31 22:22 ` Auke Kok
2 siblings, 0 replies; 4+ messages in thread
From: Auke Kok @ 2007-10-31 22:22 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
While cleaning up the internal API focussing on Fiber and CX4 code
we found that I had broken the copper PHY initialization code. This
patch restores the PHY-specific code. This is mostly uninteresting
since no copper PHY boards are yet available. The changes have been
tested against Fiber only as I do not even have copper PHY versions
of 82598 macs.
This change actually cleans up the API code a bit more and we
lose some initialization code. A few PHY link detection helper
lines of code have been snuck into this patch, as well as a
read flush where it was suspected that this might cause issues.
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/ixgbe/ixgbe.h | 8 --
drivers/net/ixgbe/ixgbe_82598.c | 156 +++++++++++---------------------------
drivers/net/ixgbe/ixgbe_common.c | 10 ++
drivers/net/ixgbe/ixgbe_main.c | 19 ++---
drivers/net/ixgbe/ixgbe_phy.h | 1
drivers/net/ixgbe/ixgbe_type.h | 13 ++-
6 files changed, 71 insertions(+), 136 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index bc51432..a021a6e 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -234,14 +234,10 @@ enum ixbge_state_t {
};
enum ixgbe_boards {
- board_82598AF,
- board_82598EB,
- board_82598AT,
+ board_82598,
};
-extern struct ixgbe_info ixgbe_82598AF_info;
-extern struct ixgbe_info ixgbe_82598EB_info;
-extern struct ixgbe_info ixgbe_82598AT_info;
+extern struct ixgbe_info ixgbe_82598_info;
extern char ixgbe_driver_name[];
extern const char ixgbe_driver_version[];
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 4d64673..6321b05 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -50,8 +50,6 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up);
static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
bool autoneg,
bool autoneg_wait_to_complete);
@@ -64,6 +62,28 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES;
hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES;
+ /* PHY ops are filled in by default properly for Fiber only */
+ if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598;
+ hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598;
+ hw->mac.ops.get_link_settings =
+ &ixgbe_get_copper_link_settings_82598;
+
+ /* Call PHY identify routine to get the phy type */
+ ixgbe_identify_phy(hw);
+
+ switch (hw->phy.type) {
+ case ixgbe_phy_tn:
+ hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link;
+ hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link;
+ hw->phy.ops.setup_link_speed =
+ &ixgbe_setup_tnx_phy_link_speed;
+ break;
+ default:
+ break;
+ }
+ }
+
return 0;
}
@@ -206,6 +226,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
autoc_reg |= hw->mac.link_mode_select;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ IXGBE_WRITE_FLUSH(hw);
msleep(50);
}
@@ -314,7 +335,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
* ixgbe_hw This will write the AUTOC register based on the new
* stored values
*/
- hw->phy.ops.setup(hw);
+ hw->mac.ops.setup_link(hw);
}
return status;
@@ -332,72 +353,18 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
**/
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
{
- s32 status;
- u32 speed = 0;
- bool link_up = false;
-
- /* Set up MAC */
- hw->phy.ops.setup(hw);
+ s32 status = 0;
/* Restart autonegotiation on PHY */
- status = hw->phy.ops.setup(hw);
-
- /* Synchronize MAC to PHY speed */
- if (status == 0)
- status = hw->phy.ops.check(hw, &speed, &link_up);
-
- return status;
-}
+ if (hw->phy.ops.setup_link)
+ status = hw->phy.ops.setup_link(hw);
-/**
- * ixgbe_check_copper_link_82598 - Syncs MAC & PHY link settings
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @link_up: true if link is up, false otherwise
- *
- * Reads the mac link, phy link, and synchronizes the MAC to PHY.
- **/
-static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up)
-{
- s32 status;
- u32 phy_speed = 0;
- bool phy_link = false;
+ /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */
+ hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
+ hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
- /* This is the speed and link the MAC is set at */
- hw->phy.ops.check(hw, speed, link_up);
-
- /*
- * Check current speed and link status of the PHY register.
- * This is a vendor specific register and may have to
- * be changed for other copper PHYs.
- */
- status = hw->phy.ops.check(hw, &phy_speed, &phy_link);
-
- if ((status == 0) && (phy_link)) {
- /*
- * Check current link status of the MACs link's register
- * matches that of the speed in the PHY register
- */
- if (*speed != phy_speed) {
- /*
- * The copper PHY requires 82598 attach type to be XAUI
- * for 10G and BX for 1G
- */
- hw->mac.link_attach_type =
- (IXGBE_AUTOC_10G_XAUI | IXGBE_AUTOC_1G_BX);
-
- /* Synchronize the MAC speed to the PHY speed */
- status = hw->phy.ops.setup_speed(hw, phy_speed, false,
- false);
- if (status == 0)
- hw->phy.ops.check(hw, speed, link_up);
- else
- status = IXGBE_ERR_LINK_SETUP;
- }
- } else {
- *link_up = phy_link;
- }
+ /* Set up MAC */
+ hw->mac.ops.setup_link(hw);
return status;
}
@@ -415,16 +382,19 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
bool autoneg,
bool autoneg_wait_to_complete)
{
- s32 status;
- bool link_up = 0;
+ s32 status = 0;
/* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
+ if (hw->phy.ops.setup_link_speed)
+ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ autoneg_wait_to_complete);
+
+ /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
+ hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
+ hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
- /* Synchronize MAC to PHY speed */
- if (status == 0)
- status = hw->phy.ops.check(hw, &speed, &link_up);
+ /* Set up MAC */
+ hw->mac.ops.setup_link(hw);
return status;
}
@@ -542,47 +512,15 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
static struct ixgbe_mac_operations mac_ops_82598 = {
.reset = &ixgbe_reset_hw_82598,
.get_media_type = &ixgbe_get_media_type_82598,
+ .setup_link = &ixgbe_setup_mac_link_82598,
+ .check_link = &ixgbe_check_mac_link_82598,
+ .setup_link_speed = &ixgbe_setup_mac_link_speed_82598,
+ .get_link_settings = &ixgbe_get_link_settings_82598,
};
-static struct ixgbe_phy_operations phy_ops_82598EB = {
- .setup = &ixgbe_setup_copper_link_82598,
- .check = &ixgbe_check_copper_link_82598,
- .setup_speed = &ixgbe_setup_copper_link_speed_82598,
- .get_settings = &ixgbe_get_copper_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598EB_info = {
- .mac = ixgbe_mac_82598EB,
- .get_invariants = &ixgbe_get_invariants_82598,
- .mac_ops = &mac_ops_82598,
- .phy_ops = &phy_ops_82598EB,
-};
-
-static struct ixgbe_phy_operations phy_ops_82598AT = {
- .setup = &ixgbe_setup_tnx_phy_link,
- .check = &ixgbe_check_tnx_phy_link,
- .setup_speed = &ixgbe_setup_tnx_phy_link_speed,
- .get_settings = &ixgbe_get_copper_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598AT_info = {
- .mac = ixgbe_mac_82598EB,
- .get_invariants = &ixgbe_get_invariants_82598,
- .mac_ops = &mac_ops_82598,
- .phy_ops = &phy_ops_82598AT,
-};
-
-static struct ixgbe_phy_operations phy_ops_82598AF = {
- .setup = &ixgbe_setup_mac_link_82598,
- .check = &ixgbe_check_mac_link_82598,
- .setup_speed = &ixgbe_setup_mac_link_speed_82598,
- .get_settings = &ixgbe_get_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598AF_info = {
+struct ixgbe_info ixgbe_82598_info = {
.mac = ixgbe_mac_82598EB,
.get_invariants = &ixgbe_get_invariants_82598,
.mac_ops = &mac_ops_82598,
- .phy_ops = &phy_ops_82598AF,
};
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 512e3b2..9c10c05 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -74,7 +74,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
ixgbe_clear_vfta(hw);
/* Set up link */
- hw->phy.ops.setup(hw);
+ hw->mac.ops.setup_link(hw);
/* Clear statistics registers */
ixgbe_clear_hw_cntrs(hw);
@@ -83,6 +83,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS;
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+ IXGBE_WRITE_FLUSH(hw);
/* Clear adapter stopped flag */
hw->adapter_stopped = false;
@@ -297,6 +298,7 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
return 0;
}
@@ -314,6 +316,7 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
return 0;
}
@@ -496,6 +499,7 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
/* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */
swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);
IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
+ IXGBE_WRITE_FLUSH(hw);
}
/**
@@ -1132,7 +1136,7 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
}
/**
- * ixgbe_read_analog_reg8- Reads 8 bit 82598 Atlas analog register
+ * ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register
* @hw: pointer to hardware structure
* @reg: analog register to read
* @val: read value
@@ -1154,7 +1158,7 @@ s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val)
}
/**
- * ixgbe_write_analog_reg8- Writes 8 bit Atlas analog register
+ * ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register
* @hw: pointer to hardware structure
* @reg: atlas register to write
* @val: value to write
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 00bc525..0e14761 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -54,9 +54,7 @@ static const char ixgbe_copyright[] =
"Copyright (c) 1999-2007 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = {
- [board_82598AF] = &ixgbe_82598AF_info,
- [board_82598EB] = &ixgbe_82598EB_info,
- [board_82598AT] = &ixgbe_82598AT_info,
+ [board_82598] = &ixgbe_82598_info,
};
/* ixgbe_pci_tbl - PCI Device ID Table
@@ -69,13 +67,13 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = {
*/
static struct pci_device_id ixgbe_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT),
- board_82598AF },
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
- board_82598AF },
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT_DUAL_PORT),
- board_82598AT },
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
- board_82598EB },
+ board_82598 },
/* required last entry */
{0, }
@@ -1571,8 +1569,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
dev_err(&pdev->dev, "HW Init failed\n");
return -EIO;
}
- if (hw->phy.ops.setup_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
- false)) {
+ if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
+ false)) {
dev_err(&pdev->dev, "Link Speed setup failed\n");
return -EIO;
}
@@ -2039,7 +2037,7 @@ static void ixgbe_watchdog(unsigned long data)
bool link_up;
u32 link_speed = 0;
- adapter->hw.phy.ops.check(&adapter->hw, &(link_speed), &link_up);
+ adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
if (link_up) {
if (!netif_carrier_ok(netdev)) {
@@ -2607,7 +2605,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* Setup hw api */
memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
- memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
err = ii->get_invariants(hw);
if (err)
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index 199e8f6..aa3ea72 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -31,7 +31,6 @@
#include "ixgbe_type.h"
-s32 ixgbe_init_shared_code_phy(struct ixgbe_hw *hw);
s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw);
s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index fdcde16..e60787a 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1244,13 +1244,16 @@ struct ixgbe_hw;
struct ixgbe_mac_operations {
s32 (*reset)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
+ s32 (*setup_link)(struct ixgbe_hw *);
+ s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
+ s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *);
};
struct ixgbe_phy_operations {
- s32 (*setup)(struct ixgbe_hw *);
- s32 (*check)(struct ixgbe_hw *, u32 *, bool *);
- s32 (*setup_speed)(struct ixgbe_hw *, u32, bool, bool);
- s32 (*get_settings)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link)(struct ixgbe_hw *);
+ s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
};
struct ixgbe_mac_info {
@@ -1267,7 +1270,6 @@ struct ixgbe_mac_info {
bool link_settings_loaded;
};
-
struct ixgbe_eeprom_info {
enum ixgbe_eeprom_type type;
u16 word_size;
@@ -1290,7 +1292,6 @@ struct ixgbe_info {
enum ixgbe_mac_type mac;
s32 (*get_invariants)(struct ixgbe_hw *);
struct ixgbe_mac_operations *mac_ops;
- struct ixgbe_phy_operations *phy_ops;
};
struct ixgbe_hw {
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-10-31 22:25 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-31 22:21 [PATCH 1/4] e1000e: alternate MAC address support Auke Kok
2007-10-31 22:22 ` [PATCH 2/4] e1000e: Disable L1 ASPM power savings for 82573 mobile variants Auke Kok
2007-10-31 22:22 ` [PATCH 3/4] e1000/e1000e: Move PCI-Express device IDs over to e1000e Auke Kok
2007-10-31 22:22 ` [PATCH 4/4] ixgbe: Fix copper PHY initialization code Auke Kok
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).