📄 e1000_80003es2lan.c
字号:
/* Empty */ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); swfw_sync &= ~mask; E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); e1000_put_hw_semaphore_generic(hw);}/** * e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register * @hw: pointer to the HW structure * @offset: offset of the register to read * @data: pointer to the data returned from the operation * * Read the GG82563 PHY register. This is a function pointer entry * point called by the api module. **/static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data){ s32 ret_val; u32 page_select; u16 temp; DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan"); /* Select Configuration Page */ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) page_select = GG82563_PHY_PAGE_SELECT; else { /* Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; } temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); ret_val = e1000_write_phy_reg_m88(hw, page_select, temp); if (ret_val) goto out; /* The "ready" bit in the MDIC register may be incorrectly set * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ usec_delay(200); /* ...and verify the command was successful. */ ret_val = e1000_read_phy_reg_m88(hw, page_select, &temp); if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { ret_val = -E1000_ERR_PHY; goto out; } usec_delay(200); ret_val = e1000_read_phy_reg_m88(hw, MAX_PHY_REG_ADDRESS & offset, data); usec_delay(200);out: return ret_val;}/** * e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register * @hw: pointer to the HW structure * @offset: offset of the register to read * @data: value to write to the register * * Write to the GG82563 PHY register. This is a function pointer entry * point called by the api module. **/static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data){ s32 ret_val; u32 page_select; u16 temp; DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan"); /* Select Configuration Page */ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) page_select = GG82563_PHY_PAGE_SELECT; else { /* Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; } temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); ret_val = e1000_write_phy_reg_m88(hw, page_select, temp); if (ret_val) goto out; /* The "ready" bit in the MDIC register may be incorrectly set * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ usec_delay(200); /* ...and verify the command was successful. */ ret_val = e1000_read_phy_reg_m88(hw, page_select, &temp); if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { ret_val = -E1000_ERR_PHY; goto out; } usec_delay(200); ret_val = e1000_write_phy_reg_m88(hw, MAX_PHY_REG_ADDRESS & offset, data); usec_delay(200);out: return ret_val;}/** * e1000_write_nvm_80003es2lan - Write to ESB2 NVM * @hw: pointer to the HW structure * @offset: offset of the register to read * @words: number of words to write * @data: buffer of data to write to the NVM * * Write "words" of data to the ESB2 NVM. This is a function * pointer entry point called by the api module. **/static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data){ DEBUGFUNC("e1000_write_nvm_80003es2lan"); return e1000_write_nvm_spi(hw, offset, words, data);}/** * e1000_get_cfg_done_80003es2lan - Wait for configuration to complete * @hw: pointer to the HW structure * * Wait a specific amount of time for manageability processes to complete. * This is a function pointer entry point called by the phy module. **/static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw){ s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; u32 mask = E1000_NVM_CFG_DONE_PORT_0; DEBUGFUNC("e1000_get_cfg_done_80003es2lan"); if (hw->bus.func == 1) mask = E1000_NVM_CFG_DONE_PORT_1; while (timeout) { if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask) break; msec_delay(1); timeout--; } if (!timeout) { DEBUGOUT("MNG configuration cycle has not completed.\n"); ret_val = -E1000_ERR_RESET; goto out; }out: return ret_val;}/** * e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex * @hw: pointer to the HW structure * * Force the speed and duplex settings onto the PHY. This is a * function pointer entry point called by the phy module. **/static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw){ s32 ret_val; u16 phy_data; boolean_t link; DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan"); /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed and duplex are forced. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO; ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); if (ret_val) goto out; DEBUGOUT1("GG82563 PSCR: %X\n", phy_data); ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) goto out; e1000_phy_force_speed_duplex_setup(hw, &phy_data); /* Reset the phy to commit changes. */ phy_data |= MII_CR_RESET; ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data); if (ret_val) goto out; usec_delay(1); if (hw->phy.wait_for_link) { DEBUGOUT("Waiting for forced speed/duplex link " "on GG82563 phy.\n"); ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 100000, &link); if (ret_val) goto out; if (!link) { /* We didn't get link. * Reset the DSP and cross our fingers. */ ret_val = e1000_phy_reset_dsp_generic(hw); if (ret_val) goto out; } /* Try once more */ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 100000, &link); if (ret_val) goto out; } ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); if (ret_val) goto out; /* Resetting the phy means we need to verify the TX_CLK corresponds * to the link speed. 10Mbps -> 2.5MHz, else 25MHz. */ phy_data &= ~GG82563_MSCR_TX_CLK_MASK; if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED) phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5; else phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25; /* In addition, we must re-enable CRS on Tx for both half and full * duplex. */ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);out: return ret_val;}/** * e1000_get_cable_length_80003es2lan - Set approximate cable length * @hw: pointer to the HW structure * * Find the approximate cable length as measured by the GG82563 PHY. * This is a function pointer entry point called by the phy module. **/static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw){ struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 phy_data, index; DEBUGFUNC("e1000_get_cable_length_80003es2lan"); ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); if (ret_val) goto out; index = phy_data & GG82563_DSPD_CABLE_LENGTH; phy->min_cable_length = e1000_gg82563_cable_length_table[index]; phy->max_cable_length = e1000_gg82563_cable_length_table[index+5]; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;out: return ret_val;}/** * e1000_get_link_up_info_80003es2lan - Report speed and duplex * @hw: pointer to the HW structure * @speed: pointer to speed buffer * @duplex: pointer to duplex buffer * * Retrieve the current speed and duplex configuration. * This is a function pointer entry point called by the api module. **/static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, u16 *duplex){ s32 ret_val; DEBUGFUNC("e1000_get_link_up_info_80003es2lan"); if (hw->media_type == e1000_media_type_copper) { ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex); if (ret_val) goto out; if (*speed == SPEED_1000) ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); else ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, *duplex); } else { ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw, speed, duplex); }out: return ret_val;}/** * e1000_reset_hw_80003es2lan - Reset the ESB2 controller * @hw: pointer to the HW structure * * Perform a global reset to the ESB2 controller. * This is a function pointer entry point called by the api module. **/static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw){ u32 ctrl, icr; s32 ret_val; DEBUGFUNC("e1000_reset_hw_80003es2lan"); /* Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); if (ret_val) { DEBUGOUT("PCI-E Master disable polling has failed.\n"); } DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); E1000_WRITE_REG(hw, E1000_RCTL, 0); E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); E1000_WRITE_FLUSH(hw); msec_delay(10); ctrl = E1000_READ_REG(hw, E1000_CTRL); DEBUGOUT("Issuing a global reset to MAC\n"); E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); ret_val = e1000_get_auto_rd_done_generic(hw); if (ret_val) /* We don't want to continue accessing MAC registers. */ goto out; /* Clear any pending interrupt events. */ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); icr = E1000_READ_REG(hw, E1000_ICR);out: return ret_val;}/** * e1000_init_hw_80003es2lan - Initialize the ESB2 controller * @hw: pointer to the HW structure * * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. * This is a function pointer entry point called by the api module. **/static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw){ struct e1000_mac_info *mac = &hw->mac; u32 reg_data; s32 ret_val; u16 i; DEBUGFUNC("e1000_init_hw_80003es2lan"); e1000_initialize_hw_bits_80003es2lan(hw); /* Initialize identification LED */ ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); goto out; } /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); e1000_clear_vfta(hw); /* Setup the receive address. */ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); /* Setup link and flow control */ ret_val = e1000_setup_link(hw); /* Set the transmit descriptor write-back policy */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; E1000_WRITE_REG(hw, E1000_TXDCTL, reg_data); /* ...for both queues. */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL1); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -