[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: em(4) sync



On Sat, Oct 16, 2004 at 09:11:41PM -0400, Brad wrote:
> Markus commited this before release...
> 
> Added support for Intel PRO/1000 GT Desktop Adapter(Device ID 8086 107C)
> 
> My diff syncs in the other parts of the commit..
> 
> Removed support for Intel 82541ER.
> Added fix for 82547 which corrects an issue with Jumbo frames larger than 10k.
> Corrected TBI workaround.
> Corrected incorrect LED operation issues.
> 
> >From FreeBSD
> 
> 
> please try this out if you have any em(4) NICs.
 
I have had confirmation that removing the PCI id for the 82541ER was
a mistake made in FreeBSD. Unless you have an 82541ER then there has
been no other functional changes with this new diff over the previous
one.


Added fix for 82547 which corrects an issue with Jumbo frames larger than 10k.
Corrected TBI workaround.
Corrected incorrect LED operation issues.

>From FreeBSD

Index: dev/pci/if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.31
diff -u -p -r1.31 if_em.c
--- dev/pci/if_em.c	1 Oct 2004 19:08:04 -0000	1.31
+++ dev/pci/if_em.c	13 Nov 2004 14:09:17 -0000
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
 
 ***************************************************************************/
 
-/*$FreeBSD: if_em.c,v 1.38 2004/03/17 17:50:31 njl Exp $*/
+/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
 /* $OpenBSD: if_em.c,v 1.31 2004/10/01 19:08:04 grange Exp $ */
 
 #include "bpfilter.h"
@@ -91,7 +91,7 @@ struct em_softc *em_adapter_list = NULL;
  *  Driver version
  *********************************************************************/
 
-char em_driver_version[] = "1.7.25";
+char em_driver_version[] = "1.7.35";
 
 #ifdef __FreeBSD__
 /*********************************************************************
@@ -954,7 +954,7 @@ em_ioctl(struct ifnet *ifp, u_long comma
 		break;
 #endif /* __FreeBSD__ */
 	default:
-		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)\n", (int)command);
+		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)", (int)command);
 		error = EINVAL;
 	}
 
@@ -1009,6 +1009,8 @@ em_init_locked(struct em_softc *sc)
 {
 	struct ifnet   *ifp = &sc->interface_data.ac_if;
 
+	uint32_t	pba;
+
 	INIT_DEBUGOUT("em_init: begin");
 
         mtx_assert(&sc->mtx, MA_OWNED);
@@ -1023,6 +1025,35 @@ em_init_locked(struct em_softc *sc)
 		sc->num_rx_desc = EM_MIN_RXD;
 	}
 
+	/* Packet Buffer Allocation (PBA)
+	 * Writing PBA sets the receive portion of the buffer
+	 * the remainder is used for the transmit buffer.
+	 *
+	 * Devices before the 82547 had a Packet Buffer of 64K.
+	 *   Default allocation: PBA=48K for Rx, leaving 16K for Tx.
+	 * After the 82547 the buffer was reduced to 40K.
+	 *   Default allocation: PBA=30K for Rx, leaving 10K for Tx.
+	 *   Note: default does not leave enough room for Jumbo Frame >10k.
+	 */
+	if(sc->hw.mac_type < em_82547) {
+		/* Total FIFO is 64K */
+		if(sc->rx_buffer_len > EM_RXBUFFER_8192)
+			pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
+		else
+			pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */
+	} else {
+		/* Total FIFO is 40K */
+		if(sc->hw.max_frame_size > EM_RXBUFFER_8192) {
+			pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */
+		} else {
+		        pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */
+		}
+		sc->tx_fifo_head = 0;
+		sc->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT;
+		sc->tx_fifo_size = (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT;
+	}
+	INIT_DEBUGOUT1("em_init: pba=%dK",pba);
+	E1000_WRITE_REG(&sc->hw, PBA, pba);
 
 #ifdef __FreeBSD__
         /* Get the latest mac address, User can use a LAA */
@@ -1393,10 +1424,6 @@ em_tx_cb(void *arg, bus_dma_segment_t *s
 }
 #endif /* __FreeBSD__ */
 
-#define EM_FIFO_HDR		 0x10
-#define EM_82547_PKT_THRESH	 0x3e0
-#define EM_82547_TX_FIFO_SIZE	 0x2800
-#define EM_82547_TX_FIFO_BEGIN	 0xf00
 /*********************************************************************
  *
  *  This routine maps the mbufs to tx descriptors.
@@ -1607,7 +1634,7 @@ em_82547_move_tail_locked(struct em_soft
 
 		if(eop) {
 			if (em_82547_fifo_workaround(sc, length)) {
-				sc->tx_fifo_wrk++;
+				sc->tx_fifo_wrk_cnt++;
 #ifdef __FreeBSD__
                                 callout_reset(&sc->tx_fifo_timer, 1,
                                         em_82547_move_tail, sc);
@@ -1644,7 +1671,7 @@ em_82547_fifo_workaround(struct em_softc
 	fifo_pkt_len = EM_ROUNDUP(len + EM_FIFO_HDR, EM_FIFO_HDR);
 
 	if (sc->link_duplex == HALF_DUPLEX) {
-		fifo_space = EM_82547_TX_FIFO_SIZE - sc->tx_fifo_head;
+		fifo_space = sc->tx_fifo_size - sc->tx_fifo_head;
 
 		if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) {
 			if (em_82547_tx_fifo_reset(sc)) {
@@ -1666,8 +1693,8 @@ em_82547_update_fifo_head(struct em_soft
 
 	/* tx_fifo_head is always 16 byte aligned */
 	sc->tx_fifo_head += fifo_pkt_len;
-	if (sc->tx_fifo_head >= EM_82547_TX_FIFO_SIZE) {
-		sc->tx_fifo_head -= EM_82547_TX_FIFO_SIZE;
+	if (sc->tx_fifo_head >= sc->tx_fifo_size) {
+		sc->tx_fifo_head -= sc->tx_fifo_size;
 	}
 
 	return;
@@ -1692,17 +1719,17 @@ em_82547_tx_fifo_reset(struct em_softc *
 		E1000_WRITE_REG(&sc->hw, TCTL, tctl & ~E1000_TCTL_EN);
 
 		/* Reset FIFO pointers */
-		E1000_WRITE_REG(&sc->hw, TDFT, EM_82547_TX_FIFO_BEGIN);
-		E1000_WRITE_REG(&sc->hw, TDFH, EM_82547_TX_FIFO_BEGIN);
-		E1000_WRITE_REG(&sc->hw, TDFTS, EM_82547_TX_FIFO_BEGIN);
-		E1000_WRITE_REG(&sc->hw, TDFHS, EM_82547_TX_FIFO_BEGIN);
+		E1000_WRITE_REG(&sc->hw, TDFT, sc->tx_head_addr);
+		E1000_WRITE_REG(&sc->hw, TDFH, sc->tx_head_addr);
+		E1000_WRITE_REG(&sc->hw, TDFTS, sc->tx_head_addr);
+		E1000_WRITE_REG(&sc->hw, TDFHS, sc->tx_head_addr);
 
 		/* Re-enable TX unit */
 		E1000_WRITE_REG(&sc->hw, TCTL, tctl);
 		E1000_WRITE_FLUSH(&sc->hw);
 
 		sc->tx_fifo_head = 0;
-		sc->tx_fifo_reset++;
+		sc->tx_fifo_reset_cnt++;
 
 		return(TRUE);
 	}
@@ -1716,13 +1743,24 @@ em_set_promisc(struct em_softc * sc)
 {
 
 	u_int32_t	reg_rctl;
+	u_int32_t	ctrl;
 	struct ifnet   *ifp = &sc->interface_data.ac_if;
 
 	reg_rctl = E1000_READ_REG(&sc->hw, RCTL);
+	ctrl = E1000_READ_REG(&sc->hw, CTRL);
 
 	if (ifp->if_flags & IFF_PROMISC) {
 		reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 		E1000_WRITE_REG(&sc->hw, RCTL, reg_rctl);
+
+#if 0
+		/* Disable VLAN stripping in promiscous mode 
+		 * This enables bridging of vlan tagged frames to occur 
+		 * and also allows vlan tags to be seen in tcpdump
+		 */
+		ctrl &= ~E1000_CTRL_VME; 
+		E1000_WRITE_REG(&sc->hw, CTRL, ctrl);
+#endif
 	} else if (ifp->if_flags & IFF_ALLMULTI) {
 		reg_rctl |= E1000_RCTL_MPE;
 		reg_rctl &= ~E1000_RCTL_UPE;
@@ -1743,6 +1781,7 @@ em_disable_promisc(struct em_softc * sc)
 	reg_rctl &=  (~E1000_RCTL_MPE);
 	E1000_WRITE_REG(&sc->hw, RCTL, reg_rctl);
 
+	/* em_enable_vlans(sc); */
 	return;
 }
 
@@ -2681,7 +2720,7 @@ em_transmit_checksum_setup(struct em_sof
 		offsetof(struct udphdr, uh_sum);
 	}
 
-	TXD->tcp_seg_setup.data = htole32(0);
+	TXD->tcp_seg_setup.data = 0;
 	TXD->cmd_and_length = htole32(sc->txd_cmd | E1000_TXD_CMD_DEXT);
 
 	tx_buffer->m_head = NULL;
@@ -3624,7 +3663,7 @@ em_update_stats_counters(struct em_softc
 	sc->stats.rxerrc +
 	sc->stats.crcerrs +
 	sc->stats.algnerrc +
-	sc->stats.rlec + sc->stats.rnbc + 
+	sc->stats.rlec +
 	sc->stats.mpc + sc->stats.cexterr;
 
 	/* Tx Errors */
@@ -3647,6 +3686,10 @@ em_print_debug_info(struct em_softc *sc)
 	uint8_t *hw_addr = sc->hw.hw_addr;
 
         printf("%s: Adapter hardware address = %p \n", unit, hw_addr);
+	printf("%s:CTRL  = 0x%x\n", unit, 
+		E1000_READ_REG(&sc->hw, CTRL)); 
+	printf("%s:RCTL  = 0x%x PS=(0x8402)\n", unit, 
+		E1000_READ_REG(&sc->hw, RCTL));
         printf("%s:tx_int_delay = %d, tx_abs_int_delay = %d\n", unit,
               E1000_READ_REG(&sc->hw, TIDV),
               E1000_READ_REG(&sc->hw, TADV));
@@ -3661,8 +3704,8 @@ em_print_debug_info(struct em_softc *sc)
 	       sc->clean_tx_interrupts);
 #endif
 	printf("%s: fifo workaround = %lld, fifo_reset = %lld\n", unit,
-		(long long)sc->tx_fifo_wrk,
-		(long long)sc->tx_fifo_reset);
+		(long long)sc->tx_fifo_wrk_cnt,
+		(long long)sc->tx_fifo_reset_cnt);
 	printf("%s: hw tdh = %d, hw tdt = %d\n", unit,
 		E1000_READ_REG(&sc->hw, TDH),
 		E1000_READ_REG(&sc->hw, TDT));
Index: dev/pci/if_em.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.h,v
retrieving revision 1.7
diff -u -p -r1.7 if_em.h
--- dev/pci/if_em.h	18 Jun 2004 20:42:35 -0000	1.7
+++ dev/pci/if_em.h	13 Nov 2004 14:09:17 -0000
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
 
 ***************************************************************************/
 
-/*$FreeBSD: if_em.h,v 1.24 2003/11/14 18:02:24 pdeuskar Exp $*/
+/* $FreeBSD: if_em.h,v 1.26 2004/09/01 23:22:41 pdeuskar Exp $ */
 /* $OpenBSD: if_em.h,v 1.7 2004/06/18 20:42:35 mcbride Exp $ */
 
 #ifndef _EM_H_DEFINED_
@@ -387,8 +387,6 @@ struct em_softc {
 	struct mbuf        *fmp;
 	struct mbuf        *lmp;
 
-	u_int16_t          tx_fifo_head;
-
 #ifdef __FreeBSD__
         struct sysctl_ctx_list sysctl_ctx;
         struct sysctl_oid *sysctl_tree;
@@ -402,8 +400,21 @@ struct em_softc {
 	unsigned long   no_tx_desc_avail2;
 	unsigned long   no_tx_map_avail;
         unsigned long   no_tx_dma_setup;
-	u_int64_t       tx_fifo_reset;
-	u_int64_t       tx_fifo_wrk;
+
+	/* Used in for 82547 10Mb Half workaround */
+	#define EM_PBA_BYTES_SHIFT	0xA
+	#define EM_TX_HEAD_ADDR_SHIFT	7
+	#define EM_PBA_TX_MASK		0xFFFF0000
+	#define EM_FIFO_HDR              0x10
+
+	#define EM_82547_PKT_THRESH      0x3e0
+
+	u_int32_t       tx_fifo_size;
+	u_int32_t       tx_fifo_head;
+	u_int32_t       tx_fifo_head_addr;
+	u_int64_t       tx_fifo_reset_cnt;
+	u_int64_t       tx_fifo_wrk_cnt;
+	u_int32_t       tx_head_addr;
 
         /* For 82544 PCIX Workaround */
         boolean_t       pcix_82544;
Index: dev/pci/if_em_hw.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.c,v
retrieving revision 1.4
diff -u -p -r1.4 if_em_hw.c
--- dev/pci/if_em_hw.c	18 Apr 2004 04:15:00 -0000	1.4
+++ dev/pci/if_em_hw.c	13 Nov 2004 14:09:20 -0000
@@ -38,9 +38,9 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: if_em_hw.c,v 1.13 2004/02/10 21:31:09 pdeuskar Exp $");
+__FBSDID("$FreeBSD: if_em_hw.c,v 1.15 2004/09/23 22:57:53 cognet Exp $");
 #endif
- 
+
 #include "bpfilter.h"
 #include "vlan.h"
 
@@ -115,6 +115,7 @@ static void em_release_eeprom(struct em_
 static void em_standby_eeprom(struct em_hw *hw);
 static int32_t em_id_led_init(struct em_hw * hw);
 static int32_t em_set_vco_speed(struct em_hw *hw);
+static int32_t em_set_phy_mode(struct em_hw *hw);
 
 /* IGP cable length table */
 static const
@@ -300,6 +301,7 @@ em_set_mac_type(struct em_hw *hw)
         break;
     case E1000_DEV_ID_82541ER:
     case E1000_DEV_ID_82541GI:
+    case E1000_DEV_ID_82541GI_LF:
     case E1000_DEV_ID_82541GI_MOBILE:
         hw->mac_type = em_82541_rev_2;
         break;
@@ -417,7 +419,9 @@ em_reset_hw(struct em_hw *hw)
         case em_82544:
         case em_82540:
         case em_82545:
+#if defined(__FreeBSD__) && !defined(__arm__)
         case em_82546:
+#endif
         case em_82541:
         case em_82541_rev_2:
             /* These controllers can't ack the 64-bit write when issuing the
@@ -519,11 +523,11 @@ em_init_hw(struct em_hw *hw)
     uint16_t pcix_stat_hi_word;
     uint16_t cmd_mmrbc;
     uint16_t stat_mmrbc;
-
     DEBUGFUNC("em_init_hw");
 
     /* Initialize Identification LED */
-    if((ret_val = em_id_led_init(hw))) {
+    ret_val = em_id_led_init(hw);
+    if(ret_val) {
         DEBUGOUT("Error Initializing Identification LED\n");
         return ret_val;
     }
@@ -644,16 +648,16 @@ em_adjust_serdes_amplitude(struct em_hw 
         return E1000_SUCCESS;
     }
 
-    if ((ret_val = em_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
-                                     &eeprom_data))) {
+    ret_val = em_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1, &eeprom_data);
+    if (ret_val) {
         return ret_val;
     }
 
     if(eeprom_data != EEPROM_RESERVED_WORD) {
         /* Adjust SERDES output amplitude only. */
         eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK; 
-        if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
-                                          eeprom_data)))
+        ret_val = em_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
+        if(ret_val)
             return ret_val;
     }
 
@@ -802,14 +806,16 @@ em_setup_fiber_serdes_link(struct em_hw 
     if(hw->media_type == em_media_type_fiber)
         signal = (hw->mac_type > em_82544) ? E1000_CTRL_SWDPIN1 : 0;
 
-    if((ret_val = em_adjust_serdes_amplitude(hw)))
+    ret_val = em_adjust_serdes_amplitude(hw);
+    if(ret_val)
         return ret_val;
 
     /* Take the link out of reset */
     ctrl &= ~(E1000_CTRL_LRST);
 
     /* Adjust VCO speed to improve BER performance */
-    if((ret_val = em_set_vco_speed(hw)))
+    ret_val = em_set_vco_speed(hw);
+    if(ret_val)
         return ret_val;
 
     em_config_collision_dist(hw);
@@ -896,7 +902,8 @@ em_setup_fiber_serdes_link(struct em_hw 
              * we detect a signal. This will allow us to communicate with
              * non-autonegotiating link partners.
              */
-            if((ret_val = em_check_for_link(hw))) {
+            ret_val = em_check_for_link(hw);
+            if(ret_val) {
                 DEBUGOUT("Error while checking for link\n");
                 return ret_val;
             }
@@ -943,12 +950,25 @@ em_setup_copper_link(struct em_hw *hw)
     }
 
     /* Make sure we have a valid PHY */
-    if((ret_val = em_detect_gig_phy(hw))) {
+    ret_val = em_detect_gig_phy(hw);
+    if(ret_val) {
         DEBUGOUT("Error, did not detect valid phy.\n");
         return ret_val;
     }
     DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
 
+    /* Set PHY to class A mode (if necessary) */
+    ret_val = em_set_phy_mode(hw);
+    if(ret_val)
+        return ret_val;
+
+    if((hw->mac_type == em_82545_rev_3) ||
+       (hw->mac_type == em_82546_rev_3)) {
+        ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+        phy_data |= 0x00000008;
+        ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+    }
+
     if(hw->mac_type <= em_82543 ||
        hw->mac_type == em_82541 || hw->mac_type == em_82547 ||
        hw->mac_type == em_82541_rev_2 || hw->mac_type == em_82547_rev_2)
@@ -957,7 +977,8 @@ em_setup_copper_link(struct em_hw *hw)
     if(!hw->phy_reset_disable) {
         if (hw->phy_type == em_phy_igp) {
 
-            if((ret_val = em_phy_reset(hw))) {
+            ret_val = em_phy_reset(hw);
+            if(ret_val) {
                 DEBUGOUT("Error Resetting the PHY\n");
                 return ret_val;
             }
@@ -972,14 +993,16 @@ em_setup_copper_link(struct em_hw *hw)
             E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
 
             /* disable lplu d3 during driver init */
-            if((ret_val = em_set_d3_lplu_state(hw, FALSE))) {
+            ret_val = em_set_d3_lplu_state(hw, FALSE);
+            if(ret_val) {
                 DEBUGOUT("Error Disabling LPLU D3\n");
                 return ret_val;
             }
 
             /* Configure mdi-mdix settings */
-            if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-                                             &phy_data)))
+            ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                         &phy_data);
+            if(ret_val)
                 return ret_val;
 
             if((hw->mac_type == em_82541) || (hw->mac_type == em_82547)) {
@@ -1006,8 +1029,9 @@ em_setup_copper_link(struct em_hw *hw)
                     break;
                 }
             }
-            if((ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-                                              phy_data)))
+            ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                          phy_data);
+            if(ret_val)
                 return ret_val;
 
             /* set auto-master slave resolution settings */
@@ -1025,27 +1049,28 @@ em_setup_copper_link(struct em_hw *hw)
                  * resolution as hardware default. */
                 if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
                     /* Disable SmartSpeed */
-                    if((ret_val = em_read_phy_reg(hw,
-                                                    IGP01E1000_PHY_PORT_CONFIG,
-                                                    &phy_data)))
+                    ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                                 &phy_data);
+                    if(ret_val)
                         return ret_val;
                     phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-                    if((ret_val = em_write_phy_reg(hw,
-                                                     IGP01E1000_PHY_PORT_CONFIG,
-                                                     phy_data)))
+                    ret_val = em_write_phy_reg(hw,
+                                                  IGP01E1000_PHY_PORT_CONFIG,
+                                                  phy_data);
+                    if(ret_val)
                         return ret_val;
                     /* Set auto Master/Slave resolution process */
-                    if((ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL,
-                                                     &phy_data)))
+                    ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
+                    if(ret_val)
                         return ret_val;
                     phy_data &= ~CR_1000T_MS_ENABLE;
-                    if((ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL,
-                                                      phy_data)))
+                    ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
+                    if(ret_val)
                         return ret_val;
                 }
 
-                if((ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL,
-                                                 &phy_data)))
+                ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
+                if(ret_val)
                     return ret_val;
 
                 /* load defaults for future use */
@@ -1068,14 +1093,15 @@ em_setup_copper_link(struct em_hw *hw)
                 default:
                     break;
                 }
-                if((ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL,
-                                                  phy_data)))
+                ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
+                if(ret_val)
                     return ret_val;
             }
         } else {
             /* Enable CRS on TX. This must be set for half-duplex operation. */
-            if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-                                             &phy_data)))
+            ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                         &phy_data);
+            if(ret_val)
                 return ret_val;
 
             phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
@@ -1114,15 +1140,17 @@ em_setup_copper_link(struct em_hw *hw)
             phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
             if(hw->disable_polarity_correction == 1)
                 phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-            if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-                                              phy_data)))
+            ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                          phy_data);
+            if(ret_val)
                 return ret_val;
 
             /* Force TX_CLK in the Extended PHY Specific Control Register
              * to 25MHz clock.
              */
-            if((ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-                                             &phy_data)))
+            ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                         &phy_data);
+            if(ret_val)
                 return ret_val;
 
             phy_data |= M88E1000_EPSCR_TX_CLK_25;
@@ -1133,14 +1161,15 @@ em_setup_copper_link(struct em_hw *hw)
                               M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
                 phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
                              M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
-                if((ret_val = em_write_phy_reg(hw,
-                                                  M88E1000_EXT_PHY_SPEC_CTRL,
-                                                  phy_data)))
+                ret_val = em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                              phy_data);
+                if(ret_val)
                     return ret_val;
             }
 
             /* SW Reset the PHY so all changes take effect */
-            if((ret_val = em_phy_reset(hw))) {
+            ret_val = em_phy_reset(hw);
+            if(ret_val) {
                 DEBUGOUT("Error Resetting the PHY\n");
                 return ret_val;
             }
@@ -1174,7 +1203,8 @@ em_setup_copper_link(struct em_hw *hw)
                 hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
             DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
-            if((ret_val = em_phy_setup_autoneg(hw))) {
+            ret_val = em_phy_setup_autoneg(hw);
+            if(ret_val) {
                 DEBUGOUT("Error Setting up Auto-Negotiation\n");
                 return ret_val;
             }
@@ -1183,18 +1213,21 @@ em_setup_copper_link(struct em_hw *hw)
             /* Restart auto-negotiation by setting the Auto Neg Enable bit and
              * the Auto Neg Restart bit in the PHY control register.
              */
-            if((ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data)))
+            ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data);
+            if(ret_val)
                 return ret_val;
 
             phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
-            if((ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data)))
+            ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data);
+            if(ret_val)
                 return ret_val;
 
             /* Does the user want to wait for Auto-Neg to complete here, or
              * check at a later time (for example, callback routine).
              */
             if(hw->wait_autoneg_complete) {
-                if((ret_val = em_wait_autoneg(hw))) {
+                ret_val = em_wait_autoneg(hw);
+                if(ret_val) {
                     DEBUGOUT("Error while waiting for autoneg to complete\n");
                     return ret_val;
                 }
@@ -1202,7 +1235,8 @@ em_setup_copper_link(struct em_hw *hw)
             hw->get_link_status = TRUE;
         } else {
             DEBUGOUT("Forcing speed and duplex\n");
-            if((ret_val = em_phy_force_speed_duplex(hw))) {
+            ret_val = em_phy_force_speed_duplex(hw);
+            if(ret_val) {
                 DEBUGOUT("Error Forcing Speed and Duplex\n");
                 return ret_val;
             }
@@ -1213,9 +1247,11 @@ em_setup_copper_link(struct em_hw *hw)
      * valid.
      */
     for(i = 0; i < 10; i++) {
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
 
         if(phy_data & MII_SR_LINK_STATUS) {
@@ -1230,19 +1266,22 @@ em_setup_copper_link(struct em_hw *hw)
             if(hw->mac_type >= em_82544) {
                 em_config_collision_dist(hw);
             } else {
-                if((ret_val = em_config_mac_to_phy(hw))) {
+                ret_val = em_config_mac_to_phy(hw);
+                if(ret_val) {
                     DEBUGOUT("Error configuring MAC to PHY settings\n");
                     return ret_val;
                 }
             }
-            if((ret_val = em_config_fc_after_link_up(hw))) {
+            ret_val = em_config_fc_after_link_up(hw);
+            if(ret_val) {
                 DEBUGOUT("Error Configuring Flow Control\n");
                 return ret_val;
             }
             DEBUGOUT("Valid link established!!!\n");
 
             if(hw->phy_type == em_phy_igp) {
-                if((ret_val = em_config_dsp_after_link_change(hw, TRUE))) {
+                ret_val = em_config_dsp_after_link_change(hw, TRUE);
+                if(ret_val) {
                     DEBUGOUT("Error Configuring DSP after link up\n");
                     return ret_val;
                 }
@@ -1272,12 +1311,13 @@ em_phy_setup_autoneg(struct em_hw *hw)
     DEBUGFUNC("em_phy_setup_autoneg");
 
     /* Read the MII Auto-Neg Advertisement Register (Address 4). */
-    if((ret_val = em_read_phy_reg(hw, PHY_AUTONEG_ADV,
-                                     &mii_autoneg_adv_reg)))
+    ret_val = em_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
+    if(ret_val)
         return ret_val;
 
     /* Read the MII 1000Base-T Control Register (Address 9). */
-    if((ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg)))
+    ret_val = em_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
+    if(ret_val)
         return ret_val;
 
     /* Need to parse both autoneg_advertised and fc and set up
@@ -1384,13 +1424,14 @@ em_phy_setup_autoneg(struct em_hw *hw)
         return -E1000_ERR_CONFIG;
     }
 
-    if((ret_val = em_write_phy_reg(hw, PHY_AUTONEG_ADV,
-                                      mii_autoneg_adv_reg)))
+    ret_val = em_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
+    if(ret_val)
         return ret_val;
 
     DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
 
-    if((ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg)))
+    ret_val = em_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
+    if(ret_val)
         return ret_val;
 
     return E1000_SUCCESS;
@@ -1429,7 +1470,8 @@ em_phy_force_speed_duplex(struct em_hw *
     ctrl &= ~E1000_CTRL_ASDE;
 
     /* Read the MII Control Register. */
-    if((ret_val = em_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg)))
+    ret_val = em_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
+    if(ret_val)
         return ret_val;
 
     /* We need to disable autoneg in order to force link and duplex. */
@@ -1531,10 +1573,12 @@ em_phy_force_speed_duplex(struct em_hw *
             /* Read the MII Status Register and wait for Auto-Neg Complete bit
              * to be set.
              */
-            if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+            ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+            if(ret_val)
                 return ret_val;
 
-            if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+            ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+            if(ret_val)
                 return ret_val;
 
             if(mii_status_reg & MII_SR_LINK_STATUS) break;
@@ -1542,7 +1586,8 @@ em_phy_force_speed_duplex(struct em_hw *
         }
         if((i == 0) && (hw->phy_type == em_phy_m88)) {
             /* We didn't get link.  Reset the DSP and wait again for link. */
-            if((ret_val = em_phy_reset_dsp(hw))) {
+            ret_val = em_phy_reset_dsp(hw);
+            if(ret_val) {
                 DEBUGOUT("Error Resetting PHY DSP\n");
                 return ret_val;
             }
@@ -1554,10 +1599,12 @@ em_phy_force_speed_duplex(struct em_hw *
             /* Read the MII Status Register and wait for Auto-Neg Complete bit
              * to be set.
              */
-            if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+            ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+            if(ret_val)
                 return ret_val;
 
-            if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+            ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+            if(ret_val)
                 return ret_val;
         }
     }
@@ -1567,46 +1614,26 @@ em_phy_force_speed_duplex(struct em_hw *
          * Extended PHY Specific Control Register to 25MHz clock.  This value
          * defaults back to a 2.5MHz clock when the PHY is reset.
          */
-        if((ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
+        if(ret_val)
             return ret_val;
 
         phy_data |= M88E1000_EPSCR_TX_CLK_25;
-        if((ret_val = em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-                                          phy_data)))
+        ret_val = em_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
+        if(ret_val)
             return ret_val;
 
         /* In addition, because of the s/w reset above, we need to enable CRS on
          * TX.  This must be set for both full and half duplex operation.
          */
-        if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+        if(ret_val)
             return ret_val;
 
         phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-        if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-                                          phy_data)))
+        ret_val = em_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+        if(ret_val)
             return ret_val;
-
-        /* Polarity reversal workaround for forced 10F/10H links. */
-        if(hw->mac_type <= em_82544 &&
-           (hw->forced_speed_duplex == em_10_full ||
-            hw->forced_speed_duplex == em_10_half)) {
-            if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
-                                              0x0019)))
-                return ret_val;
-            if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
-                                              0x8F0F)))
-                return ret_val;
-            /* IEEE requirement is 150ms */
-            msec_delay(200);
-            if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
-                                              0x0019)))
-                return ret_val;
-            if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
-                                              0x8F00)))
-                return ret_val;
-        }
     }
     return E1000_SUCCESS;
 }
@@ -1664,8 +1691,9 @@ em_config_mac_to_phy(struct em_hw *hw)
      * registers depending on negotiated values.
      */
     if (hw->phy_type == em_phy_igp) {
-        if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                     &phy_data);
+        if(ret_val)
             return ret_val;
 
         if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
@@ -1683,8 +1711,9 @@ em_config_mac_to_phy(struct em_hw *hw)
                 IGP01E1000_PSSR_SPEED_100MBPS)
             ctrl |= E1000_CTRL_SPD_100;
     } else {
-        if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                     &phy_data);
+        if(ret_val)
             return ret_val;
 
         if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
@@ -1802,7 +1831,8 @@ em_config_fc_after_link_up(struct em_hw 
     if(((hw->media_type == em_media_type_fiber) && (hw->autoneg_failed)) ||
        ((hw->media_type == em_media_type_internal_serdes) && (hw->autoneg_failed)) ||
        ((hw->media_type == em_media_type_copper) && (!hw->autoneg))) {
-        if((ret_val = em_force_mac_fc(hw))) {
+        ret_val = em_force_mac_fc(hw);
+        if(ret_val) {
             DEBUGOUT("Error forcing flow control settings\n");
             return ret_val;
         }
@@ -1818,9 +1848,11 @@ em_config_fc_after_link_up(struct em_hw 
          * has completed.  We read this twice because this reg has
          * some "sticky" (latched) bits.
          */
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+        if(ret_val)
             return ret_val;
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+        if(ret_val)
             return ret_val;
 
         if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
@@ -1830,11 +1862,13 @@ em_config_fc_after_link_up(struct em_hw 
              * Register (Address 5) to determine how flow control was
              * negotiated.
              */
-            if((ret_val = em_read_phy_reg(hw, PHY_AUTONEG_ADV,
-                                             &mii_nway_adv_reg)))
+            ret_val = em_read_phy_reg(hw, PHY_AUTONEG_ADV,
+                                         &mii_nway_adv_reg);
+            if(ret_val)
                 return ret_val;
-            if((ret_val = em_read_phy_reg(hw, PHY_LP_ABILITY,
-                                             &mii_nway_lp_ability_reg)))
+            ret_val = em_read_phy_reg(hw, PHY_LP_ABILITY,
+                                         &mii_nway_lp_ability_reg);
+            if(ret_val)
                 return ret_val;
 
             /* Two bits in the Auto Negotiation Advertisement Register
@@ -1951,7 +1985,8 @@ em_config_fc_after_link_up(struct em_hw 
              * negotiated to HALF DUPLEX, flow control should not be
              * enabled per IEEE 802.3 spec.
              */
-            if((ret_val = em_get_speed_and_duplex(hw, &speed, &duplex))) {
+            ret_val = em_get_speed_and_duplex(hw, &speed, &duplex);
+            if(ret_val) {
                 DEBUGOUT("Error getting link speed and duplex\n");
                 return ret_val;
             }
@@ -1962,7 +1997,8 @@ em_config_fc_after_link_up(struct em_hw 
             /* Now we call a subroutine to actually force the MAC
              * controller to use the correct flow control settings.
              */
-            if((ret_val = em_force_mac_fc(hw))) {
+            ret_val = em_force_mac_fc(hw);
+            if(ret_val) {
                 DEBUGOUT("Error forcing flow control settings\n");
                 return ret_val;
             }
@@ -1983,7 +2019,7 @@ em_config_fc_after_link_up(struct em_hw 
 int32_t
 em_check_for_link(struct em_hw *hw)
 {
-    uint32_t rxcw;
+    uint32_t rxcw = 0;
     uint32_t ctrl;
     uint32_t status;
     uint32_t rctl;
@@ -1993,16 +2029,23 @@ em_check_for_link(struct em_hw *hw)
 
     DEBUGFUNC("em_check_for_link");
 
+    ctrl = E1000_READ_REG(hw, CTRL);
+    status = E1000_READ_REG(hw, STATUS);
+
     /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
      * set when the optics detect a signal. On older adapters, it will be
      * cleared when there is a signal.  This applies to fiber media only.
      */
-    if(hw->media_type == em_media_type_fiber)
-        signal = (hw->mac_type > em_82544) ? E1000_CTRL_SWDPIN1 : 0;
+    if((hw->media_type == em_media_type_fiber) ||
+       (hw->media_type == em_media_type_internal_serdes)) {
+        rxcw = E1000_READ_REG(hw, RXCW);
 
-    ctrl = E1000_READ_REG(hw, CTRL);
-    status = E1000_READ_REG(hw, STATUS);
-    rxcw = E1000_READ_REG(hw, RXCW);
+        if(hw->media_type == em_media_type_fiber) {
+            signal = (hw->mac_type > em_82544) ? E1000_CTRL_SWDPIN1 : 0;
+            if(status & E1000_STATUS_LU)
+                hw->get_link_status = FALSE;
+        }
+    }
 
     /* If we have a copper PHY then we only want to go out to the PHY
      * registers to see if Auto-Neg has completed and/or if our link
@@ -2016,9 +2059,11 @@ em_check_for_link(struct em_hw *hw)
          * of the PHY.
          * Read the register twice since the link bit is sticky.
          */
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
 
         if(phy_data & MII_SR_LINK_STATUS) {
@@ -2052,7 +2097,8 @@ em_check_for_link(struct em_hw *hw)
         if(hw->mac_type >= em_82544)
             em_config_collision_dist(hw);
         else {
-            if((ret_val = em_config_mac_to_phy(hw))) {
+            ret_val = em_config_mac_to_phy(hw);
+            if(ret_val) {
                 DEBUGOUT("Error configuring MAC to PHY settings\n");
                 return ret_val;
             }
@@ -2062,7 +2108,8 @@ em_check_for_link(struct em_hw *hw)
          * need to restore the desired flow control settings because we may
          * have had to re-autoneg with a different link partner.
          */
-        if((ret_val = em_config_fc_after_link_up(hw))) {
+        ret_val = em_config_fc_after_link_up(hw);
+        if(ret_val) {
             DEBUGOUT("Error configuring flow control\n");
             return ret_val;
         }
@@ -2074,7 +2121,7 @@ em_check_for_link(struct em_hw *hw)
          * 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) {
+	if(hw->tbi_compatibility_en) {
             uint16_t speed, duplex;
             em_get_speed_and_duplex(hw, &speed, &duplex);
             if(speed != SPEED_1000) {
@@ -2111,8 +2158,8 @@ em_check_for_link(struct em_hw *hw)
      * in. The autoneg_failed flag does this.
      */
     else if((((hw->media_type == em_media_type_fiber) &&
-            ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
-            (hw->media_type == em_media_type_internal_serdes)) &&
+              ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
+             (hw->media_type == em_media_type_internal_serdes)) &&
             (!(status & E1000_STATUS_LU)) &&
             (!(rxcw & E1000_RXCW_C))) {
         if(hw->autoneg_failed == 0) {
@@ -2130,7 +2177,8 @@ em_check_for_link(struct em_hw *hw)
         E1000_WRITE_REG(hw, CTRL, ctrl);
 
         /* Configure Flow Control after forcing link up. */
-        if((ret_val = em_config_fc_after_link_up(hw))) {
+        ret_val = em_config_fc_after_link_up(hw);
+        if(ret_val) {
             DEBUGOUT("Error configuring flow control\n");
             return ret_val;
         }
@@ -2142,8 +2190,7 @@ em_check_for_link(struct em_hw *hw)
      */
     else if(((hw->media_type == em_media_type_fiber) ||
              (hw->media_type == em_media_type_internal_serdes)) &&
-              (ctrl & E1000_CTRL_SLU) &&
-              (rxcw & E1000_RXCW_C)) {
+            (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
         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));
@@ -2223,13 +2270,15 @@ em_get_speed_and_duplex(struct em_hw *hw
      * match the duplex in the link partner's capabilities.
      */
     if(hw->phy_type == em_phy_igp && hw->speed_downgraded) {
-        if((ret_val = em_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
+        if(ret_val)
             return ret_val;
 
         if(!(phy_data & NWAY_ER_LP_NWAY_CAPS))
             *duplex = HALF_DUPLEX;
         else {
-            if((ret_val == em_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data)))
+            ret_val = em_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
+            if(ret_val)
                 return ret_val;
             if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
                (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
@@ -2260,9 +2309,11 @@ em_wait_autoneg(struct em_hw *hw)
         /* Read the MII Status Register and wait for Auto-Neg
          * Complete bit to be set.
          */
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
-        if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
         if(phy_data & MII_SR_AUTONEG_COMPLETE) {
             return E1000_SUCCESS;
@@ -2427,8 +2478,9 @@ em_read_phy_reg(struct em_hw *hw,
 
     if(hw->phy_type == em_phy_igp &&
        (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
-        if((ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
-                                             (uint16_t)reg_addr)))
+        ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                         (uint16_t)reg_addr);
+        if(ret_val)
             return ret_val;
     }
 
@@ -2530,8 +2582,9 @@ em_write_phy_reg(struct em_hw *hw,
 
     if(hw->phy_type == em_phy_igp &&
        (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
-        if((ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
-                                             (uint16_t)reg_addr)))
+        ret_val = em_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                         (uint16_t)reg_addr);
+        if(ret_val)
             return ret_val;
     }
 
@@ -2670,11 +2723,13 @@ em_phy_reset(struct em_hw *hw)
     DEBUGFUNC("em_phy_reset");
 
     if(hw->mac_type != em_82541_rev_2) {
-        if((ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_CTRL, &phy_data);
+        if(ret_val)
             return ret_val;
 
         phy_data |= MII_CR_RESET;
-        if((ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data)))
+        ret_val = em_write_phy_reg(hw, PHY_CTRL, phy_data);
+        if(ret_val)
             return ret_val;
 
         usec_delay(1);
@@ -2701,12 +2756,14 @@ em_detect_gig_phy(struct em_hw *hw)
     DEBUGFUNC("em_detect_gig_phy");
 
     /* Read the PHY ID Registers to identify which PHY is onboard. */
-    if((ret_val = em_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
+    ret_val = em_read_phy_reg(hw, PHY_ID1, &phy_id_high);
+    if(ret_val)
         return ret_val;
 
     hw->phy_id = (uint32_t) (phy_id_high << 16);
     usec_delay(20);
-    if((ret_val = em_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
+    ret_val = em_read_phy_reg(hw, PHY_ID2, &phy_id_low);
+    if(ret_val)
         return ret_val;
 
     hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
@@ -2758,9 +2815,12 @@ em_phy_reset_dsp(struct em_hw *hw)
     DEBUGFUNC("em_phy_reset_dsp");
 
     do {
-        if((ret_val = em_write_phy_reg(hw, 29, 0x001d))) break;
-        if((ret_val = em_write_phy_reg(hw, 30, 0x00c1))) break;
-        if((ret_val = em_write_phy_reg(hw, 30, 0x0000))) break;
+        ret_val = em_write_phy_reg(hw, 29, 0x001d);
+        if(ret_val) break;
+        ret_val = em_write_phy_reg(hw, 30, 0x00c1);
+        if(ret_val) break;
+        ret_val = em_write_phy_reg(hw, 30, 0x0000);
+        if(ret_val) break;
         ret_val = E1000_SUCCESS;
     } while(0);
 
@@ -2793,13 +2853,14 @@ em_phy_igp_get_info(struct em_hw *hw,
     phy_info->polarity_correction = em_polarity_reversal_enabled;
 
     /* Check polarity status */
-    if((ret_val = em_check_polarity(hw, &polarity)))
+    ret_val = em_check_polarity(hw, &polarity);
+    if(ret_val)
         return ret_val;
 
     phy_info->cable_polarity = polarity;
 
-    if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
-                                     &phy_data)))
+    ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
+    if(ret_val)
         return ret_val;
 
     phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
@@ -2808,7 +2869,8 @@ em_phy_igp_get_info(struct em_hw *hw,
     if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
        IGP01E1000_PSSR_SPEED_1000MBPS) {
         /* Local/Remote Receiver Information are only valid at 1000 Mbps */
-        if((ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
 
         phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
@@ -2817,7 +2879,8 @@ em_phy_igp_get_info(struct em_hw *hw,
                               SR_1000T_REMOTE_RX_STATUS_SHIFT;
 
         /* Get cable length */
-        if((ret_val = em_get_cable_length(hw, &min_length, &max_length)))
+        ret_val = em_get_cable_length(hw, &min_length, &max_length);
+        if(ret_val)
             return ret_val;
 
         /* transalte to old method */
@@ -2857,7 +2920,8 @@ em_phy_m88_get_info(struct em_hw *hw,
      * and it stored in the hw->speed_downgraded parameter. */
     phy_info->downshift = hw->speed_downgraded;
 
-    if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data)))
+    ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+    if(ret_val)
         return ret_val;
 
     phy_info->extended_10bt_distance =
@@ -2868,12 +2932,14 @@ em_phy_m88_get_info(struct em_hw *hw,
         M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
 
     /* Check polarity status */
-    if((ret_val = em_check_polarity(hw, &polarity)))
+    ret_val = em_check_polarity(hw, &polarity);
+    if(ret_val)
         return ret_val;
 
     phy_info->cable_polarity = polarity;
 
-    if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data)))
+    ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
+    if(ret_val)
         return ret_val;
 
     phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
@@ -2886,7 +2952,8 @@ em_phy_m88_get_info(struct em_hw *hw,
         phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
                                   M88E1000_PSSR_CABLE_LENGTH_SHIFT);
 
-        if((ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
+        ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
+        if(ret_val)
             return ret_val;
 
         phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
@@ -2928,10 +2995,12 @@ em_phy_get_info(struct em_hw *hw,
         return -E1000_ERR_CONFIG;
     }
 
-    if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+    ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+    if(ret_val)
         return ret_val;
 
-    if((ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+    ret_val = em_read_phy_reg(hw, PHY_STATUS, &phy_data);
+    if(ret_val)
         return ret_val;
 
     if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
@@ -3394,6 +3463,7 @@ em_spi_eeprom_ready(struct em_hw *hw)
         usec_delay(5);
         retry_count += 5;
 
+        em_standby_eeprom(hw);
     } while(retry_count < EEPROM_MAX_RETRY_SPI);
 
     /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
@@ -4162,12 +4232,14 @@ em_setup_led(struct em_hw *hw)
     case em_82541_rev_2:
     case em_82547_rev_2:
         /* Turn off PHY Smart Power Down (if enabled) */
-        if((ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
-                                         &hw->phy_spd_default)))
-            return ret_val;
-        if((ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
-                                          (uint16_t)(hw->phy_spd_default &
-                                          ~IGP01E1000_GMII_SPD))))
+        ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
+                                     &hw->phy_spd_default);
+        if(ret_val)
+            return ret_val;
+        ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
+                                      (uint16_t)(hw->phy_spd_default &
+                                      ~IGP01E1000_GMII_SPD));
+        if(ret_val)
             return ret_val;
         /* Fall Through */
     default:
@@ -4214,8 +4286,9 @@ em_cleanup_led(struct em_hw *hw)
     case em_82541_rev_2:
     case em_82547_rev_2:
         /* Turn on PHY Smart Power Down (if previously enabled) */
-        if((ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
-                                          hw->phy_spd_default)))
+        ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
+                                      hw->phy_spd_default);
+        if(ret_val)
             return ret_val;
         /* Fall Through */
     default:
@@ -4662,8 +4735,9 @@ em_get_cable_length(struct em_hw *hw,
 
     /* Use old method for Phy older than IGP */
     if(hw->phy_type == em_phy_m88) {
-        if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                     &phy_data);
+        if(ret_val)
             return ret_val;
 
         /* Convert the enum value to ranged values */
@@ -4702,7 +4776,8 @@ em_get_cable_length(struct em_hw *hw,
         /* Read the AGC registers for all channels */
         for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
 
-            if((ret_val = em_read_phy_reg(hw, agc_reg_array[i], &phy_data)))
+            ret_val = em_read_phy_reg(hw, agc_reg_array[i], &phy_data);
+            if(ret_val)
                 return ret_val;
 
             cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
@@ -4769,15 +4844,17 @@ em_check_polarity(struct em_hw *hw,
 
     if(hw->phy_type == em_phy_m88) {
         /* return the Polarity bit in the Status register. */
-        if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                     &phy_data);
+        if(ret_val)
             return ret_val;
         *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
                     M88E1000_PSSR_REV_POLARITY_SHIFT;
     } else if(hw->phy_type == em_phy_igp) {
         /* Read the Status register to check the speed */
-        if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                     &phy_data);
+        if(ret_val)
             return ret_val;
 
         /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
@@ -4786,8 +4863,9 @@ em_check_polarity(struct em_hw *hw,
            IGP01E1000_PSSR_SPEED_1000MBPS) {
 
             /* Read the GIG initialization PCS register (0x00B4) */
-            if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
-                                             &phy_data)))
+            ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
+                                         &phy_data);
+            if(ret_val)
                 return ret_val;
 
             /* Check the polarity bits */
@@ -4825,15 +4903,17 @@ em_check_downshift(struct em_hw *hw)
     DEBUGFUNC("em_check_downshift");
 
     if(hw->phy_type == em_phy_igp) {
-        if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
+                                     &phy_data);
+        if(ret_val)
             return ret_val;
 
         hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
     }
     else if(hw->phy_type == em_phy_m88) {
-        if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                     &phy_data);
+        if(ret_val)
             return ret_val;
 
         hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
@@ -4873,7 +4953,8 @@ em_config_dsp_after_link_change(struct e
         return E1000_SUCCESS;
 
     if(link_up) {
-        if((ret_val = em_get_speed_and_duplex(hw, &speed, &duplex))) {
+        ret_val = em_get_speed_and_duplex(hw, &speed, &duplex);
+        if(ret_val) {
             DEBUGOUT("Error getting link speed and duplex\n");
             return ret_val;
         }
@@ -4886,14 +4967,16 @@ em_config_dsp_after_link_change(struct e
                 min_length >= em_igp_cable_length_50) {
 
                 for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-                    if((ret_val = em_read_phy_reg(hw, dsp_reg_array[i],
-                                                     &phy_data)))
+                    ret_val = em_read_phy_reg(hw, dsp_reg_array[i],
+                                                 &phy_data);
+                    if(ret_val)
                         return ret_val;
 
                     phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
 
-                    if((ret_val = em_write_phy_reg(hw, dsp_reg_array[i],
-                                                      phy_data)))
+                    ret_val = em_write_phy_reg(hw, dsp_reg_array[i],
+                                                  phy_data);
+                    if(ret_val)
                         return ret_val;
                 }
                 hw->dsp_config_state = em_dsp_config_activated;
@@ -4906,23 +4989,26 @@ em_config_dsp_after_link_change(struct e
                 uint32_t idle_errs = 0;
 
                 /* clear previous idle error counts */
-                if((ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS,
-                                                 &phy_data)))
+                ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS,
+                                             &phy_data);
+                if(ret_val)
                     return ret_val;
 
                 for(i = 0; i < ffe_idle_err_timeout; i++) {
                     usec_delay(1000);
-                    if((ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS,
-                                                     &phy_data)))
+                    ret_val = em_read_phy_reg(hw, PHY_1000T_STATUS,
+                                                 &phy_data);
+                    if(ret_val)
                         return ret_val;
 
                     idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
                     if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
                         hw->ffe_config_state = em_ffe_config_active;
 
-                        if((ret_val = em_write_phy_reg(hw,
+                        ret_val = em_write_phy_reg(hw,
                                     IGP01E1000_PHY_DSP_FFE,
-                                    IGP01E1000_PHY_DSP_FFE_CM_CP)))
+                                    IGP01E1000_PHY_DSP_FFE_CM_CP);
+                        if(ret_val)
                             return ret_val;
                         break;
                     }
@@ -4934,43 +5020,87 @@ em_config_dsp_after_link_change(struct e
         }
     } else {
         if(hw->dsp_config_state == em_dsp_config_activated) {
-            if((ret_val = em_write_phy_reg(hw, 0x0000,
-                IGP01E1000_IEEE_FORCE_GIGA)))
+            ret_val = em_write_phy_reg(hw, 0x0000,
+                                          IGP01E1000_IEEE_FORCE_GIGA);
+            if(ret_val)
                 return ret_val;
             for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-                if((ret_val = em_read_phy_reg(hw, dsp_reg_array[i],
-                                                 &phy_data)))
+                ret_val = em_read_phy_reg(hw, dsp_reg_array[i], &phy_data);
+                if(ret_val)
                     return ret_val;
 
                 phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
                 phy_data |=  IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
 
-                if((ret_val = em_write_phy_reg(hw,dsp_reg_array[i],
-                                                  phy_data)))
+                ret_val = em_write_phy_reg(hw,dsp_reg_array[i], phy_data);
+                if(ret_val)
                     return ret_val;
             }
 
-            if((ret_val = em_write_phy_reg(hw, 0x0000,
-                                              IGP01E1000_IEEE_RESTART_AUTONEG)))
+            ret_val = em_write_phy_reg(hw, 0x0000,
+                                          IGP01E1000_IEEE_RESTART_AUTONEG);
+            if(ret_val)
                 return ret_val;
 
             hw->dsp_config_state = em_dsp_config_enabled;
         }
 
         if(hw->ffe_config_state == em_ffe_config_active) {
-            if((ret_val = em_write_phy_reg(hw, 0x0000,
-                                              IGP01E1000_IEEE_FORCE_GIGA)))
+            ret_val = em_write_phy_reg(hw, 0x0000,
+                                          IGP01E1000_IEEE_FORCE_GIGA);
+            if(ret_val)
                 return ret_val;
-            if((ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
-                                              IGP01E1000_PHY_DSP_FFE_DEFAULT)))
+            ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
+                                          IGP01E1000_PHY_DSP_FFE_DEFAULT);
+            if(ret_val)
+                return ret_val;
+
+            ret_val = em_write_phy_reg(hw, 0x0000,
+                                          IGP01E1000_IEEE_RESTART_AUTONEG);
+            if(ret_val)
                 return ret_val;
+            hw->ffe_config_state = em_ffe_config_enabled;
+        }
+    }
+    return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ * Set PHY to class A mode
+ * Assumes the following operations will follow to enable the new class mode.
+ *  1. Do a PHY soft reset
+ *  2. Restart auto-negotiation or force link.
+ *
+ * hw - Struct containing variables accessed by shared code
+ ****************************************************************************/
+static int32_t
+em_set_phy_mode(struct em_hw *hw)
+{
+    int32_t ret_val;
+    uint16_t eeprom_data;
+
+    DEBUGFUNC("em_set_phy_mode");
+
+    if((hw->mac_type == em_82545_rev_3) &&
+       (hw->media_type == em_media_type_copper)) {
+        ret_val = em_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1, &eeprom_data);
+        if(ret_val) {
+            return ret_val;
+        }
 
-            if((ret_val = em_write_phy_reg(hw, 0x0000,
-                                              IGP01E1000_IEEE_RESTART_AUTONEG)))
+        if((eeprom_data != EEPROM_RESERVED_WORD) &&
+           (eeprom_data & EEPROM_PHY_CLASS_A)) {
+            ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x000B);
+            if(ret_val)
+                return ret_val;
+            ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x8104);
+            if(ret_val)
                 return ret_val;
-        hw->ffe_config_state = em_ffe_config_enabled;
+
+            hw->phy_reset_disable = FALSE;
         }
     }
+
     return E1000_SUCCESS;
 }
 
@@ -5003,25 +5133,27 @@ em_set_d3_lplu_state(struct em_hw *hw,
     /* During driver activity LPLU should not be used or it will attain link
      * from the lowest speeds starting from 10Mbps. The capability is used for
      * Dx transitions and states */
-    if((ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data)))
+    ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
+    if(ret_val)
         return ret_val;
 
     if(!active) {
         phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
-        if((ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
+        ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
+        if(ret_val)
             return ret_val;
 
         /* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
          * Dx states where the power conservation is most important.  During
          * driver activity we should enable SmartSpeed, so performance is
          * maintained. */
-        if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+        if(ret_val)
             return ret_val;
 
         phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
-        if((ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-                                          phy_data)))
+        ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
+        if(ret_val)
             return ret_val;
 
     } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
@@ -5029,17 +5161,18 @@ em_set_d3_lplu_state(struct em_hw *hw,
               (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
 
         phy_data |= IGP01E1000_GMII_FLEX_SPD;
-        if((ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
+        ret_val = em_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
+        if(ret_val)
             return ret_val;
 
         /* When LPLU is enabled we should disable SmartSpeed */
-        if((ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-                                         &phy_data)))
+        ret_val = em_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+        if(ret_val)
             return ret_val;
 
         phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-        if((ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-                                          phy_data)))
+        ret_val = em_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
+        if(ret_val)
             return ret_val;
 
     }
@@ -5070,34 +5203,40 @@ em_set_vco_speed(struct em_hw *hw)
 
     /* Set PHY register 30, page 5, bit 8 to 0 */
 
-    if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
-                                     &default_page)))
+    ret_val = em_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
+    if(ret_val)
         return ret_val;
 
-    if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005)))
+    ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
+    if(ret_val)
         return ret_val;
 
-    if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
+    ret_val = em_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
+    if(ret_val)
         return ret_val;
 
     phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
-    if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
+    ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
+    if(ret_val)
         return ret_val;
 
     /* Set PHY register 30, page 4, bit 11 to 1 */
 
-    if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004)))
+    ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
+    if(ret_val)
         return ret_val;
 
-    if((ret_val = em_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
+    ret_val = em_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
+    if(ret_val)
         return ret_val;
 
     phy_data |= M88E1000_PHY_VCO_REG_BIT11;
-    if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
+    ret_val = em_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
+    if(ret_val)
         return ret_val;
 
-    if((ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
-                                      default_page)))
+    ret_val = em_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
+    if(ret_val)
         return ret_val;
 
     return E1000_SUCCESS;
Index: dev/pci/if_em_hw.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v
retrieving revision 1.5
diff -u -p -r1.5 if_em_hw.h
--- dev/pci/if_em_hw.h	18 Apr 2004 04:15:00 -0000	1.5
+++ dev/pci/if_em_hw.h	13 Nov 2004 14:09:21 -0000
@@ -31,7 +31,7 @@
 
 *******************************************************************************/
 
-/*$FreeBSD: if_em_hw.h,v 1.13 2004/02/10 21:31:09 pdeuskar Exp $*/
+/* $FreeBSD: if_em_hw.h,v 1.14 2004/09/01 23:22:41 pdeuskar Exp $ */
 /* $OpenBSD: if_em_hw.h,v 1.5 2004/04/18 04:15:00 henric Exp $ */
 /* if_em_hw.h
  * Structures, enums, and macros for the MAC
@@ -372,6 +372,7 @@ int32_t em_set_d3_lplu_state(struct em_h
 #define E1000_DEV_ID_82547GI             0x1075
 #define E1000_DEV_ID_82541GI             0x1076
 #define E1000_DEV_ID_82541GI_MOBILE      0x1077
+#define E1000_DEV_ID_82541GI_LF          0x107C
 #define E1000_DEV_ID_82546GB_COPPER      0x1079
 #define E1000_DEV_ID_82546GB_FIBER       0x107A
 #define E1000_DEV_ID_82546GB_SERDES      0x107B
@@ -385,6 +386,9 @@ int32_t em_set_d3_lplu_state(struct em_h
 
 #define E1000_82542_2_0_REV_ID 2
 #define E1000_82542_2_1_REV_ID 3
+#define E1000_REVISION_0       0
+#define E1000_REVISION_1       1
+#define E1000_REVISION_2       2
 
 #define SPEED_10    10
 #define SPEED_100   100
@@ -779,6 +783,7 @@ struct em_ffvt_entry {
 #define E1000_WUPL     0x05900  /* Wakeup Packet Length - RW */
 #define E1000_WUPM     0x05A00  /* Wakeup Packet Memory - RO A */
 #define E1000_FFLT     0x05F00  /* Flexible Filter Length Table - RW Array */
+#define E1000_HOST_IF  0x08800  /* Host Interface */
 #define E1000_FFMT     0x09000  /* Flexible Filter Mask Table - RW Array */
 #define E1000_FFVT     0x09800  /* Flexible Filter Value Table - RW Array */
 
@@ -915,6 +920,7 @@ struct em_ffvt_entry {
 #define E1000_82542_TDFT     0x08018
 #define E1000_82542_FFMT     E1000_FFMT
 #define E1000_82542_FFVT     E1000_FFVT
+#define E1000_82542_HOST_IF  E1000_HOST_IF
 
 /* Statistics counters collected by the MAC */
 struct em_hw_stats {
@@ -1450,6 +1456,10 @@ struct em_hw {
 #define E1000_MANC_TCO_RESET     0x00010000 /* TCO Reset Occurred */
 #define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
 #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
+#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000 /* Enable MAC address
+                                                    * filtering */
+#define E1000_MANC_EN_MNG2HOST   0x00200000 /* Enable MNG packets to host
+                                             * memory */
 #define E1000_MANC_SMB_REQ       0x01000000 /* SMBus Request */
 #define E1000_MANC_SMB_GNT       0x02000000 /* SMBus Grant */
 #define E1000_MANC_SMB_CLK_IN    0x04000000 /* SMBus Clock In */
@@ -1496,6 +1506,7 @@ struct em_hw {
 #define EEPROM_COMPAT                 0x0003
 #define EEPROM_ID_LED_SETTINGS        0x0004
 #define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude adjustment. */
+#define EEPROM_PHY_CLASS_WORD         0x0007
 #define EEPROM_INIT_CONTROL1_REG      0x000A
 #define EEPROM_INIT_CONTROL2_REG      0x000F
 #define EEPROM_INIT_CONTROL3_PORT_B   0x0014
@@ -1529,6 +1540,9 @@ struct em_hw {
 /* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
 #define EEPROM_SERDES_AMPLITUDE_MASK  0x000F
 
+/* Mask bit for PHY class in Word 7 of the EEPROM */
+#define EEPROM_PHY_CLASS_A   0x8000
+
 /* Mask bits for fields in Word 0x0a of the EEPROM */
 #define EEPROM_WORD0A_ILOS   0x0010
 #define EEPROM_WORD0A_SWDPIO 0x01E0
@@ -1556,7 +1570,7 @@ struct em_hw {
 #define PBA_SIZE 4
 
 /* Collision related configuration parameters */
-#define E1000_COLLISION_THRESHOLD       16
+#define E1000_COLLISION_THRESHOLD       15
 #define E1000_CT_SHIFT                  4
 #define E1000_COLLISION_DISTANCE        64
 #define E1000_FDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
@@ -2022,7 +2036,7 @@ struct em_hw {
 #define IGP01E1000_PSSR_MDIX_SHIFT             0x000B /* shift right 11 */
 
 /* IGP01E1000 Specific Port Control Register - R/W */
-#define IGP01E1000_PSCR_TP_LOOPBACK            0x0001
+#define IGP01E1000_PSCR_TP_LOOPBACK            0x0010
 #define IGP01E1000_PSCR_CORRECT_NC_SCMBLR      0x0200
 #define IGP01E1000_PSCR_TEN_CRS_SELECT         0x0400
 #define IGP01E1000_PSCR_FLIP_CHIP              0x0800
@@ -2032,16 +2046,18 @@ struct em_hw {
 /* IGP01E1000 Specific Port Link Health Register */
 #define IGP01E1000_PLHR_SS_DOWNGRADE           0x8000
 #define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR    0x4000
+#define IGP01E1000_PLHR_MASTER_FAULT           0x2000
+#define IGP01E1000_PLHR_MASTER_RESOLUTION      0x1000
 #define IGP01E1000_PLHR_GIG_REM_RCVR_NOK       0x0800 /* LH */
 #define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW   0x0400 /* LH */
 #define IGP01E1000_PLHR_DATA_ERR_1             0x0200 /* LH */
 #define IGP01E1000_PLHR_DATA_ERR_0             0x0100
-#define IGP01E1000_PLHR_AUTONEG_FAULT          0x0010
-#define IGP01E1000_PLHR_AUTONEG_ACTIVE         0x0008
-#define IGP01E1000_PLHR_VALID_CHANNEL_D        0x0004
-#define IGP01E1000_PLHR_VALID_CHANNEL_C        0x0002
-#define IGP01E1000_PLHR_VALID_CHANNEL_B        0x0001
-#define IGP01E1000_PLHR_VALID_CHANNEL_A        0x0000
+#define IGP01E1000_PLHR_AUTONEG_FAULT          0x0040
+#define IGP01E1000_PLHR_AUTONEG_ACTIVE         0x0010
+#define IGP01E1000_PLHR_VALID_CHANNEL_D        0x0008
+#define IGP01E1000_PLHR_VALID_CHANNEL_C        0x0004
+#define IGP01E1000_PLHR_VALID_CHANNEL_B        0x0002
+#define IGP01E1000_PLHR_VALID_CHANNEL_A        0x0001
 
 /* IGP01E1000 Channel Quality Register */
 #define IGP01E1000_MSE_CHANNEL_D        0x000F



Visit your host, monkey.org