if (offset > MAX_PHY_REG_ADDRESS) {
hw_dbg("PHY Address %d is out of range\n", offset);
ret_val = -E1000_ERR_PARAM; goto out;
}
/* Set up Op-code, Phy Address, and register offset in the MDI *Controlregister.TheMACwilltakecareofinterfacingwiththe *PHYtoretrievethedesireddata.
*/
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
(phy->addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_READ));
wr32(E1000_MDIC, mdic);
/* Poll the ready bit to see if the MDI read completed *Increasingthetimeoutastestingshowedfailureswith *thelowertimeout
*/ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
udelay(50);
mdic = rd32(E1000_MDIC); if (mdic & E1000_MDIC_READY) break;
} if (!(mdic & E1000_MDIC_READY)) {
hw_dbg("MDI Read did not complete\n");
ret_val = -E1000_ERR_PHY; goto out;
} if (mdic & E1000_MDIC_ERROR) {
hw_dbg("MDI Error\n");
ret_val = -E1000_ERR_PHY; goto out;
}
*data = (u16) mdic;
if (offset > MAX_PHY_REG_ADDRESS) {
hw_dbg("PHY Address %d is out of range\n", offset);
ret_val = -E1000_ERR_PARAM; goto out;
}
/* Set up Op-code, Phy Address, and register offset in the MDI *Controlregister.TheMACwilltakecareofinterfacingwiththe *PHYtoretrievethedesireddata.
*/
mdic = (((u32)data) |
(offset << E1000_MDIC_REG_SHIFT) |
(phy->addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_WRITE));
wr32(E1000_MDIC, mdic);
/* Poll the ready bit to see if the MDI read completed *Increasingthetimeoutastestingshowedfailureswith *thelowertimeout
*/ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
udelay(50);
mdic = rd32(E1000_MDIC); if (mdic & E1000_MDIC_READY) break;
} if (!(mdic & E1000_MDIC_READY)) {
hw_dbg("MDI Write did not complete\n");
ret_val = -E1000_ERR_PHY; goto out;
} if (mdic & E1000_MDIC_ERROR) {
hw_dbg("MDI Error\n");
ret_val = -E1000_ERR_PHY; goto out;
}
/* Set up Op-code, Phy Address, and register address in the I2CCMD *register.TheMACwilltakecareofinterfacingwiththe *PHYtoretrievethedesireddata.
*/
i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
(phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
(E1000_I2CCMD_OPCODE_READ));
wr32(E1000_I2CCMD, i2ccmd);
/* Poll the ready bit to see if the I2C read completed */ for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
udelay(50);
i2ccmd = rd32(E1000_I2CCMD); if (i2ccmd & E1000_I2CCMD_READY) break;
} if (!(i2ccmd & E1000_I2CCMD_READY)) {
hw_dbg("I2CCMD Read did not complete\n"); return -E1000_ERR_PHY;
} if (i2ccmd & E1000_I2CCMD_ERROR) {
hw_dbg("I2CCMD Error bit set\n"); return -E1000_ERR_PHY;
}
/* Need to byte-swap the 16-bit value. */
*data = ((i2ccmd >> 8) & 0x00FF) | FIELD_PREP(0xFF00, i2ccmd);
/* Prevent overwriting SFP I2C EEPROM which is at A0 address.*/ if ((hw->phy.addr == 0) || (hw->phy.addr > 7)) {
hw_dbg("PHY I2C Address %d is out of range.\n",
hw->phy.addr); return -E1000_ERR_CONFIG;
}
/* Swap the data bytes for the I2C interface */
phy_data_swapped = ((data >> 8) & 0x00FF) | FIELD_PREP(0xFF00, data);
/* Set up Op-code, Phy Address, and register address in the I2CCMD *register.TheMACwilltakecareofinterfacingwiththe *PHYtoretrievethedesireddata.
*/
i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
(phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
E1000_I2CCMD_OPCODE_WRITE |
phy_data_swapped);
wr32(E1000_I2CCMD, i2ccmd);
/* Poll the ready bit to see if the I2C read completed */ for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
udelay(50);
i2ccmd = rd32(E1000_I2CCMD); if (i2ccmd & E1000_I2CCMD_READY) break;
} if (!(i2ccmd & E1000_I2CCMD_READY)) {
hw_dbg("I2CCMD Write did not complete\n"); return -E1000_ERR_PHY;
} if (i2ccmd & E1000_I2CCMD_ERROR) {
hw_dbg("I2CCMD Error bit set\n"); return -E1000_ERR_PHY;
}
/* Set up Op-code, EEPROM Address,in the I2CCMD *register.TheMACwilltakecareofinterfacingwiththe *EEPROMtoretrievethedesireddata.
*/
i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
E1000_I2CCMD_OPCODE_READ);
wr32(E1000_I2CCMD, i2ccmd);
/* Poll the ready bit to see if the I2C read completed */ for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
udelay(50);
data_local = rd32(E1000_I2CCMD); if (data_local & E1000_I2CCMD_READY) break;
} if (!(data_local & E1000_I2CCMD_READY)) {
hw_dbg("I2CCMD Read did not complete\n"); return -E1000_ERR_PHY;
} if (data_local & E1000_I2CCMD_ERROR) {
hw_dbg("I2CCMD Error bit set\n"); return -E1000_ERR_PHY;
}
*data = (u8) data_local & 0xFF;
if (phy->reset_disable) {
ret_val = 0; goto out;
}
/* Enable CRS on TX. This must be set for half-duplex operation. */
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out;
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) goto out;
if (phy->revision < E1000_REVISION_4) { /* Force TX_CLK in the Extended PHY Specific Control Register *to25MHzclock.
*/
ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
&phy_data); if (ret_val) goto out;
phy_data |= M88E1000_EPSCR_TX_CLK_25;
if ((phy->revision == E1000_REVISION_2) &&
(phy->id == M88E1111_I_PHY_ID)) { /* 82573L PHY - set the downshift counter to 5x. */
phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
} else { /* Configure Master and Slave downshift values */
phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
}
ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
phy_data); if (ret_val) goto out;
}
/* Commit the changes. */
ret_val = igb_phy_sw_reset(hw); if (ret_val) {
hw_dbg("Error committing the PHY changes\n"); goto out;
}
/* Enable CRS on Tx. This must be set for half-duplex operation. */
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) return ret_val;
switch (phy->mdix) { case1:
data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; break; case2:
data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; break; case0: default:
data |= IGP01E1000_PSCR_AUTO_MDIX; break;
}
ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data); if (ret_val) goto out;
/* set auto-master slave resolution settings */ if (hw->mac.autoneg) { /* when autonegotiation advertisement is only 1000Mbps then we *shoulddisableSmartSpeedandenableAutoMasterSlave *resolutionashardwaredefault.
*/ if (phy->autoneg_advertised == ADVERTISE_1000_FULL) { /* Disable SmartSpeed */
ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data); if (ret_val) goto out;
/* Set auto Master/Slave resolution process */
ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); if (ret_val) goto out;
data &= ~CR_1000T_MS_ENABLE;
ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); if (ret_val) goto out;
}
ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); if (ret_val) goto out;
switch (phy->ms_type) { case e1000_ms_force_master:
data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); break; case e1000_ms_force_slave:
data |= CR_1000T_MS_ENABLE;
data &= ~(CR_1000T_MS_VALUE); break; case e1000_ms_auto:
data &= ~CR_1000T_MS_ENABLE; break; default: break;
}
ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); if (ret_val) goto out;
}
/* Perform some bounds checking on the autoneg advertisement *parameter.
*/
phy->autoneg_advertised &= phy->autoneg_mask;
/* If autoneg_advertised is zero, we assume it was not defaulted *bythecallingcodesowesettoadvertisefullcapability.
*/ if (phy->autoneg_advertised == 0)
phy->autoneg_advertised = phy->autoneg_mask;
hw_dbg("Reconfiguring auto-neg advertisement params\n");
ret_val = igb_phy_setup_autoneg(hw); if (ret_val) {
hw_dbg("Error Setting up Auto-Negotiation\n"); goto out;
}
hw_dbg("Restarting Auto-Neg\n");
/* Restart auto-negotiation by setting the Auto Neg Enable bit and *theAutoNegRestartbitinthePHYcontrolregister.
*/
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); if (ret_val) goto out;
/* Does the user want to wait for Auto-Neg to complete here, or *checkatalatertime(forexample,callbackroutine).
*/ if (phy->autoneg_wait_to_complete) {
ret_val = igb_wait_autoneg(hw); if (ret_val) {
hw_dbg("Error while waiting for autoneg to complete\n"); goto out;
}
}
/* Read the MII Auto-Neg Advertisement Register (Address 4). */
ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); if (ret_val) goto out;
if (phy->autoneg_mask & ADVERTISE_1000_FULL) { /* Read the MII 1000Base-T Control Register (Address 9). */
ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
&mii_1000t_ctrl_reg); if (ret_val) goto out;
}
/* Need to parse both autoneg_advertised and fc and set up *theappropriatePHYregisters.Firstwewillparsefor *autoneg_advertisedsoftwareoverride.Sincewecanadvertise *aplethoraofcombinations,weneedtocheckeachbit *individually.
*/
/* First we clear all the 10/100 mb speed bits in the Auto-Neg *AdvertisementRegister(Address4)andthe1000mbspeedbitsin *the1000Base-TControlRegister(Address9).
*/
mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
NWAY_AR_100TX_HD_CAPS |
NWAY_AR_10T_FD_CAPS |
NWAY_AR_10T_HD_CAPS);
mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
/* Do we want to advertise 10 Mb Half Duplex? */ if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
hw_dbg("Advertise 10mb Half duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
}
/* Do we want to advertise 10 Mb Full Duplex? */ if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
hw_dbg("Advertise 10mb Full duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
}
/* Do we want to advertise 100 Mb Half Duplex? */ if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
hw_dbg("Advertise 100mb Half duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
}
/* Do we want to advertise 100 Mb Full Duplex? */ if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
hw_dbg("Advertise 100mb Full duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
}
/* We do not allow the Phy to advertise 1000 Mb Half Duplex */ if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
hw_dbg("Advertise 1000mb Half duplex request denied!\n");
/* Do we want to advertise 1000 Mb Full Duplex? */ if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
hw_dbg("Advertise 1000mb Full duplex\n");
mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
}
/* Check for a software override of the flow control settings, and *setupthePHYadvertisementregistersaccordingly.If *auto-negotiationisenabled,thensoftwarewillhavetosetthe *"PAUSE"bitstothecorrectvalueintheAuto-Negotiation *AdvertisementRegister(PHY_AUTONEG_ADV)andre-startauto- *negotiation. * *Thepossiblevaluesofthe"fc"parameterare: *0:Flowcontroliscompletelydisabled *1:Rxflowcontrolisenabled(wecanreceivepauseframes *butnotsendpauseframes). *2:Txflowcontrolisenabled(wecansendpauseframes *butwedonotsupportreceivingpauseframes). *3:BothRxandTXflowcontrol(symmetric)areenabled. *other:Nosoftwareoverride.Theflowcontrolconfiguration *intheEEPROMisused.
*/ switch (hw->fc.current_mode) { case e1000_fc_none: /* Flow control (RX & TX) is completely disabled by a *softwareover-ride.
*/
mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); break; case e1000_fc_rx_pause: /* RX Flow control is enabled, and TX Flow control is *disabled,byasoftwareover-ride. * *Sincetherereallyisn'tawaytoadvertisethatweare *capableofRXPauseONLY,wewilladvertisethatwe *supportbothsymmetricandasymmetricRXPAUSE.Later *(ine1000_config_fc_after_link_up)wewilldisablethe *hw'sabilitytosendPAUSEframes.
*/
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); break; case e1000_fc_tx_pause: /* TX Flow control is enabled, and RX Flow control is *disabled,byasoftwareover-ride.
*/
mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE; break; case e1000_fc_full: /* Flow control (both RX and TX) is enabled by a software *over-ride.
*/
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); break; default:
hw_dbg("Flow control param set incorrectly\n");
ret_val = -E1000_ERR_CONFIG; goto out;
}
ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); if (ret_val) goto out;
if (hw->mac.autoneg) { /* Setup autoneg and flow control advertisement and perform *autonegotiation.
*/
ret_val = igb_copper_link_autoneg(hw); if (ret_val) goto out;
} else { /* PHY will be set to 10H, 10F, 100H or 100F *dependingonusersettings.
*/
hw_dbg("Forcing Speed and Duplex\n");
ret_val = hw->phy.ops.force_speed_duplex(hw); if (ret_val) {
hw_dbg("Error Forcing Speed and Duplex\n"); goto out;
}
}
/* Check link status. Wait up to 100 microseconds for link to become *valid.
*/
ret_val = igb_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link); if (ret_val) goto out;
if (link) {
hw_dbg("Valid link established!!!\n");
igb_config_collision_dist(hw);
ret_val = igb_config_fc_after_link_up(hw);
} else {
hw_dbg("Unable to establish link!!!\n");
}
/* I210 and I211 devices support Auto-Crossover in forced operation. */ if (phy->type != e1000_phy_i210) { /* Clear Auto-Crossover to force MDI manually. M88E1000 *requiresMDIforcedwheneverspeedandduplexareforced.
*/
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
&phy_data); if (ret_val) goto out;
ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out;
/* Resetting the phy means we need to re-force TX_CLK in the *ExtendedPHYSpecificControlRegisterto25MHzclockfrom *theresetvalueof2.5MHz.
*/
phy_data |= M88E1000_EPSCR_TX_CLK_25;
ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); if (ret_val) goto out;
/* In addition, we must re-enable CRS on Tx for both half and full *duplex.
*/
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out;
ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); if (ret_val) goto out;
if (!active) {
data &= ~IGP02E1000_PM_D3_LPLU;
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data); if (ret_val) goto out; /* LPLU and SmartSpeed are mutually exclusive. LPLU is used *duringDxstateswherethepowerconservationismost *important.Duringdriveractivityweshouldenable *SmartSpeed,soperformanceismaintained.
*/ if (phy->smart_speed == e1000_smart_speed_on) {
ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data); if (ret_val) goto out;
} elseif (phy->smart_speed == e1000_smart_speed_off) {
ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data); if (ret_val) goto out;
}
} elseif ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
(phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
(phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
data |= IGP02E1000_PM_D3_LPLU;
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data); if (ret_val) goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&data); if (ret_val) goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
data);
}
/* Polarity is determined based on the speed of *ourconnection.
*/
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); if (ret_val) goto out;
if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
offset = IGP01E1000_PHY_PCS_INIT_REG;
mask = IGP01E1000_PHY_POLARITY_MASK;
} else { /* This really only applies to 10Mbps since *thereisnopolarityfor100Mbps(always0).
*/
offset = IGP01E1000_PHY_PORT_STATUS;
mask = IGP01E1000_PSSR_POLARITY_REVERSED;
}
for (i = 0; i < iterations; i++) { /* Some PHYs require the PHY_STATUS register to be read *twiceduetothelinkbitbeingsticky.Noharmdoing *itacrosstheboard.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val && usec_interval > 0) { /* If the first read fails, another entity may have *ownershipoftheresources,waitandtryagainto *seeiftheyhaverelinquishedtheresourcesyet.
*/ if (usec_interval >= 1000)
mdelay(usec_interval/1000); else
udelay(usec_interval);
}
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val) break; if (phy_status & MII_SR_LINK_STATUS) break; if (usec_interval >= 1000)
mdelay(usec_interval/1000); else
udelay(usec_interval);
}
switch (hw->phy.id) { case M88E1543_E_PHY_ID: case M88E1512_E_PHY_ID: case I347AT4_E_PHY_ID: case I210_I_PHY_ID: /* Remember the original page select and set it to 7 */
ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
&default_page); if (ret_val) goto out;
ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07); if (ret_val) goto out;
/* Check if the unit of cable length is meters or cm */
ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2); if (ret_val) goto out;
/* Populate the phy structure with cable length in meters */
phy->min_cable_length = len_min;
phy->max_cable_length = len_max;
phy->cable_length = len_tot / 4;
/* Reset the page selec to its original value */
ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
default_page); if (ret_val) goto out; break; case M88E1112_E_PHY_ID: /* Remember the original page select and set it to 5 */
ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
&default_page); if (ret_val) goto out;
ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05); if (ret_val) goto out;
ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE,
&phy_data); if (ret_val) goto out;
index = FIELD_GET(M88E1000_PSSR_CABLE_LENGTH, phy_data); if (index >= ARRAY_SIZE(e1000_m88_cable_length_table) - 1) {
ret_val = -E1000_ERR_PHY; goto out;
}
/* Read the AGC registers for all channels */ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data); if (ret_val) goto out;
/* Getting bits 15:9, which represent the combination of *coarseandfinegainvalues.Theresultisanumber *thatcanbeputintothelookuptabletoobtainthe *approximatecablelength.
*/
cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
IGP02E1000_AGC_LENGTH_MASK;
/* Remove min & max AGC values from calculation. */ if (e1000_igp_2_cable_length_table[min_agc_index] >
e1000_igp_2_cable_length_table[cur_agc_index])
min_agc_index = cur_agc_index; if (e1000_igp_2_cable_length_table[max_agc_index] <
e1000_igp_2_cable_length_table[cur_agc_index])
max_agc_index = cur_agc_index;
/* The PHY will retain its settings across a power down/up cycle */
hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
mii_reg &= ~MII_CR_POWER_DOWN;
hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
}
/* The PHY will retain its settings across a power down/up cycle */
hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN;
hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
usleep_range(1000, 2000);
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.53Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-04)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.