e1000e fails probe
Subsystems (2)
Dear All:
I have a box where e1000e would refuse to probe the onboard interface with the following in dmesg:
e1000e: Intel(R) PRO/1000 Network Driver - 1.0.2-k2
e1000e: Copyright (c) 1999 - 2009 Intel Corporation. e1000e 0000:00:19.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20 e1000e 0000:00:19.0: setting latency timer to 64 e1000e 0000:00:19.0: irq 34 for MSI/MSI-X 0000:00:19.0: 0000:00:19.0: MDI Error
e1000e 0000:00:19.0: PCI INT A disabled
e1000e: probe of 0000:00:19.0 failed with error -2
The "MDI Error" seems to indicate a hardware failure, so I paid it no mind until I noticed that RHEL 5 works. So, I diffed the drivers between Linus' 2.6.34-rc5 and RHEL's 2.6.18-180.el5, with the following minimal patch working for me:
drivers/net/e1000e/ich8lan.c +168 -10
@@ -276,19 +276,21 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->id = e1000_phy_unknown; ret_val =e1000e_get_phy_id (hw); -if (ret_val) - goto out; -if ((phy->id ==0 ) || (phy->id ==PHY_REVISION_MASK )) { +/* P3 */ printk ("get_phy_id.fast ret %d id %d\n" , ret_val, phy->id); +if (ret_val || (phy->id ==0 ) || (phy->id ==PHY_REVISION_MASK )) {/* * In case the PHY needs to be in mdio slow mode (eg. 82577), * set slow mode and try to get the PHY id again. */ ret_val =e1000_set_mdio_slow_mode_hv (hw); -if (ret_val) - goto out; - ret_val =e1000e_get_phy_id (hw); -if (ret_val) - goto out; +if (ret_val) { +/* P3 */ printk ("failed to set mdio slow mode %d\n" , ret_val); + phy->id = e1000_phy_unknown; + }else { + ret_val =e1000e_get_phy_id (hw); +/* P3 */ printk ("get_phy_id.slow ret %d id %d\n" , ret_val, phy->id); + } + ret_val =0 ;/* P3 */ } phy->type =e1000e_get_phy_type_from_id (phy->id);
@@ -307,11 +309,10 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->ops.get_info = e1000e_get_phy_info_m88;break ;default : - ret_val = -E1000_ERR_PHY ; +/* P3 */ printk ("not doing anything for phy type %d\n" , phy->type);break ; } -out:return ret_val; }
@@ -354,7 +355,10 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)msleep (1 ); ret_val =e1000e_get_phy_id (hw);if (ret_val) +{ +/* P3 */ printk ("get_phy_id for params ret %d id %d\n" , ret_val, phy->id);return ret_val; +} }/* Verify phy id */
@@ -777,6 +781,77 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) }/** +* e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex +* @hw: pointer to the HW structure +* +* Forces the speed and duplex settings of the PHY. +* This is a function pointer entry point only called by +* PHY setup routines. +**/ +static s32 e1000_phy_force_speed_duplex_ich8lan (struct e1000_hw *hw) +{ +struct e1000_phy_info *phy = &hw->phy; +s32 ret_val; +u16 data; +bool link; + +if (phy->type != e1000_phy_ife) { + ret_val =e1000e_phy_force_speed_duplex_igp (hw); +return ret_val; + } + + ret_val =e1e_rphy (hw,PHY_CONTROL , &data); +if (ret_val) +return ret_val; + +e1000e_phy_force_speed_duplex_setup (hw, &data); + + ret_val =e1e_wphy (hw,PHY_CONTROL , data); +if (ret_val) +return ret_val; + +/* Disable MDI-X support for 10/100 */ + ret_val =e1e_rphy (hw,IFE_PHY_MDIX_CONTROL , &data); +if (ret_val) +return ret_val; + + data &= ~IFE_PMC_AUTO_MDIX ; + data &= ~IFE_PMC_FORCE_MDIX ; + + ret_val =e1e_wphy (hw,IFE_PHY_MDIX_CONTROL , data); +if (ret_val) +return ret_val; + +e_dbg ("IFE PMC: %X\n" , data); + +udelay (1 ); + +if (phy->autoneg_wait_to_complete) { +e_dbg ("Waiting for forced speed/duplex link on IFE phy.\n" ); + + ret_val =e1000e_phy_has_link_generic (hw, +PHY_FORCE_LIMIT , +100000 , + &link); +if (ret_val) +return ret_val; + +if (!link) +e_dbg ("Link taking longer than expected.\n" ); + +/* Try once more */ + ret_val =e1000e_phy_has_link_generic (hw, +PHY_FORCE_LIMIT , +100000 , + &link); +if (ret_val) +return ret_val; + } + +return 0 ; +} + +/** * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration * @hw: pointer to the HW structure *
@@ -1273,6 +1348,87 @@ out: }/** +* e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states +* @hw: pointer to the HW structure +* +* Populates "phy" structure with various feature states. +* This function is only called by other family-specific +* routines. +**/ +static s32 e1000_get_phy_info_ife_ich8lan (struct e1000_hw *hw) +{ +struct e1000_phy_info *phy = &hw->phy; +s32 ret_val; +u16 data; +bool link; + + ret_val =e1000e_phy_has_link_generic (hw,1 ,0 , &link); +if (ret_val) +return ret_val; + +if (!link) { +e_dbg ("Phy info is only valid if link is up\n" ); +return -E1000_ERR_CONFIG ; + } + + ret_val =e1e_rphy (hw,IFE_PHY_SPECIAL_CONTROL , &data); +if (ret_val) +return ret_val; + phy->polarity_correction = (!(data &IFE_PSC_AUTO_POLARITY_DISABLE )); + +if (phy->polarity_correction) { + ret_val = phy->ops.check_polarity (hw); +if (ret_val) +return ret_val; + }else { +/* Polarity is forced */ + phy->cable_polarity = (data &IFE_PSC_FORCE_POLARITY ) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; + } + + ret_val =e1e_rphy (hw,IFE_PHY_MDIX_CONTROL , &data); +if (ret_val) +return ret_val; + + phy->is_mdix = (data &IFE_PMC_MDIX_STATUS ); + +/* The following parameters are undefined for 10/100 operation. */ + phy->cable_length =E1000_CABLE_LENGTH_UNDEFINED ; + phy->local_rx = e1000_1000t_rx_status_undefined; + phy->remote_rx = e1000_1000t_rx_status_undefined; + +return 0 ; +} + +/** +* e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_info +* @hw: pointer to the HW structure +* +* Wrapper for calling the get_info routines for the appropriate phy type. +* This is a function pointer entry point called by drivers +* or other shared routines. +**/ +static s32 e1000_get_phy_info_ich8lan (struct e1000_hw *hw) +{ +switch (hw->phy.type) { +case e1000_phy_ife: +return e1000_get_phy_info_ife_ich8lan (hw); +break ; +case e1000_phy_igp_3: +case e1000_phy_bm: +case e1000_phy_82578: +case e1000_phy_82577: +return e1000e_get_phy_info_igp (hw); +break ; +default : +break ; + } + +return -E1000_ERR_PHY_TYPE ; +} + +/** * e1000_set_lplu_state_pchlan - Set Low Power Link Up state * @hw: pointer to the HW structure * @active: true to enable LPLU, false to disable
@@ -3394,8 +3550,10 @@ static struct e1000_phy_operations ich8_phy_ops = { .acquire = e1000_acquire_swflag_ich8lan, .check_reset_block = e1000_check_reset_block_ich8lan, .commit = NULL, + .force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan, .get_cfg_done = e1000_get_cfg_done_ich8lan, .get_cable_length = e1000e_get_cable_length_igp_2, + .get_info = e1000_get_phy_info_ich8lan, .read_reg = e1000e_read_phy_reg_igp, .release = e1000_release_swflag_ich8lan, .reset = e1000_phy_hw_reset_ich8lan,
What seems to be happening here is a persistent failure of e1000e_get_phy_id, in both "slow" and "fast" MDI modes. However, in RHEL 5, this failure triggers a chain of workaround and adjustments that bring up the interface with some default parameters... which appear to work with my 1Gbit/s Netgear switch. So the hardware is not dead, or not completely dead.
Could someone come up with a fix here, please? I have no clue where to start even.
Greetings,
-- Pete
Quoted 14 lines · Pete Zaitcev
Dear All:
I have a box where e1000e would refuse to probe the onboard interface with the following in dmesg:
e1000e: Intel(R) PRO/1000 Network Driver - 1.0.2-k2
e1000e: Copyright (c) 1999 - 2009 Intel Corporation. e1000e 0000:00:19.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20 e1000e 0000:00:19.0: setting latency timer to 64 e1000e 0000:00:19.0: irq 34 for MSI/MSI-X 0000:00:19.0: 0000:00:19.0: MDI Error
e1000e 0000:00:19.0: PCI INT A disabled
e1000e: probe of 0000:00:19.0 failed with error -2
Quoted 5 lines
The "MDI Error" seems to indicate a hardware failure, so I paid it no mind until I noticed that RHEL 5 works. So, I diffed the drivers between Linus' 2.6.34-rc5 and RHEL's 2.6.18-180.el5, with the following
minimal patch working for me:
Hi Pete,
Sorry you are having problems with e1000e. You didn't mention which LOM device was on this system - is the PCI device id 0x10ea, 0x10eb, 0x10ef or 0x10f0?
What BIOS version is on the system?
Would you be able to try a patch that is already in DaveM's net-next-2.6 tree? If so, it is http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=627c8a041f7aaaea93c766f69bd61d952a277586
Thanks,
Bruce.
Quoted 3 lines · Bruce W
Sorry you are having problems with e1000e. You didn't mention which LOM device was on this system - is the PCI device id
0x10ea,0x10eb,0x10efor0x10f0?
lspci -n says:
00:19.0 0200: 8086:10ef (rev 04)
Quoted 1 line
What BIOS version is on the system?
dmidecode says:
Vendor: American Megatrends Inc.
Version: 4.6.3
Release Date: 05/22/2009Quoted 3 lines
Would you be able to try a patch that is already in DaveM's net-next-2.6 tree? If so, it is
http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=627c8a041f7aaaea93c766f69bd61d952a277586
Thank you, this works. I guess I should've been more patient.
Yours,
-- Pete
Quoted 1 line · Bruce W
Would you be able to try a patch that is already in DaveM's net-next-2.6 tree? If so, it is http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=627c8a041f7aaaea93c766f69bd61d952a277586
I was too quick to claim victory here. I did an rmmod+insmod, it worked. Then I rebooted and it didn't. Weird...
-- Pete
Quoted 8 lines · Pete Zaitcev
Quoted 1 line · Bruce W
Would you be able to try a patch that is already in DaveM's net-next-2.6 tree? If so, it is http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=627c8a041f7aaaea93c766f69bd61d952a277586
I was too quick to claim victory here. I did an rmmod+insmod, it worked. Then I rebooted and it didn't. Weird...
That is exactly what I used to see on what I think is a similar system to Pete's. Pete and I have been talking and it looks like this system may need a BIOS update, so I'll see if we can work to get him an updated one.