patch-2.4.26 linux-2.4.26/drivers/net/e1000/e1000_hw.c
Next file: linux-2.4.26/drivers/net/e1000/e1000_hw.h
Previous file: linux-2.4.26/drivers/net/e1000/e1000_ethtool.c
Back to the patch index
Back to the overall index
- Lines: 213
- Date:
2004-04-14 06:05:30.000000000 -0700
- Orig file:
linux-2.4.25/drivers/net/e1000/e1000_hw.c
- Orig date:
2003-11-28 10:26:20.000000000 -0800
diff -urN linux-2.4.25/drivers/net/e1000/e1000_hw.c linux-2.4.26/drivers/net/e1000/e1000_hw.c
@@ -1,7 +1,7 @@
/*******************************************************************************
- Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+ Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@@ -96,8 +96,14 @@
hw->phy_type = e1000_phy_m88;
break;
case IGP01E1000_I_PHY_ID:
- hw->phy_type = e1000_phy_igp;
- break;
+ if(hw->mac_type == e1000_82541 ||
+ hw->mac_type == e1000_82541_rev_2 ||
+ hw->mac_type == e1000_82547 ||
+ hw->mac_type == e1000_82547_rev_2) {
+ hw->phy_type = e1000_phy_igp;
+ break;
+ }
+ /* Fall Through */
default:
/* Should never have loaded on this device */
hw->phy_type = e1000_phy_undefined;
@@ -148,7 +154,6 @@
e1000_write_phy_reg(hw, 0x0000, 0x3300);
-
if(hw->mac_type == e1000_82547) {
uint16_t fused, fine, coarse;
@@ -1485,8 +1490,8 @@
if(mii_status_reg & MII_SR_LINK_STATUS) break;
msec_delay(100);
}
- if(i == 0) { /* We didn't get link */
- /* Reset the DSP and wait again for link. */
+ if((i == 0) && (hw->phy_type == e1000_phy_m88)) {
+ /* We didn't get link. Reset the DSP and wait again for link. */
if((ret_val = e1000_phy_reset_dsp(hw))) {
DEBUGOUT("Error Resetting PHY DSP\n");
return ret_val;
@@ -1533,6 +1538,25 @@
phy_data)))
return ret_val;
+ /* Polarity reversal workaround for forced 10F/10H links. */
+ if(hw->mac_type <= e1000_82544 &&
+ (hw->forced_speed_duplex == e1000_10_full ||
+ hw->forced_speed_duplex == e1000_10_half)) {
+ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
+ 0x0019)))
+ return ret_val;
+ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
+ 0x8F0F)))
+ return ret_val;
+ /* IEEE requirement is 150ms */
+ msec_delay(200);
+ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
+ 0x0019)))
+ return ret_val;
+ if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
+ 0x8F00)))
+ return ret_val;
+ }
}
return E1000_SUCCESS;
}
@@ -1916,7 +1940,6 @@
uint32_t signal = 0;
int32_t ret_val;
uint16_t phy_data;
- uint16_t lp_capability;
DEBUGFUNC("e1000_check_for_link");
@@ -1996,24 +2019,17 @@
/* At this point we know that we are on copper and we have
* auto-negotiated link. These are conditions for checking the link
- * parter capability register. We use the link partner capability to
- * determine if TBI Compatibility needs to be turned on or off. If
- * the link partner advertises any speed in addition to Gigabit, then
- * we assume that they are GMII-based, and TBI compatibility is not
- * needed. If no other speeds are advertised, we assume the link
- * partner is TBI-based, and we turn on TBI Compatibility.
- */
- if(hw->tbi_compatibility_en) {
- if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
- &lp_capability)))
- return ret_val;
- if(lp_capability & (NWAY_LPAR_10T_HD_CAPS |
- NWAY_LPAR_10T_FD_CAPS |
- NWAY_LPAR_100TX_HD_CAPS |
- NWAY_LPAR_100TX_FD_CAPS |
- NWAY_LPAR_100T4_CAPS)) {
- /* If our link partner advertises anything in addition to
- * gigabit, we do not need to enable TBI compatibility.
+ * partner capability register. We use the link speed to determine if
+ * TBI compatibility needs to be turned on or off. If the link is not
+ * at gigabit speed, then TBI compatibility is not needed. If we are
+ * at gigabit speed, we turn on TBI compatibility.
+ */
+ if(hw->tbi_compatibility_en) {
+ uint16_t speed, duplex;
+ e1000_get_speed_and_duplex(hw, &speed, &duplex);
+ if(speed != SPEED_1000) {
+ /* If link speed is not set to gigabit speed, we do not need
+ * to enable TBI compatibility.
*/
if(hw->tbi_compatibility_on) {
/* If we previously were in the mode, turn it off. */
@@ -2081,6 +2097,29 @@
DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
E1000_WRITE_REG(hw, TXCW, hw->txcw);
E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
+
+ hw->serdes_link_down = FALSE;
+ }
+ /* If we force link for non-auto-negotiation switch, check link status
+ * based on MAC synchronization for internal serdes media type.
+ */
+ else if((hw->media_type == e1000_media_type_internal_serdes) &&
+ !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
+ /* SYNCH bit and IV bit are sticky. */
+ udelay(10);
+ if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
+ if(!(rxcw & E1000_RXCW_IV)) {
+ hw->serdes_link_down = FALSE;
+ DEBUGOUT("SERDES: Link is up.\n");
+ }
+ } else {
+ hw->serdes_link_down = TRUE;
+ DEBUGOUT("SERDES: Link is down.\n");
+ }
+ }
+ if((hw->media_type == e1000_media_type_internal_serdes) &&
+ (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
+ hw->serdes_link_down = !(E1000_STATUS_LU & E1000_READ_REG(hw, STATUS));
}
return E1000_SUCCESS;
}
@@ -3742,22 +3781,13 @@
e1000_init_rx_addrs(struct e1000_hw *hw)
{
uint32_t i;
- uint32_t addr_low;
- uint32_t addr_high;
DEBUGFUNC("e1000_init_rx_addrs");
/* Setup the receive address. */
DEBUGOUT("Programming MAC Address into RAR[0]\n");
- addr_low = (hw->mac_addr[0] |
- (hw->mac_addr[1] << 8) |
- (hw->mac_addr[2] << 16) | (hw->mac_addr[3] << 24));
-
- addr_high = (hw->mac_addr[4] |
- (hw->mac_addr[5] << 8) | E1000_RAH_AV);
- E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
- E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
+ e1000_rar_set(hw, hw->mac_addr, 0);
/* Zero out the other 15 receive addresses. */
DEBUGOUT("Clearing RAR[1-15]\n");
@@ -3774,6 +3804,7 @@
* mc_addr_list - the list of new multicast addresses
* mc_addr_count - number of addresses
* pad - number of bytes between addresses in the list
+ * rar_used_count - offset where to start adding mc addresses into the RAR's
*
* The given list replaces any existing list. Clears the last 15 receive
* address registers and the multicast table. Uses receive address registers
@@ -3784,11 +3815,11 @@
e1000_mc_addr_list_update(struct e1000_hw *hw,
uint8_t *mc_addr_list,
uint32_t mc_addr_count,
- uint32_t pad)
+ uint32_t pad,
+ uint32_t rar_used_count)
{
uint32_t hash_value;
uint32_t i;
- uint32_t rar_used_count = 1; /* RAR[0] is used for our MAC address */
DEBUGFUNC("e1000_mc_addr_list_update");
@@ -4522,8 +4553,8 @@
e1000_read_reg_io(struct e1000_hw *hw,
uint32_t offset)
{
- uint32_t io_addr = hw->io_base;
- uint32_t io_data = hw->io_base + 4;
+ unsigned long io_addr = hw->io_base;
+ unsigned long io_data = hw->io_base + 4;
e1000_io_write(hw, io_addr, offset);
return e1000_io_read(hw, io_data);
@@ -4542,8 +4573,8 @@
uint32_t offset,
uint32_t value)
{
- uint32_t io_addr = hw->io_base;
- uint32_t io_data = hw->io_base + 4;
+ unsigned long io_addr = hw->io_base;
+ unsigned long io_data = hw->io_base + 4;
e1000_io_write(hw, io_addr, offset);
e1000_io_write(hw, io_data, value);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)