/* Setup the receive address */
hw_dbg("Programming MAC Address into RAR[0]\n");
hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
/* Zero out the other (rar_entry_count - 1) receive addresses */
hw_dbg("Clearing RAR[1-%u]\n", rar_count-1); for (i = 1; i < rar_count; i++)
hw->mac.ops.rar_set(hw, mac_addr, i);
}
/* short cut the special case */ if (vlan == 0) return0;
/* if vlvf_bypass is set we don't want to use an empty slot, we *willsimplybypasstheVLVFiftherearenoentriespresentinthe *VLVFthatcontainourVLAN
*/
first_empty_slot = vlvf_bypass ? -E1000_ERR_NO_SPACE : 0;
/* Search for the VLAN id in the VLVF entries. Save off the first empty *slotfoundalongtheway. * *pre-decrementloopcovering(IXGBE_VLVF_ENTRIES-1)..1
*/ for (regindex = E1000_VLVF_ARRAY_SIZE; --regindex > 0;) {
bits = rd32(E1000_VLVF(regindex)) & E1000_VLVF_VLANID_MASK; if (bits == vlan) return regindex; if (!first_empty_slot && !bits)
first_empty_slot = regindex;
}
/* vfta_delta represents the difference between the current value *ofvftaandthevaluewewantintheregister.Sincethediff *isanXORmaskwecanjustupdatevftausinganXOR.
*/
vfta_delta &= vlan_on ? ~vfta : vfta;
vfta ^= vfta_delta;
/* Part 2 *IfVTModeisset *Eithervlan_on *makesuretheVLANisinVLVF *setthevindbitinthematchingVLVFB *Or!vlan_on *clearthepoolbitandpossiblythevind
*/ if (!adapter->vfs_allocated_count) goto vfta_update;
vlvf_index = igb_find_vlvf_slot(hw, vlan, vlvf_bypass); if (vlvf_index < 0) { if (vlvf_bypass) goto vfta_update; return vlvf_index;
}
bits = rd32(E1000_VLVF(vlvf_index));
/* set the pool bit */
bits |= BIT(E1000_VLVF_POOLSEL_SHIFT + vind); if (vlan_on) goto vlvf_update;
/* clear the pool bit */
bits ^= BIT(E1000_VLVF_POOLSEL_SHIFT + vind);
if (!(bits & E1000_VLVF_POOLSEL_MASK)) { /* Clear VFTA first, then disable VLVF. Otherwise *weruntheriskofstraypacketsleakinginto *thePFviathedefaultpool
*/ if (vfta_delta)
hw->mac.ops.write_vfta(hw, regidx, vfta);
/* disable VLVF and clear remaining bit from pool */
wr32(E1000_VLVF(vlvf_index), 0);
return0;
}
/* If there are still bits set in the VLVFB registers *fortheVLANIDindicatedweneedtoseeifthe *callerisrequestingthatwecleartheVFTAentrybit. *IfthecallerhasrequestedthatwecleartheVFTA *entrybitbuttherearestillpools/VFsusingthisVLAN *IDentrythenignoretherequest.We'renotworried *aboutthecasewherewe'returningtheVFTAVLANID *entrybiton,onlywhenrequestedtoturnitoffas *theremaybemultiplepoolsand/orVFsusingthe *VLANIDentry.Inthatcasewecannotclearthe *VFTAbituntilallpools/VFsusingthatVLANIDhavealso *beencleared.Thiswillbeindicatedby"bits"being *zero.
*/
vfta_delta = 0;
vlvf_update: /* record pool change and enable VLAN ID if not already enabled */
wr32(E1000_VLVF(vlvf_index), bits | vlan | E1000_VLVF_VLANID_ENABLE);
vfta_update: /* bit was set/cleared before we started */ if (vfta_delta)
hw->mac.ops.write_vfta(hw, regidx, vfta);
/* if multicast bit is set, the alternate address will not be used */ if (is_multicast_ether_addr(alt_mac_addr)) {
hw_dbg("Ignoring Alternate Mac Address with MC bit set\n"); goto out;
}
/* We have a valid alternate MAC address, and we want to treat it the *sameasthenormalpermanentMACaddressstoredbytheHWintothe *RAR.DothisbymappingthisaddressintoRAR0.
*/
hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
/* HW expects these in little endian so we reverse the byte order *fromnetworkorder(bigendian)tolittleendian
*/
rar_low = ((u32) addr[0] |
((u32) addr[1] << 8) |
((u32) addr[2] << 16) | ((u32) addr[3] << 24));
/* The MTA is a register array of 32-bit registers. It is *treatedlikeanarrayof(32*mta_reg_count)bits.Wewantto *setbitBitArray[hash_value].Sowefigureoutwhatregister *thebitisin,readit,ORinthenewbit,thenwrite *backthenewvalue.The(hw->mac.mta_reg_count-1)servesasa *masktobits31:5ofthehashvaluewhichgivesusthe *registerwe'remodifying.Thehashbitwithinthatregister *isdeterminedbythelower5bitsofthehashvalue.
*/
hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
hash_bit = hash_value & 0x1F;
/* Register count multiplied by bits per register */
hash_mask = (hw->mac.mta_reg_count * 32) - 1;
/* For a mc_filter_type of 0, bit_shift is the number of left-shifts *where0xFFwouldstillfallwithinthehashmask.
*/ while (hash_mask >> bit_shift != 0xFF && bit_shift < 4)
bit_shift++;
/* The portion of the address that is used for the hash table *isdeterminedbythemc_filter_typesetting. *Thealgorithmissuchthatthereisatotalof8bitsofshifting. *Thebit_shiftforamc_filter_typeof0representsthenumberof *left-shiftswheretheMSBofmc_addr[5]wouldstillfallwithin *thehash_mask.Case0doesthisexactly.Sincethereareatotal *of8bitsofshifting,thenmc_addr[4]willshiftrightthe *remainingnumberofbits.Thus8-bit_shift.Therestofthe *casesareavariationofthisalgorithm...essentiallyraisingthe *numberofbitstoshiftmc_addr[5]left,whilestillkeepingthe *8-bitshiftingtotal. * *Forexample,giventhefollowingDestinationMACAddressandan *mtaregistercountof128(thusa4096-bitvectorand0xFFFmask), *wecanseethatthebit_shiftforcase0is4.Thesearethehash *valuesresultingfromeachmc_filter_type... *[0][1][2][3][4][5] *01AA00123456 *LSBMSB * *case0:hash_value=((0x34>>4)|(0x56<<4))&0xFFF=0x563 *case1:hash_value=((0x34>>3)|(0x56<<5))&0xFFF=0xAC6 *case2:hash_value=((0x34>>2)|(0x56<<6))&0xFFF=0x163 *case3:hash_value=((0x34>>0)|(0x56<<8))&0xFFF=0x634
*/ switch (hw->mac.mc_filter_type) { default: case0: break; case1:
bit_shift += 1; break; case2:
bit_shift += 2; break; case3:
bit_shift += 4; break;
}
/** *igb_i21x_hw_doublecheck-doublecheckspotentialHWissueini21X *@hw:pointertotheHWstructure * *Checksifmulticastarrayiswrotecorrectly *Ifnotthenrewritesagaintoregister
**/ staticvoid igb_i21x_hw_doublecheck(struct e1000_hw *hw)
{ int failed_cnt = 3; bool is_failed; int i;
do {
is_failed = false; for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) { if (array_rd32(E1000_MTA, i) != hw->mac.mta_shadow[i]) {
is_failed = true;
array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
wrfl();
}
} if (is_failed && --failed_cnt <= 0) {
hw_dbg("Failed to update MTA_REGISTER, too many retries"); break;
}
} while (is_failed);
}
/* replace the entire MTA table */ for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
wrfl(); if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211)
igb_i21x_hw_doublecheck(hw);
}
/* We only want to go out to the PHY registers to see if Auto-Neg *hascompletedand/orifourlinkstatushaschanged.The *get_link_statusflagissetuponreceivingaLinkStatus *ChangeorRxSequenceErrorinterrupt.
*/ if (!mac->get_link_status) {
ret_val = 0; goto out;
}
/* First we want to see if the MII Status Register reports *link.Ifso,thenwewanttogetthecurrentspeed/duplex *ofthePHY.
*/
ret_val = igb_phy_has_link(hw, 1, 0, &link); if (ret_val) goto out;
if (!link) goto out; /* No link detected */
mac->get_link_status = false;
/* Check if there was DownShift, must be checked *immediatelyafterlink-up
*/
igb_check_downshift(hw);
/* If we are forcing speed/duplex, then we simply return since *wehavealreadydeterminedwhetherwehavelinkornot.
*/ if (!mac->autoneg) {
ret_val = -E1000_ERR_CONFIG; goto out;
}
/* Auto-Neg is enabled. Auto Speed Detection takes care *ofMACspeed/duplexconfiguration.Soweonlyneedto *configureCollisionDistanceintheMAC.
*/
igb_config_collision_dist(hw);
/* Configure Flow Control now that Auto-Neg has completed. *First,weneedtorestorethedesiredflowcontrol *settingsbecausewemayhavehadtore-autonegwitha *differentlinkpartner.
*/
ret_val = igb_config_fc_after_link_up(hw); if (ret_val)
hw_dbg("Error configuring flow control\n");
/* In the case of the phy reset being blocked, we already have a link. *Wedonotneedtosetitupagain.
*/ if (igb_check_reset_block(hw)) goto out;
/* If requested flow control is set to default, set flow control *basedontheEEPROMflowcontrolsettings.
*/ if (hw->fc.requested_mode == e1000_fc_default) {
ret_val = igb_set_default_fc(hw); if (ret_val) goto out;
}
/* We want to save off the original Flow Control configuration just *incasewegetdisconnectedandthenreconnectedintoadifferent *huborswitchwithdifferentFlowControlcapabilities.
*/
hw->fc.current_mode = hw->fc.requested_mode;
hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
/* Call the necessary media_type subroutine to configure the link. */
ret_val = hw->mac.ops.setup_physical_interface(hw); if (ret_val) goto out;
/* Initialize the flow control address, type, and PAUSE timer *registerstotheirdefaultvalues.Thisisdoneevenifflow *controlisdisabled,becauseitdoesnothurtanythingto *initializetheseregisters.
*/
hw_dbg("Initializing the Flow Control address, type and timer regs\n");
wr32(E1000_FCT, FLOW_CONTROL_TYPE);
wr32(E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
wr32(E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
/* Set the flow control receive threshold registers. Normally, *theseregisterswillbesettoadefaultthresholdthatmaybe *adjustedlaterbythedriver'sruntimecode.However,ifthe *abilitytotransmitpauseframesisnotenabled,thenthese *registerswillbesetto0.
*/ if (hw->fc.current_mode & e1000_fc_tx_pause) { /* We need to set up the Receive Threshold high and low water *marksaswellas(optionally)enablingthetransmissionof *XONframes.
*/
fcrtl = hw->fc.low_water; if (hw->fc.send_xon)
fcrtl |= E1000_FCRTL_XONE;
/* Read and store word 0x0F of the EEPROM. This word contains bits *thatdeterminethehardware'sdefaultPAUSE(flowcontrol)mode, *abitthatdetermineswhethertheHWdefaultstoenablingor *disablingauto-negotiation,andthedirectionofthe *SWdefinedpins.IfthereisnoSWover-rideoftheflow *controlsetting,thenthevariablehw->fcwill *beinitializedbasedonavalueintheEEPROM.
*/ if (hw->mac.type == e1000_i350)
lan_offset = NVM_82580_LAN_FUNC_OFFSET(hw->bus.func); else
lan_offset = 0;
/* Because we didn't get link via the internal auto-negotiation *mechanism(weeitherforcedlinkorwegotlinkviaPHY *auto-neg),wehavetomanuallyenable/disabletransmitan *receiveflowcontrol. * *The"Case"statementbelowenables/disableflowcontrol *accordingtothe"hw->fc.current_mode"parameter. * *Thepossiblevaluesofthe"fc"parameterare: *0:Flowcontroliscompletelydisabled *1:Rxflowcontrolisenabled(wecanreceivepause *framesbutnotsendpauseframes). *2:Txflowcontrolisenabled(wecansendpauseframes *butwedonotreceivepauseframes). *3:BothRxandTXflowcontrol(symmetric)isenabled. *other:Noothervaluesshouldbepossibleatthispoint.
*/
hw_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
switch (hw->fc.current_mode) { case e1000_fc_none:
ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); break; case e1000_fc_rx_pause:
ctrl &= (~E1000_CTRL_TFCE);
ctrl |= E1000_CTRL_RFCE; break; case e1000_fc_tx_pause:
ctrl &= (~E1000_CTRL_RFCE);
ctrl |= E1000_CTRL_TFCE; break; case e1000_fc_full:
ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); break; default:
hw_dbg("Flow control param set incorrectly\n");
ret_val = -E1000_ERR_CONFIG; goto out;
}
/* Check for the case where we have fiber media and auto-neg failed *sowehadtoforcelink.Inthiscase,weneedtoforcethe *configurationoftheMACtomatchthe"fc"parameter.
*/ if (mac->autoneg_failed) { if (hw->phy.media_type == e1000_media_type_internal_serdes)
ret_val = igb_force_mac_fc(hw);
} else { if (hw->phy.media_type == e1000_media_type_copper)
ret_val = igb_force_mac_fc(hw);
}
if (ret_val) {
hw_dbg("Error forcing flow control settings\n"); goto out;
}
/* Check for the case where we have copper media and auto-neg is *enabled.Inthiscase,weneedtocheckandseeifAuto-Neg *hascompleted,andifso,howthePHYandlinkpartnerhas *flowcontrolconfigured.
*/ if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) { /* Read the MII Status Register and check to see if AutoNeg *hascompleted.Wereadthistwicebecausethisreghas *some"sticky"(latched)bits.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg); if (ret_val) goto out;
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg); if (ret_val) goto out;
if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
hw_dbg("Copper PHY and Auto Neg has not completed.\n"); goto out;
}
/* The AutoNeg process has completed, so we now need to *readboththeAutoNegotiationAdvertisement *Register(Address4)andtheAuto_NegotiationBase *PageAbilityRegister(Address5)todeterminehow *flowcontrolwasnegotiated.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
&mii_nway_adv_reg); if (ret_val) goto out;
ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
&mii_nway_lp_ability_reg); if (ret_val) goto out;
/* Two bits in the Auto Negotiation Advertisement Register *(Address4)andtwobitsintheAutoNegotiationBase *PageAbilityRegister(Address5)determineflowcontrol *forboththePHYandthelinkpartner.Thefollowing *table,takenoutoftheIEEE802.3ab/D6.0datedMarch25, *1999,describesthesePAUSEresolutionbitsandhowflow *controlisdeterminedbaseduponthesesettings. *NOTE:DC=Don'tCare * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|NICResolution *-------|---------|-------|---------|-------------------- *0|0|DC|DC|e1000_fc_none *0|1|0|DC|e1000_fc_none *0|1|1|0|e1000_fc_none *0|1|1|1|e1000_fc_tx_pause *1|0|0|DC|e1000_fc_none *1|DC|1|DC|e1000_fc_full *1|1|0|0|e1000_fc_none *1|1|0|1|e1000_fc_rx_pause * *ArebothPAUSEbitssetto1?Ifso,thisimplies *SymmetricFlowControlisenabledatbothends.The *ASM_DIRbitsareirrelevantperthespec. * *ForSymmetricFlowControl: * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|Result *-------|---------|-------|---------|-------------------- *1|DC|1|DC|E1000_fc_full *
*/ if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { /* Now we need to check if the user selected RX ONLY *ofpauseframes.Inthiscase,wehadtoadvertise *FULLflowcontrolbecausewecouldnotadvertiseRX *ONLY.Hence,wemustnowchecktoseeifweneedto *turnOFFtheTRANSMISSIONofPAUSEframes.
*/ if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full;
hw_dbg("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
} /* For receiving PAUSE frames ONLY. * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|Result *-------|---------|-------|---------|-------------------- *0|1|1|1|e1000_fc_tx_pause
*/ elseif (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_tx_pause;
hw_dbg("Flow Control = TX PAUSE frames only.\n");
} /* For transmitting PAUSE frames ONLY. * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|Result *-------|---------|-------|---------|-------------------- *1|1|0|1|e1000_fc_rx_pause
*/ elseif ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
} /* Per the IEEE spec, at this point flow control should be *disabled.However,wewanttoconsiderthatwecould *beconnectedtoalegacyswitchthatdoesn'tadvertise *desiredflowcontrol,butcanbeforcedonthelink *partner.Soifweadvertisednoflowcontrol,thatis *whatwewillresolveto.Ifweadvertisedsomekindof *receivecapability(RxPauseOnlyorFullFlowControl) *andthelinkpartneradvertisednone,wewillconfigure *ourselvestoenableRxFlowControlonly.Wecando *thissafelyfortworeasons:Ifthelinkpartnerreally *didn'twantflowcontrolenabled,andweenableRx,no *harmdonesincewewon'tbereceivinganyPAUSEframes *anyway.Iftheintentonthelinkpartnerwastohave *flowcontrolenabled,thenbyusenablingRXonly,we *canatleastreceivepauseframesandprocessthem. *Thisisagoodideabecauseinmostcases,sinceweare *predominantlyaserverNIC,moretimesthannotwewill *beaskedtodelaytransmissionofpacketsthanasking *ourlinkpartnertopausetransmissionofframes.
*/ elseif ((hw->fc.requested_mode == e1000_fc_none) ||
(hw->fc.requested_mode == e1000_fc_tx_pause) ||
(hw->fc.strict_ieee)) {
hw->fc.current_mode = e1000_fc_none;
hw_dbg("Flow Control = NONE.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Now we need to do one last check... If we auto- *negotiatedtoHALFDUPLEX,flowcontrolshouldnotbe *enabledperIEEE802.3spec.
*/
ret_val = hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex); if (ret_val) {
hw_dbg("Error getting link speed and duplex\n"); goto out;
}
if (duplex == HALF_DUPLEX)
hw->fc.current_mode = e1000_fc_none;
/* Now we call a subroutine to actually force the MAC *controllertousethecorrectflowcontrolsettings.
*/
ret_val = igb_force_mac_fc(hw); if (ret_val) {
hw_dbg("Error forcing flow control settings\n"); goto out;
}
} /* Check for the case where we have SerDes media and auto-neg is *enabled.Inthiscase,weneedtocheckandseeifAuto-Neg *hascompleted,andifso,howthePHYandlinkpartnerhas *flowcontrolconfigured.
*/ if ((hw->phy.media_type == e1000_media_type_internal_serdes)
&& mac->autoneg) { /* Read the PCS_LSTS and check to see if AutoNeg *hascompleted.
*/
pcs_status_reg = rd32(E1000_PCS_LSTAT);
if (!(pcs_status_reg & E1000_PCS_LSTS_AN_COMPLETE)) {
hw_dbg("PCS Auto Neg has not completed.\n"); return ret_val;
}
/* The AutoNeg process has completed, so we now need to *readboththeAutoNegotiationAdvertisement *Register(PCS_ANADV)andtheAuto_NegotiationBase *PageAbilityRegister(PCS_LPAB)todeterminehow *flowcontrolwasnegotiated.
*/
pcs_adv_reg = rd32(E1000_PCS_ANADV);
pcs_lp_ability_reg = rd32(E1000_PCS_LPAB);
/* Two bits in the Auto Negotiation Advertisement Register *(PCS_ANADV)andtwobitsintheAutoNegotiationBase *PageAbilityRegister(PCS_LPAB)determineflowcontrol *forboththePHYandthelinkpartner.Thefollowing *table,takenoutoftheIEEE802.3ab/D6.0datedMarch25, *1999,describesthesePAUSEresolutionbitsandhowflow *controlisdeterminedbaseduponthesesettings. *NOTE:DC=Don'tCare * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|NICResolution *-------|---------|-------|---------|-------------------- *0|0|DC|DC|e1000_fc_none *0|1|0|DC|e1000_fc_none *0|1|1|0|e1000_fc_none *0|1|1|1|e1000_fc_tx_pause *1|0|0|DC|e1000_fc_none *1|DC|1|DC|e1000_fc_full *1|1|0|0|e1000_fc_none *1|1|0|1|e1000_fc_rx_pause * *ArebothPAUSEbitssetto1?Ifso,thisimplies *SymmetricFlowControlisenabledatbothends.The *ASM_DIRbitsareirrelevantperthespec. * *ForSymmetricFlowControl: * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|Result *-------|---------|-------|---------|-------------------- *1|DC|1|DC|e1000_fc_full *
*/ if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
(pcs_lp_ability_reg & E1000_TXCW_PAUSE)) { /* Now we need to check if the user selected Rx ONLY *ofpauseframes.Inthiscase,wehadtoadvertise *FULLflowcontrolbecausewecouldnotadvertiseRx *ONLY.Hence,wemustnowchecktoseeifweneedto *turnOFFtheTRANSMISSIONofPAUSEframes.
*/ if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full;
hw_dbg("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
hw_dbg("Flow Control = Rx PAUSE frames only.\n");
}
} /* For receiving PAUSE frames ONLY. * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|Result *-------|---------|-------|---------|-------------------- *0|1|1|1|e1000_fc_tx_pause
*/ elseif (!(pcs_adv_reg & E1000_TXCW_PAUSE) &&
(pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
(pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_tx_pause;
hw_dbg("Flow Control = Tx PAUSE frames only.\n");
} /* For transmitting PAUSE frames ONLY. * *LOCALDEVICE|LINKPARTNER *PAUSE|ASM_DIR|PAUSE|ASM_DIR|Result *-------|---------|-------|---------|-------------------- *1|1|0|1|e1000_fc_rx_pause
*/ elseif ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
(pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
!(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
(pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_rx_pause;
hw_dbg("Flow Control = Rx PAUSE frames only.\n");
} else { /* Per the IEEE spec, at this point flow control *shouldbedisabled.
*/
hw->fc.current_mode = e1000_fc_none;
hw_dbg("Flow Control = NONE.\n");
}
/* Now we call a subroutine to actually force the MAC *controllertousethecorrectflowcontrolsettings.
*/
pcs_ctrl_reg = rd32(E1000_PCS_LCTL);
pcs_ctrl_reg |= E1000_PCS_LCTL_FORCE_FCTRL;
wr32(E1000_PCS_LCTL, pcs_ctrl_reg);
ret_val = igb_force_mac_fc(hw); if (ret_val) {
hw_dbg("Error forcing flow control settings\n"); return ret_val;
}
}
for (i = 0; i < 4; i++) {
temp = (data >> (i << 2)) & led_mask; switch (temp) { case ID_LED_ON1_DEF2: case ID_LED_ON1_ON2: case ID_LED_ON1_OFF2:
mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
mac->ledctl_mode1 |= ledctl_on << (i << 3); break; case ID_LED_OFF1_DEF2: case ID_LED_OFF1_ON2: case ID_LED_OFF1_OFF2:
mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
mac->ledctl_mode1 |= ledctl_off << (i << 3); break; default: /* Do nothing */ break;
} switch (temp) { case ID_LED_DEF1_ON2: case ID_LED_ON1_ON2: case ID_LED_OFF1_ON2:
mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
mac->ledctl_mode2 |= ledctl_on << (i << 3); break; case ID_LED_DEF1_OFF2: case ID_LED_ON1_OFF2: case ID_LED_OFF1_OFF2:
mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
mac->ledctl_mode2 |= ledctl_off << (i << 3); break; default: /* Do nothing */ break;
}
}
/* Set up the address and data */
regvalue = ((u32)data) | (offset << E1000_GEN_CTL_ADDRESS_SHIFT);
wr32(reg, regvalue);
/* Poll the ready bit to see if the MDI read completed */ for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) {
udelay(5);
regvalue = rd32(reg); if (regvalue & E1000_GEN_CTL_READY) break;
} if (!(regvalue & E1000_GEN_CTL_READY)) {
hw_dbg("Reg %08x did not indicate ready\n", reg);
ret_val = -E1000_ERR_PHY; goto out;
}
¤ 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.0.38Bemerkung:
(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.