static void e1000_loopback_cleanup(struct e1000_adapter *adapter) { uint32_t rctl; uint16_t phy_reg; rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); E1000_WRITE_REG(&adapter->hw, RCTL, rctl); if(adapter->hw.media_type == e1000_media_type_copper || ((adapter->hw.media_type == e1000_media_type_fiber || adapter->hw.media_type == e1000_media_type_internal_serdes) && (adapter->hw.mac_type == e1000_82545 || adapter->hw.mac_type == e1000_82546 || adapter->hw.mac_type == e1000_82545_rev_3 || adapter->hw.mac_type == e1000_82546_rev_3))) { adapter->hw.autoneg = TRUE; e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); if(phy_reg & MII_CR_LOOPBACK) { phy_reg &= ~MII_CR_LOOPBACK; e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); e1000_phy_reset(&adapter->hw); } } }
/* * phy_dump - dump important phy registers */ void phy_dump(void *instance) { struct e1000g *Adapter = (struct e1000g *)instance; struct e1000_hw *hw = &Adapter->shared; /* offset to each phy register */ int32_t offset[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0x1796, 0x187A, 0x1895, 0x1F30, 0x1F35, 0x1F3E, 0x1F54, 0x1F55, 0x1F56, 0x1F72, 0x1F76, 0x1F77, 0x1F78, 0x1F79, 0x1F98, 0x2010, 0x2011, 0x20DC, 0x20DD, 0x20DE, 0x28B4, 0x2F52, 0x2F5B, 0x2F70, 0x2F90, 0x2FB1, 0x2FB2 }; uint16_t value; /* register value */ uint32_t stat; /* status from e1000_read_phy_reg */ int i; e1000g_log(Adapter, CE_CONT, "Begin PHY dump\n"); for (i = 0; i < ((sizeof (offset)) / sizeof (offset[0])); i++) { stat = e1000_read_phy_reg(hw, offset[i], &value); if (stat == 0) { e1000g_log(Adapter, CE_CONT, "phyreg offset: %d value: 0x%x\n", offset[i], value); } else { e1000g_log(Adapter, CE_WARN, "phyreg offset: %d ERROR: 0x%x\n", offset[i], stat); } } }
static void e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter) { uint16_t phy_reg; /* Because we reset the PHY above, we need to re-force TX_CLK in the * Extended PHY Specific Control Register to 25MHz clock. This * value defaults back to a 2.5MHz clock when the PHY is reset. */ e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); phy_reg |= M88E1000_EPSCR_TX_CLK_25; e1000_write_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_reg); /* 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. */ e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg); phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX; e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, phy_reg); }
static int e1000_set_phy_loopback(struct e1000_adapter *adapter) { uint16_t phy_reg = 0; uint16_t count = 0; switch (adapter->hw.mac_type) { case e1000_82543: if(adapter->hw.media_type == e1000_media_type_copper) { /* Attempt to setup Loopback mode on Non-integrated PHY. * Some PHY registers get corrupted at random, so * attempt this 10 times. */ while(e1000_nonintegrated_phy_loopback(adapter) && count++ < 10); if(count < 11) return 0; } break; case e1000_82544: case e1000_82540: case e1000_82545: case e1000_82545_rev_3: case e1000_82546: case e1000_82546_rev_3: case e1000_82541: case e1000_82541_rev_2: case e1000_82547: case e1000_82547_rev_2: return e1000_integrated_phy_loopback(adapter); break; default: /* Default PHY loopback work is to read the MII * control register and assert bit 14 (loopback mode). */ e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); phy_reg |= MII_CR_LOOPBACK; e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); return 0; break; } return 8; }
/* * phy_spd_state - set smart-power-down (SPD) state * * This only acts on the silicon families that have the SPD feature. * For any others, return without doing anything. */ void phy_spd_state(struct e1000_hw *hw, boolean_t enable) { int32_t offset; /* offset to register */ uint16_t spd_bit; /* bit to be set */ uint16_t reg; /* register contents */ switch (hw->mac.type) { case e1000_82541: case e1000_82547: case e1000_82541_rev_2: case e1000_82547_rev_2: offset = IGP01E1000_GMII_FIFO; spd_bit = IGP01E1000_GMII_SPD; break; case e1000_82571: case e1000_82572: case e1000_82573: case e1000_82574: case e1000_82583: offset = IGP02E1000_PHY_POWER_MGMT; spd_bit = IGP02E1000_PM_SPD; break; default: return; /* no action */ } (void) e1000_read_phy_reg(hw, offset, ®); if (enable) reg |= spd_bit; /* enable: set the spd bit */ else reg &= ~spd_bit; /* disable: clear the spd bit */ (void) e1000_write_phy_reg(hw, offset, reg); }
/* * e1000g_rx_setup - setup rx data structures * * This routine initializes all of the receive related * structures. This includes the receive descriptors, the * actual receive buffers, and the rx_sw_packet software * structures. */ void e1000g_rx_setup(struct e1000g *Adapter) { struct e1000_hw *hw; p_rx_sw_packet_t packet; struct e1000_rx_desc *descriptor; uint32_t buf_low; uint32_t buf_high; uint32_t reg_val; uint32_t rctl; uint32_t rxdctl; uint32_t ert; uint16_t phy_data; int i; int size; e1000g_rx_data_t *rx_data; hw = &Adapter->shared; rx_data = Adapter->rx_ring->rx_data; /* * zero out all of the receive buffer descriptor memory * assures any previous data or status is erased */ bzero(rx_data->rbd_area, sizeof (struct e1000_rx_desc) * Adapter->rx_desc_num); if (!Adapter->rx_buffer_setup) { /* Init the list of "Receive Buffer" */ QUEUE_INIT_LIST(&rx_data->recv_list); /* Init the list of "Free Receive Buffer" */ QUEUE_INIT_LIST(&rx_data->free_list); /* Init the list of "Free Receive Buffer" */ QUEUE_INIT_LIST(&rx_data->recycle_list); /* * Setup Receive list and the Free list. Note that * the both were allocated in one packet area. */ packet = rx_data->packet_area; descriptor = rx_data->rbd_first; for (i = 0; i < Adapter->rx_desc_num; i++, packet = packet->next, descriptor++) { ASSERT(packet != NULL); ASSERT(descriptor != NULL); descriptor->buffer_addr = packet->rx_buf->dma_address; /* Add this rx_sw_packet to the receive list */ QUEUE_PUSH_TAIL(&rx_data->recv_list, &packet->Link); } for (i = 0; i < Adapter->rx_freelist_num; i++, packet = packet->next) { ASSERT(packet != NULL); /* Add this rx_sw_packet to the free list */ QUEUE_PUSH_TAIL(&rx_data->free_list, &packet->Link); } rx_data->avail_freepkt = Adapter->rx_freelist_num; rx_data->recycle_freepkt = 0; Adapter->rx_buffer_setup = B_TRUE; } else { /* Setup the initial pointer to the first rx descriptor */ packet = (p_rx_sw_packet_t) QUEUE_GET_HEAD(&rx_data->recv_list); descriptor = rx_data->rbd_first; for (i = 0; i < Adapter->rx_desc_num; i++) { ASSERT(packet != NULL); ASSERT(descriptor != NULL); descriptor->buffer_addr = packet->rx_buf->dma_address; /* Get next rx_sw_packet */ packet = (p_rx_sw_packet_t) QUEUE_GET_NEXT(&rx_data->recv_list, &packet->Link); descriptor++; } } E1000_WRITE_REG(&Adapter->shared, E1000_RDTR, Adapter->rx_intr_delay); E1000G_DEBUGLOG_1(Adapter, E1000G_INFO_LEVEL, "E1000_RDTR: 0x%x\n", Adapter->rx_intr_delay); if (hw->mac.type >= e1000_82540) { E1000_WRITE_REG(&Adapter->shared, E1000_RADV, Adapter->rx_intr_abs_delay); E1000G_DEBUGLOG_1(Adapter, E1000G_INFO_LEVEL, "E1000_RADV: 0x%x\n", Adapter->rx_intr_abs_delay); } /* * Setup our descriptor pointers */ rx_data->rbd_next = rx_data->rbd_first; size = Adapter->rx_desc_num * sizeof (struct e1000_rx_desc); E1000_WRITE_REG(hw, E1000_RDLEN(0), size); size = E1000_READ_REG(hw, E1000_RDLEN(0)); /* To get lower order bits */ buf_low = (uint32_t)rx_data->rbd_dma_addr; /* To get the higher order bits */ buf_high = (uint32_t)(rx_data->rbd_dma_addr >> 32); E1000_WRITE_REG(hw, E1000_RDBAH(0), buf_high); E1000_WRITE_REG(hw, E1000_RDBAL(0), buf_low); /* * Setup our HW Rx Head & Tail descriptor pointers */ E1000_WRITE_REG(hw, E1000_RDT(0), (uint32_t)(rx_data->rbd_last - rx_data->rbd_first)); E1000_WRITE_REG(hw, E1000_RDH(0), 0); /* * Setup the Receive Control Register (RCTL), and ENABLE the * receiver. The initial configuration is to: Enable the receiver, * accept broadcasts, discard bad packets (and long packets), * disable VLAN filter checking, set the receive descriptor * minimum threshold size to 1/2, and the receive buffer size to * 2k. */ rctl = E1000_RCTL_EN | /* Enable Receive Unit */ E1000_RCTL_BAM | /* Accept Broadcast Packets */ E1000_RCTL_LPE | /* Large Packet Enable bit */ (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT) | E1000_RCTL_RDMTS_HALF | E1000_RCTL_LBM_NO; /* Loopback Mode = none */ if (Adapter->strip_crc) rctl |= E1000_RCTL_SECRC; /* Strip Ethernet CRC */ if (Adapter->mem_workaround_82546 && ((hw->mac.type == e1000_82545) || (hw->mac.type == e1000_82546) || (hw->mac.type == e1000_82546_rev_3))) { rctl |= E1000_RCTL_SZ_2048; } else { if ((Adapter->max_frame_size > FRAME_SIZE_UPTO_2K) && (Adapter->max_frame_size <= FRAME_SIZE_UPTO_4K)) rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX; else if ((Adapter->max_frame_size > FRAME_SIZE_UPTO_4K) && (Adapter->max_frame_size <= FRAME_SIZE_UPTO_8K)) rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX; else if ((Adapter->max_frame_size > FRAME_SIZE_UPTO_8K) && (Adapter->max_frame_size <= FRAME_SIZE_UPTO_16K)) rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX; else rctl |= E1000_RCTL_SZ_2048; } if (e1000_tbi_sbp_enabled_82543(hw)) rctl |= E1000_RCTL_SBP; /* * Enable Early Receive Threshold (ERT) on supported devices. * Only takes effect when packet size is equal or larger than the * specified value (in 8 byte units), e.g. using jumbo frames. */ if ((hw->mac.type == e1000_82573) || (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_ich9lan) || (hw->mac.type == e1000_ich10lan)) { ert = E1000_ERT_2048; /* * Special modification when ERT and * jumbo frames are enabled */ if (Adapter->default_mtu > ETHERMTU) { rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0)); E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 0x3); ert |= (1 << 13); } E1000_WRITE_REG(hw, E1000_ERT, ert); } /* Workaround errata on 82577/8 adapters with large frames */ if ((hw->mac.type == e1000_pchlan) && (Adapter->default_mtu > ETHERMTU)) { (void) e1000_read_phy_reg(hw, PHY_REG(770, 26), &phy_data); phy_data &= 0xfff8; phy_data |= (1 << 2); (void) e1000_write_phy_reg(hw, PHY_REG(770, 26), phy_data); if (hw->phy.type == e1000_phy_82577) { (void) e1000_read_phy_reg(hw, 22, &phy_data); phy_data &= 0x0fff; phy_data |= (1 << 14); (void) e1000_write_phy_reg(hw, 0x10, 0x2823); (void) e1000_write_phy_reg(hw, 0x11, 0x0003); (void) e1000_write_phy_reg(hw, 22, phy_data); } } reg_val = E1000_RXCSUM_TUOFL | /* TCP/UDP checksum offload Enable */ E1000_RXCSUM_IPOFL; /* IP checksum offload Enable */ E1000_WRITE_REG(hw, E1000_RXCSUM, reg_val); /* * Workaround: Set bit 16 (IPv6_ExDIS) to disable the * processing of received IPV6 extension headers */ if ((hw->mac.type == e1000_82571) || (hw->mac.type == e1000_82572)) { reg_val = E1000_READ_REG(hw, E1000_RFCTL); reg_val |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); E1000_WRITE_REG(hw, E1000_RFCTL, reg_val); } /* Write to enable the receive unit */ E1000_WRITE_REG(hw, E1000_RCTL, rctl); }
/** * e1000_reset - Put e1000 NIC in known initial state * * @v adapter e1000 private structure **/ static void e1000_reset ( struct e1000_adapter *adapter ) { uint32_t pba = 0; uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; DBG ( "e1000_reset\n" ); switch (adapter->hw.mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: case e1000_82543: case e1000_82544: case e1000_82540: case e1000_82541: case e1000_82541_rev_2: pba = E1000_PBA_48K; break; case e1000_82545: case e1000_82545_rev_3: case e1000_82546: case e1000_82546_rev_3: pba = E1000_PBA_48K; break; case e1000_82547: case e1000_82547_rev_2: pba = E1000_PBA_30K; break; case e1000_82571: case e1000_82572: case e1000_80003es2lan: pba = E1000_PBA_38K; break; case e1000_82573: pba = E1000_PBA_20K; break; case e1000_82576: pba = E1000_PBA_64K; break; case e1000_ich8lan: pba = E1000_PBA_8K; case e1000_undefined: case e1000_num_macs: break; } E1000_WRITE_REG ( &adapter->hw, PBA, pba ); /* flow control settings */ /* Set the FC high water mark to 90% of the FIFO size. * Required to clear last 3 LSB */ fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8; /* We can't use 90% on small FIFOs because the remainder * would be less than 1 full frame. In this case, we size * it to allow at least a full frame above the high water * mark. */ if (pba < E1000_PBA_16K) fc_high_water_mark = (pba * 1024) - 1600; /* This actually applies to < e1000_82575, one revision less than * e1000_82576, but e1000_82575 isn't currently defined in the code */ if (adapter->hw.mac_type < e1000_82576) { /* 8-byte granularity */ adapter->hw.fc_high_water = fc_high_water_mark & 0xFFF8; adapter->hw.fc_low_water = adapter->hw.fc_high_water - 8; } else { /* 16-byte granularity */ adapter->hw.fc_high_water = fc_high_water_mark & 0xFFF0; adapter->hw.fc_low_water = adapter->hw.fc_high_water - 16; } if (adapter->hw.mac_type == e1000_80003es2lan || adapter->hw.mac_type == e1000_82576) adapter->hw.fc_pause_time = 0xFFFF; else adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; adapter->hw.fc_send_xon = 1; adapter->hw.fc = adapter->hw.original_fc; /* Allow time for pending master requests to run */ e1000_reset_hw ( &adapter->hw ); if ( adapter->hw.mac_type >= e1000_82544 ) E1000_WRITE_REG ( &adapter->hw, WUC, 0 ); if ( e1000_init_hw ( &adapter->hw ) ) DBG ( "Hardware Error\n" ); /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */ if (adapter->hw.mac_type >= e1000_82544 && adapter->hw.mac_type <= e1000_82547_rev_2 && adapter->hw.autoneg == 1 && adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) { uint32_t ctrl = E1000_READ_REG(&adapter->hw, CTRL); /* clear phy power management bit if we are in gig only mode, * which if enabled will attempt negotiation to 100Mb, which * can cause a loss of link at power off or driver unload */ ctrl &= ~E1000_CTRL_SWDPIN3; E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); } e1000_phy_get_info ( &adapter->hw, &adapter->phy_info ); if (!adapter->smart_power_down && (adapter->hw.mac_type == e1000_82571 || adapter->hw.mac_type == e1000_82572)) { uint16_t phy_data = 0; /* speed up time to link by disabling smart power down, ignore * the return value of this function because there is nothing * different we would do if it failed */ e1000_read_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); phy_data &= ~IGP02E1000_PM_SPD; e1000_write_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT, phy_data); } }
static void e1000_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct e1000_adapter *adapter = netdev->priv; struct e1000_hw *hw = &adapter->hw; uint32_t *regs_buff = p; uint16_t phy_data; memset(p, 0, E1000_REGS_LEN * sizeof(uint32_t)); regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id; regs_buff[0] = E1000_READ_REG(hw, CTRL); regs_buff[1] = E1000_READ_REG(hw, STATUS); regs_buff[2] = E1000_READ_REG(hw, RCTL); regs_buff[3] = E1000_READ_REG(hw, RDLEN); regs_buff[4] = E1000_READ_REG(hw, RDH); regs_buff[5] = E1000_READ_REG(hw, RDT); regs_buff[6] = E1000_READ_REG(hw, RDTR); regs_buff[7] = E1000_READ_REG(hw, TCTL); regs_buff[8] = E1000_READ_REG(hw, TDLEN); regs_buff[9] = E1000_READ_REG(hw, TDH); regs_buff[10] = E1000_READ_REG(hw, TDT); regs_buff[11] = E1000_READ_REG(hw, TIDV); regs_buff[12] = adapter->hw.phy_type; /* PHY type (IGP=1, M88=0) */ if(hw->phy_type == e1000_phy_igp) { e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, IGP01E1000_PHY_AGC_A); e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_A & IGP01E1000_PHY_PAGE_SELECT, &phy_data); regs_buff[13] = (uint32_t)phy_data; /* cable length */ e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, IGP01E1000_PHY_AGC_B); e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_B & IGP01E1000_PHY_PAGE_SELECT, &phy_data); regs_buff[14] = (uint32_t)phy_data; /* cable length */ e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, IGP01E1000_PHY_AGC_C); e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_C & IGP01E1000_PHY_PAGE_SELECT, &phy_data); regs_buff[15] = (uint32_t)phy_data; /* cable length */ e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, IGP01E1000_PHY_AGC_D); e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_D & IGP01E1000_PHY_PAGE_SELECT, &phy_data); regs_buff[16] = (uint32_t)phy_data; /* cable length */ regs_buff[17] = 0; /* extended 10bt distance (not needed) */ e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0); e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS & IGP01E1000_PHY_PAGE_SELECT, &phy_data); regs_buff[18] = (uint32_t)phy_data; /* cable polarity */ e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, IGP01E1000_PHY_PCS_INIT_REG); e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG & IGP01E1000_PHY_PAGE_SELECT, &phy_data); regs_buff[19] = (uint32_t)phy_data; /* cable polarity */ regs_buff[20] = 0; /* polarity correction enabled (always) */ regs_buff[22] = 0; /* phy receive errors (unavailable) */ regs_buff[23] = regs_buff[18]; /* mdix mode */ e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0); } else { e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); regs_buff[13] = (uint32_t)phy_data; /* cable length */ regs_buff[14] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[15] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[16] = 0; /* Dummy (to align w/ IGP phy reg dump) */ e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); regs_buff[17] = (uint32_t)phy_data; /* extended 10bt distance */ regs_buff[18] = regs_buff[13]; /* cable polarity */ regs_buff[19] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[20] = regs_buff[17]; /* polarity correction */ /* phy receive errors */ regs_buff[22] = adapter->phy_stats.receive_errors; regs_buff[23] = regs_buff[13]; /* mdix mode */ } regs_buff[21] = adapter->phy_stats.idle_errors; /* phy idle errors */ e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */ regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ if(hw->mac_type >= e1000_82540 && hw->media_type == e1000_media_type_copper) { regs_buff[26] = E1000_READ_REG(hw, MANC); } }
static int e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter) { uint32_t ctrl_reg; uint16_t phy_reg; /* Setup the Device Control Register for PHY loopback test. */ ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); ctrl_reg |= (E1000_CTRL_ILOS | /* Invert Loss-Of-Signal */ E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ E1000_CTRL_SPD_1000 | /* Force Speed to 1000 */ E1000_CTRL_FD); /* Force Duplex to FULL */ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg); /* Read the PHY Specific Control Register (0x10) */ e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg); /* Clear Auto-Crossover bits in PHY Specific Control Register * (bits 6:5). */ phy_reg &= ~M88E1000_PSCR_AUTO_X_MODE; e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, phy_reg); /* Perform software reset on the PHY */ e1000_phy_reset(&adapter->hw); /* Have to setup TX_CLK and TX_CRS after software reset */ e1000_phy_reset_clk_and_crs(adapter); e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100); /* Wait for reset to complete. */ udelay(500); /* Have to setup TX_CLK and TX_CRS after software reset */ e1000_phy_reset_clk_and_crs(adapter); /* Write out to PHY registers 29 and 30 to disable the Receiver. */ e1000_phy_disable_receiver(adapter); /* Set the loopback bit in the PHY control register. */ e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); phy_reg |= MII_CR_LOOPBACK; e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); /* Setup TX_CLK and TX_CRS one more time. */ e1000_phy_reset_clk_and_crs(adapter); /* Check Phy Configuration */ e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); if(phy_reg != 0x4100) return 9; e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); if(phy_reg != 0x0070) return 10; e1000_read_phy_reg(&adapter->hw, 29, &phy_reg); if(phy_reg != 0x001A) return 11; return 0; }