static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw) { s32 ret_val; u16 j, nvm_data; u16 nvm_offset; ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); if (ret_val) { hw_dbg("NVM Read Error while updating checksum" " compatibility bit.\n"); goto out; } if ((nvm_data & NVM_COMPATIBILITY_BIT_MASK) == 0) { nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK; ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); if (ret_val) { hw_dbg("NVM Write Error while updating checksum" " compatibility bit.\n"); goto out; } } for (j = 0; j < 4; j++) { nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); ret_val = igb_update_nvm_checksum_with_offset(hw, nvm_offset); if (ret_val) goto out; } out: return ret_val; }
/** * igb_get_hw_semaphore_i210 - Acquire hardware semaphore * @hw: pointer to the HW structure * * Acquire the HW semaphore to access the PHY or NVM */ static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) { u32 swsm; s32 timeout = hw->nvm.word_size + 1; s32 i = 0; /* Get the SW semaphore */ while (i < timeout) { swsm = rd32(E1000_SWSM); if (!(swsm & E1000_SWSM_SMBI)) break; udelay(50); i++; } if (i == timeout) { /* In rare circumstances, the SW semaphore may already be held * unintentionally. Clear the semaphore once before giving up. */ if (hw->dev_spec._82575.clear_semaphore_once) { hw->dev_spec._82575.clear_semaphore_once = false; igb_put_hw_semaphore(hw); for (i = 0; i < timeout; i++) { swsm = rd32(E1000_SWSM); if (!(swsm & E1000_SWSM_SMBI)) break; udelay(50); } } /* If we do not have the semaphore here, we have to give up. */ if (i == timeout) { hw_dbg("Driver can't access device - SMBI bit is set.\n"); return -E1000_ERR_NVM; } } /* Get the FW semaphore. */ for (i = 0; i < timeout; i++) { swsm = rd32(E1000_SWSM); wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI); /* Semaphore acquired if bit latched */ if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI) break; udelay(50); } if (i == timeout) { /* Release semaphores */ igb_put_hw_semaphore(hw); hw_dbg("Driver can't access the NVM\n"); return -E1000_ERR_NVM; } return 0; }
static s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset) { s32 ret_val = 0; u16 checksum = 0; u16 i, nvm_data; for (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) { ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); if (ret_val) { hw_dbg("NVM Read Error\n"); goto out; } checksum += nvm_data; } if (checksum != (u16) NVM_SUM) { hw_dbg("NVM Checksum Invalid\n"); ret_val = -E1000_ERR_NVM; goto out; } out: return ret_val; }
/** * igb_read_invm_word_i210 - Reads OTP * @hw: pointer to the HW structure * @address: the word address (aka eeprom offset) to read * @data: pointer to the data read * * Reads 16-bit words from the OTP. Return error when the word is not * stored in OTP. **/ static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data) { s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; u32 invm_dword; u16 i; u8 record_type, word_address; for (i = 0; i < E1000_INVM_SIZE; i++) { invm_dword = rd32(E1000_INVM_DATA_REG(i)); /* Get record type */ record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword); if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE) break; if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE) i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS; if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE) i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS; if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) { word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); if (word_address == address) { *data = INVM_DWORD_TO_WORD_DATA(invm_dword); hw_dbg("Read INVM Word 0x%02x = %x\n", address, *data); status = 0; break; } } } if (status) hw_dbg("Requested word 0x%02x not found in OTP\n", address); return status; }
/** * igb_reset_hw_82575 - Reset hardware * @hw: pointer to the HW structure * * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ static s32 igb_reset_hw_82575(struct e1000_hw *hw) { u32 ctrl, icr; s32 ret_val; /* * 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 = igb_disable_pcie_master(hw); if (ret_val) hw_dbg("PCI-E Master disable polling has failed.\n"); /* set the completion timeout for interface */ ret_val = igb_set_pcie_completion_timeout(hw); if (ret_val) { hw_dbg("PCI-E Set completion timeout has failed.\n"); } hw_dbg("Masking off all interrupts\n"); wr32(E1000_IMC, 0xffffffff); wr32(E1000_RCTL, 0); wr32(E1000_TCTL, E1000_TCTL_PSP); wrfl(); msleep(10); ctrl = rd32(E1000_CTRL); hw_dbg("Issuing a global reset to MAC\n"); wr32(E1000_CTRL, ctrl | E1000_CTRL_RST); ret_val = igb_get_auto_rd_done(hw); if (ret_val) { /* * When auto config read does not complete, do not * return with an error. This can happen in situations * where there is no eeprom and prevents getting link. */ hw_dbg("Auto Read Done did not complete\n"); } /* If EEPROM is not present, run manual init scripts */ if ((rd32(E1000_EECD) & E1000_EECD_PRES) == 0) igb_reset_init_script_82575(hw); /* Clear any pending interrupt events. */ wr32(E1000_IMC, 0xffffffff); icr = rd32(E1000_ICR); /* Install any alternate MAC address into RAR0 */ ret_val = igb_check_alt_mac_addr(hw); return ret_val; }
/** * i40e_remove_pd_bp - remove a backing page from a page descriptor * @hw: pointer to our HW structure * @hmc_info: pointer to the HMC configuration information structure * @idx: the page index * @is_pf: distinguishes a VF from a PF * * This function: * 1. Marks the entry in pd tabe (for paged address mode) or in sd table * (for direct address mode) invalid. * 2. Write to register PMPDINV to invalidate the backing page in FV cache * 3. Decrement the ref count for the pd _entry * assumptions: * 1. Caller can deallocate the memory used by backing storage after this * function returns. **/ i40e_status i40e_remove_pd_bp(struct i40e_hw *hw, struct i40e_hmc_info *hmc_info, u32 idx, bool is_pf) { i40e_status ret_code = 0; struct i40e_hmc_pd_entry *pd_entry; struct i40e_hmc_pd_table *pd_table; struct i40e_hmc_sd_entry *sd_entry; u32 sd_idx, rel_pd_idx; u64 *pd_addr; /* calculate index */ sd_idx = idx / I40E_HMC_PD_CNT_IN_SD; rel_pd_idx = idx % I40E_HMC_PD_CNT_IN_SD; if (sd_idx >= hmc_info->sd_table.sd_cnt) { ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX; hw_dbg(hw, "i40e_remove_pd_bp: bad idx\n"); goto exit; } sd_entry = &hmc_info->sd_table.sd_entry[sd_idx]; if (I40E_SD_TYPE_PAGED != sd_entry->entry_type) { ret_code = I40E_ERR_INVALID_SD_TYPE; hw_dbg(hw, "i40e_remove_pd_bp: wrong sd_entry type\n"); goto exit; } /* get the entry and decrease its ref counter */ pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table; pd_entry = &pd_table->pd_entry[rel_pd_idx]; I40E_DEC_BP_REFCNT(&pd_entry->bp); if (pd_entry->bp.ref_cnt) goto exit; /* mark the entry invalid */ pd_entry->valid = false; I40E_DEC_PD_REFCNT(pd_table); pd_addr = (u64 *)pd_table->pd_page_addr.va; pd_addr += rel_pd_idx; memset(pd_addr, 0, sizeof(u64)); if (is_pf) I40E_INVALIDATE_PF_HMC_PD(hw, sd_idx, idx); else I40E_INVALIDATE_VF_HMC_PD(hw, sd_idx, idx, hmc_info->hmc_fn_id); /* free memory here */ ret_code = i40e_free_dma_mem(hw, &(pd_entry->bp.addr)); if (ret_code) goto exit; if (!pd_table->ref_cnt) i40e_free_virt_mem(hw, &pd_table->pd_entry_virt_mem); exit: return ret_code; }
/** * igb_init_rx_addrs - Initialize receive address's * @hw: pointer to the HW structure * @rar_count: receive address registers * * Setups the receive address registers by setting the base receive address * register to the devices MAC address and clearing all the other receive * address registers to 0. **/ void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) { u32 i; u8 mac_addr[ETH_ALEN] = {0}; /* 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); }
/** * igb_get_cfg_done_82575 - Read config done bit * @hw: pointer to the HW structure * * Read the management control register for the config done bit for * completion status. NOTE: silicon which is EEPROM-less will fail trying * to read the config done bit, so an error is *ONLY* logged and returns * 0. If we were to return with error, EEPROM-less silicon * would not be able to be reset or change link. **/ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = 0; u32 mask = E1000_NVM_CFG_DONE_PORT_0; if (hw->bus.func == 1) mask = E1000_NVM_CFG_DONE_PORT_1; else if (hw->bus.func == E1000_FUNC_2) mask = E1000_NVM_CFG_DONE_PORT_2; else if (hw->bus.func == E1000_FUNC_3) mask = E1000_NVM_CFG_DONE_PORT_3; while (timeout) { if (rd32(E1000_EEMNGCTL) & mask) break; msleep(1); timeout--; } if (!timeout) hw_dbg("MNG configuration cycle has not completed.\n"); /* If EEPROM is not marked present, init the PHY manually */ if (((rd32(E1000_EECD) & E1000_EECD_PRES) == 0) && (hw->phy.type == e1000_phy_igp_3)) igb_phy_init_script_igp3(hw); return ret_val; }
/** * ixgbe_get_phy_type_from_id - Get the phy type * @hw: pointer to hardware structure * **/ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) { enum ixgbe_phy_type phy_type; switch (phy_id) { case TN1010_PHY_ID: phy_type = ixgbe_phy_tn; break; case X540_PHY_ID: phy_type = ixgbe_phy_aq; break; case QT2022_PHY_ID: phy_type = ixgbe_phy_qt; break; case ATH_PHY_ID: phy_type = ixgbe_phy_nl; break; default: phy_type = ixgbe_phy_unknown; break; } hw_dbg(hw, "phy type found is %d\n", phy_type); return phy_type; }
static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw) { s32 ret_val = 0; u32 mdicnfg; u16 nvm_data = 0; if (hw->mac.type != e1000_82580) goto out; if (!igb_sgmii_active_82575(hw)) goto out; ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, &nvm_data); if (ret_val) { hw_dbg("NVM Read Error\n"); goto out; } mdicnfg = rd32(E1000_MDICNFG); if (nvm_data & NVM_WORD24_EXT_MDIO) mdicnfg |= E1000_MDICNFG_EXT_MDIO; if (nvm_data & NVM_WORD24_COM_MDIO) mdicnfg |= E1000_MDICNFG_COM_MDIO; wr32(E1000_MDICNFG, mdicnfg); out: return ret_val; }
static s32 igb_reset_init_script_82575(struct e1000_hw *hw) { if (hw->mac.type == e1000_82575) { hw_dbg("Running reset init script for 82575\n"); igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x00, 0x0C); igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x01, 0x78); igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x1B, 0x23); igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x23, 0x15); igb_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x14, 0x00); igb_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x10, 0x00); igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x00, 0xEC); igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x61, 0xDF); igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x34, 0x05); igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x2F, 0x81); igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x02, 0x47); igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x14, 0x00); igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x10, 0x00); } return 0; }
static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw) { s32 ret_val = 0; u16 eeprom_regions_count = 1; u16 j, nvm_data; u16 nvm_offset; ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); if (ret_val) { hw_dbg("NVM Read Error\n"); goto out; } if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) { eeprom_regions_count = 4; } for (j = 0; j < eeprom_regions_count; j++) { nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); ret_val = igb_validate_nvm_checksum_with_offset(hw, nvm_offset); if (ret_val != 0) goto out; } out: return ret_val; }
/** * igb_reset_init_script_82575 - Inits HW defaults after reset * @hw: pointer to the HW structure * * Inits recommended HW defaults after a reset when there is no EEPROM * detected. This is only for the 82575. **/ static s32 igb_reset_init_script_82575(struct e1000_hw *hw) { if (hw->mac.type == e1000_82575) { hw_dbg("Running reset init script for 82575\n"); /* SerDes configuration via SERDESCTRL */ igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x00, 0x0C); igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x01, 0x78); igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x1B, 0x23); igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x23, 0x15); /* CCM configuration via CCMCTL register */ igb_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x14, 0x00); igb_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x10, 0x00); /* PCIe lanes configuration */ igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x00, 0xEC); igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x61, 0xDF); igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x34, 0x05); igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x2F, 0x81); /* PCIe PLL Configuration */ igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x02, 0x47); igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x14, 0x00); igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x10, 0x00); } return 0; }
/** * i40e_set_mac_type - Sets MAC type * @hw: pointer to the HW structure * * This function sets the mac type of the adapter based on the * vendor ID and device ID stored in the hw structure. **/ i40e_status i40e_set_mac_type(struct i40e_hw *hw) { i40e_status status = 0; if (hw->vendor_id == PCI_VENDOR_ID_INTEL) { switch (hw->device_id) { case I40E_DEV_ID_SFP_XL710: case I40E_DEV_ID_SFP_X710: case I40E_DEV_ID_QEMU: case I40E_DEV_ID_KX_A: case I40E_DEV_ID_KX_B: case I40E_DEV_ID_KX_C: case I40E_DEV_ID_KX_D: case I40E_DEV_ID_QSFP_A: case I40E_DEV_ID_QSFP_B: case I40E_DEV_ID_QSFP_C: hw->mac.type = I40E_MAC_XL710; break; case I40E_DEV_ID_VF: case I40E_DEV_ID_VF_HV: hw->mac.type = I40E_MAC_VF; break; default: hw->mac.type = I40E_MAC_GENERIC; break; } } else { status = I40E_ERR_DEVICE_NOT_SUPPORTED; } hw_dbg(hw, "i40e_set_mac_type found mac: %d, returns: %d\n", hw->mac.type, status); return status; }
/** * igb_get_hw_semaphore_i210 - Acquire hardware semaphore * @hw: pointer to the HW structure * * Acquire the HW semaphore to access the PHY or NVM */ static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) { u32 swsm; s32 ret_val = E1000_SUCCESS; s32 timeout = hw->nvm.word_size + 1; s32 i = 0; /* Get the FW semaphore. */ for (i = 0; i < timeout; i++) { swsm = rd32(E1000_SWSM); wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI); /* Semaphore acquired if bit latched */ if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI) break; udelay(50); } if (i == timeout) { /* Release semaphores */ igb_put_hw_semaphore(hw); hw_dbg("Driver can't access the NVM\n"); ret_val = -E1000_ERR_NVM; goto out; } out: return ret_val; }
static s32 igb_reset_hw_82575(struct e1000_hw *hw) { u32 ctrl, icr; s32 ret_val; ret_val = igb_disable_pcie_master(hw); if (ret_val) hw_dbg("PCI-E Master disable polling has failed.\n"); ret_val = igb_set_pcie_completion_timeout(hw); if (ret_val) { hw_dbg("PCI-E Set completion timeout has failed.\n"); } hw_dbg("Masking off all interrupts\n"); wr32(E1000_IMC, 0xffffffff); wr32(E1000_RCTL, 0); wr32(E1000_TCTL, E1000_TCTL_PSP); wrfl(); msleep(10); ctrl = rd32(E1000_CTRL); hw_dbg("Issuing a global reset to MAC\n"); wr32(E1000_CTRL, ctrl | E1000_CTRL_RST); ret_val = igb_get_auto_rd_done(hw); if (ret_val) { hw_dbg("Auto Read Done did not complete\n"); } if ((rd32(E1000_EECD) & E1000_EECD_PRES) == 0) igb_reset_init_script_82575(hw); wr32(E1000_IMC, 0xffffffff); icr = rd32(E1000_ICR); ret_val = igb_check_alt_mac_addr(hw); return ret_val; }
/** * ixgbe_set_mac_type - Sets MAC type * @hw: pointer to the HW structure * * This function sets the mac type of the adapter based on the * vendor ID and device ID stored in the hw structure. **/ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) { s32 ret_val = 0; if (hw->vendor_id != IXGBE_INTEL_VENDOR_ID) { ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, "Unsupported vendor id: %x", hw->vendor_id); return IXGBE_ERR_DEVICE_NOT_SUPPORTED; } switch (hw->device_id) { case IXGBE_DEV_ID_82598: case IXGBE_DEV_ID_82598_BX: case IXGBE_DEV_ID_82598AF_SINGLE_PORT: case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AT: case IXGBE_DEV_ID_82598AT2: case IXGBE_DEV_ID_82598EB_CX4: case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: case IXGBE_DEV_ID_82598_DA_DUAL_PORT: case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: case IXGBE_DEV_ID_82598EB_XF_LR: case IXGBE_DEV_ID_82598EB_SFP_LOM: hw->mac.type = ixgbe_mac_82598EB; break; case IXGBE_DEV_ID_82599_KX4: case IXGBE_DEV_ID_82599_KX4_MEZZ: case IXGBE_DEV_ID_82599_XAUI_LOM: case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: case IXGBE_DEV_ID_82599_KR: case IXGBE_DEV_ID_82599_SFP: case IXGBE_DEV_ID_82599_BACKPLANE_FCOE: case IXGBE_DEV_ID_82599_SFP_FCOE: case IXGBE_DEV_ID_82599_SFP_EM: case IXGBE_DEV_ID_82599_SFP_SF2: case IXGBE_DEV_ID_82599_SFP_SF_QP: case IXGBE_DEV_ID_82599_QSFP_SF_QP: case IXGBE_DEV_ID_82599EN_SFP: case IXGBE_DEV_ID_82599_CX4: case IXGBE_DEV_ID_82599_LS: case IXGBE_DEV_ID_82599_T3_LOM: hw->mac.type = ixgbe_mac_82599EB; break; case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: hw->mac.type = ixgbe_mac_X540; break; default: ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED; ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, "Unsupported device id: %x", hw->device_id); break; } hw_dbg(hw, "ixgbe_set_mac_type found mac: %d, returns: %d\n", hw->mac.type, ret_val); return ret_val; }
static void ixgbevf_diag_test(struct net_device *netdev, struct ethtool_test *eth_test, u64 *data) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); bool if_running = netif_running(netdev); set_bit(__IXGBEVF_TESTING, &adapter->state); if (eth_test->flags == ETH_TEST_FL_OFFLINE) { /* Offline tests */ hw_dbg(&adapter->hw, "offline testing starting\n"); /* Link test performed before hardware reset so autoneg doesn't * interfere with test result */ if (ixgbevf_link_test(adapter, &data[1])) eth_test->flags |= ETH_TEST_FL_FAILED; if (if_running) /* indicate we're in test mode */ dev_close(netdev); else ixgbevf_reset(adapter); hw_dbg(&adapter->hw, "register testing starting\n"); if (ixgbevf_reg_test(adapter, &data[0])) eth_test->flags |= ETH_TEST_FL_FAILED; ixgbevf_reset(adapter); clear_bit(__IXGBEVF_TESTING, &adapter->state); if (if_running) dev_open(netdev); } else { hw_dbg(&adapter->hw, "online testing starting\n"); /* Online tests */ if (ixgbevf_link_test(adapter, &data[1])) eth_test->flags |= ETH_TEST_FL_FAILED; /* Online tests aren't run; pass by default */ data[0] = 0; clear_bit(__IXGBEVF_TESTING, &adapter->state); } msleep_interruptible(4 * 1000); }
static void ixgbevf_diag_test(struct net_device *netdev, struct ethtool_test *eth_test, u64 *data) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); bool if_running = netif_running(netdev); set_bit(__IXGBEVF_TESTING, &adapter->state); if (eth_test->flags == ETH_TEST_FL_OFFLINE) { /* */ hw_dbg(&adapter->hw, "offline testing starting\n"); /* */ if (ixgbevf_link_test(adapter, &data[1])) eth_test->flags |= ETH_TEST_FL_FAILED; if (if_running) /* */ dev_close(netdev); else ixgbevf_reset(adapter); hw_dbg(&adapter->hw, "register testing starting\n"); if (ixgbevf_reg_test(adapter, &data[0])) eth_test->flags |= ETH_TEST_FL_FAILED; ixgbevf_reset(adapter); clear_bit(__IXGBEVF_TESTING, &adapter->state); if (if_running) dev_open(netdev); } else { hw_dbg(&adapter->hw, "online testing starting\n"); /* */ if (ixgbevf_link_test(adapter, &data[1])) eth_test->flags |= ETH_TEST_FL_FAILED; /* */ data[0] = 0; clear_bit(__IXGBEVF_TESTING, &adapter->state); } msleep_interruptible(4 * 1000); }
/** * i40e_add_pd_table_entry - Adds page descriptor to the specified table * @hw: pointer to our HW structure * @hmc_info: pointer to the HMC configuration information structure * @pd_index: which page descriptor index to manipulate * * This function: * 1. Initializes the pd entry * 2. Adds pd_entry in the pd_table * 3. Mark the entry valid in i40e_hmc_pd_entry structure * 4. Initializes the pd_entry's ref count to 1 * assumptions: * 1. The memory for pd should be pinned down, physically contiguous and * aligned on 4K boundary and zeroed memory. * 2. It should be 4K in size. **/ i40e_status i40e_add_pd_table_entry(struct i40e_hw *hw, struct i40e_hmc_info *hmc_info, u32 pd_index) { i40e_status ret_code = I40E_SUCCESS; struct i40e_hmc_pd_table *pd_table; struct i40e_hmc_pd_entry *pd_entry; struct i40e_dma_mem mem; u32 sd_idx, rel_pd_idx; u64 *pd_addr; u64 page_desc; if (pd_index / I40E_HMC_PD_CNT_IN_SD >= hmc_info->sd_table.sd_cnt) { ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX; hw_dbg(hw, "i40e_add_pd_table_entry: bad pd_index\n"); goto exit; } /* find corresponding sd */ sd_idx = (pd_index / I40E_HMC_PD_CNT_IN_SD); if (I40E_SD_TYPE_PAGED != hmc_info->sd_table.sd_entry[sd_idx].entry_type) goto exit; rel_pd_idx = (pd_index % I40E_HMC_PD_CNT_IN_SD); pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table; pd_entry = &pd_table->pd_entry[rel_pd_idx]; if (!pd_entry->valid) { /* allocate a 4K backing page */ ret_code = i40e_allocate_dma_mem(hw, &mem, i40e_mem_bp, I40E_HMC_PAGED_BP_SIZE, I40E_HMC_PD_BP_BUF_ALIGNMENT); if (ret_code) goto exit; i40e_memcpy(&pd_entry->bp.addr, &mem, sizeof(struct i40e_dma_mem), I40E_NONDMA_TO_NONDMA); pd_entry->bp.sd_pd_index = pd_index; pd_entry->bp.entry_type = I40E_SD_TYPE_PAGED; /* Set page address and valid bit */ page_desc = mem.pa | 0x1; pd_addr = (u64 *)pd_table->pd_page_addr.va; pd_addr += rel_pd_idx; /* Add the backing page physical address in the pd entry */ i40e_memcpy(pd_addr, &page_desc, sizeof(u64), I40E_NONDMA_TO_DMA); pd_entry->sd_index = sd_idx; pd_entry->valid = true; I40E_INC_PD_REFCNT(pd_table); } I40E_INC_BP_REFCNT(&pd_entry->bp); exit: return ret_code; }
/** * igb_write_nvm_srwr - Write to Shadow Ram using EEWR * @hw: pointer to the HW structure * @offset: offset within the Shadow Ram to be written to * @words: number of words to write * @data: 16 bit word(s) to be written to the Shadow Ram * * Writes data to Shadow Ram at offset using EEWR register. * * If igb_update_nvm_checksum is not called after this function , the * Shadow Ram will most likely contain an invalid checksum. **/ static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i, k, eewr = 0; u32 attempts = 100000; s32 ret_val = E1000_SUCCESS; /* * A check for invalid values: offset too large, too many words, * too many words for the offset, and not enough words. */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { hw_dbg("nvm parameter(s) out of bounds\n"); ret_val = -E1000_ERR_NVM; goto out; } for (i = 0; i < words; i++) { eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | (data[i] << E1000_NVM_RW_REG_DATA) | E1000_NVM_RW_REG_START; wr32(E1000_SRWR, eewr); for (k = 0; k < attempts; k++) { if (E1000_NVM_RW_REG_DONE & rd32(E1000_SRWR)) { ret_val = E1000_SUCCESS; break; } udelay(5); } if (ret_val != E1000_SUCCESS) { hw_dbg("Shadow RAM write EEWR timed out\n"); break; } } out: return ret_val; }
void igb_rx_fifo_flush_82575(struct e1000_hw *hw) { u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled; int i, ms_wait; if (hw->mac.type != e1000_82575 || !(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN)) return; for (i = 0; i < 4; i++) { rxdctl[i] = rd32(E1000_RXDCTL(i)); wr32(E1000_RXDCTL(i), rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE); } for (ms_wait = 0; ms_wait < 10; ms_wait++) { msleep(1); rx_enabled = 0; for (i = 0; i < 4; i++) rx_enabled |= rd32(E1000_RXDCTL(i)); if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE)) break; } if (ms_wait == 10) hw_dbg("Queue disable timed out after 10ms\n"); rfctl = rd32(E1000_RFCTL); wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF); rlpml = rd32(E1000_RLPML); wr32(E1000_RLPML, 0); rctl = rd32(E1000_RCTL); temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP); temp_rctl |= E1000_RCTL_LPE; wr32(E1000_RCTL, temp_rctl); wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN); wrfl(); msleep(2); for (i = 0; i < 4; i++) wr32(E1000_RXDCTL(i), rxdctl[i]); wr32(E1000_RCTL, rctl); wrfl(); wr32(E1000_RLPML, rlpml); wr32(E1000_RFCTL, rfctl); rd32(E1000_ROC); rd32(E1000_RNBC); rd32(E1000_MPC); }
/** * igb_init_hw_82575 - Initialize hardware * @hw: pointer to the HW structure * * This inits the hardware readying it for operation. **/ static s32 igb_init_hw_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; u16 i, rar_count = mac->rar_entry_count; /* Initialize identification LED */ ret_val = igb_id_led_init(hw); if (ret_val) { hw_dbg("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ } /* Disabling VLAN filtering */ hw_dbg("Initializing the IEEE VLAN\n"); igb_clear_vfta(hw); /* Setup the receive address */ igb_init_rx_addrs(hw, rar_count); /* Zero out the Multicast HASH table */ hw_dbg("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) array_wr32(E1000_MTA, i, 0); /* Zero out the Unicast HASH table */ hw_dbg("Zeroing the UTA\n"); for (i = 0; i < mac->uta_reg_count; i++) array_wr32(E1000_UTA, i, 0); /* Setup link and flow control */ ret_val = igb_setup_link(hw); /* * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. */ igb_clear_hw_cntrs_82575(hw); return ret_val; }
/** * ixgbe_setup_mac_link_82598 - Configures MAC link settings * @hw: pointer to hardware structure * * Configures link settings based on values in the ixgbe_hw struct. * Restarts the link. Performs autonegotiation if needed. **/ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) { u32 autoc_reg; u32 links_reg; u32 i; s32 status = 0; autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); if (hw->mac.link_settings_loaded) { autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE; autoc_reg &= ~IXGBE_AUTOC_LMS_MASK; autoc_reg |= hw->mac.link_attach_type; autoc_reg |= hw->mac.link_mode_select; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); msleep(50); } /* Restart link */ autoc_reg |= IXGBE_AUTOC_AN_RESTART; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); /* Only poll for autoneg to complete if specified to do so */ if (hw->phy.autoneg_wait_to_complete) { if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN || hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { links_reg = 0; /* Just in case Autoneg time = 0 */ for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); if (links_reg & IXGBE_LINKS_KX_AN_COMP) break; msleep(100); } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; hw_dbg(hw, "Autonegotiation did not complete.\n"); } } } /* * We want to save off the original Flow Control configuration just in * case we get disconnected and then reconnected into a different hub * or switch with different Flow Control capabilities. */ hw->fc.type = hw->fc.original_type; ixgbe_setup_fc(hw, 0); /* Add delay to filter out noises during initial link setup */ msleep(50); return status; }
/** * ixgbe_read_pba_num_generic - Reads part number from EEPROM * @hw: pointer to hardware structure * @pba_num: stores the part number from the EEPROM * * Reads the part number from the EEPROM. **/ s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) { s32 ret_val; u16 data; ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); if (ret_val) { hw_dbg(hw, "NVM Read Error\n"); return ret_val; } *pba_num = (u32)(data << 16); ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data); if (ret_val) { hw_dbg(hw, "NVM Read Error\n"); return ret_val; } *pba_num |= data; return 0; }
static s32 igb_init_hw_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; u16 i, rar_count = mac->rar_entry_count; ret_val = igb_id_led_init(hw); if (ret_val) { hw_dbg("Error initializing identification LED\n"); } hw_dbg("Initializing the IEEE VLAN\n"); if (hw->mac.type == e1000_i350) igb_clear_vfta_i350(hw); else igb_clear_vfta(hw); igb_init_rx_addrs(hw, rar_count); hw_dbg("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) array_wr32(E1000_MTA, i, 0); hw_dbg("Zeroing the UTA\n"); for (i = 0; i < mac->uta_reg_count; i++) array_wr32(E1000_UTA, i, 0); ret_val = igb_setup_link(hw); igb_clear_hw_cntrs_82575(hw); return ret_val; }
static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; ctrl = rd32(E1000_CTRL); ctrl |= E1000_CTRL_SLU; ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); wr32(E1000_CTRL, ctrl); ret_val = igb_setup_serdes_link_82575(hw); if (ret_val) goto out; if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) { msleep(300); ret_val = hw->phy.ops.reset(hw); if (ret_val) { hw_dbg("Error resetting the PHY.\n"); goto out; } } switch (hw->phy.type) { case e1000_phy_m88: if (hw->phy.id == I347AT4_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID) ret_val = igb_copper_link_setup_m88_gen2(hw); else ret_val = igb_copper_link_setup_m88(hw); break; case e1000_phy_igp_3: ret_val = igb_copper_link_setup_igp(hw); break; case e1000_phy_82580: ret_val = igb_copper_link_setup_82580(hw); break; default: ret_val = -E1000_ERR_PHY; break; } if (ret_val) goto out; ret_val = igb_setup_copper_link(hw); out: return ret_val; }
static s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset) { s32 ret_val; u16 checksum = 0; u16 i, nvm_data; for (i = offset; i < (NVM_CHECKSUM_REG + offset); i++) { ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); if (ret_val) { hw_dbg("NVM Read Error while updating checksum.\n"); goto out; } checksum += nvm_data; } checksum = (u16) NVM_SUM - checksum; ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1, &checksum); if (ret_val) hw_dbg("NVM Write Error while updating checksum.\n"); out: return ret_val; }
/** * ixgbe_reset_phy_generic - Performs a PHY reset * @hw: pointer to hardware structure **/ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) { u32 i; u16 ctrl = 0; s32 status = 0; if (hw->phy.type == ixgbe_phy_unknown) status = ixgbe_identify_phy_generic(hw); if (status != 0 || hw->phy.type == ixgbe_phy_none) goto out; /* Don't reset PHY if it's shut down due to overtemp. */ if (!hw->phy.reset_if_overtemp && (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) goto out; /* * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY */ hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, MDIO_CTRL1_RESET); /* * Poll for reset bit to self-clear indicating reset is complete. * Some PHYs could take up to 3 seconds to complete and need about * 1.7 usec delay after the reset is complete. */ for (i = 0; i < 30; i++) { msleep(100); hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &ctrl); if (!(ctrl & MDIO_CTRL1_RESET)) { udelay(2); break; } } if (ctrl & MDIO_CTRL1_RESET) { status = IXGBE_ERR_RESET_FAILED; hw_dbg(hw, "PHY reset polling failed to complete.\n"); } out: return status; }
static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *hw) { s32 ret_val; hw_dbg("Soft resetting SGMII attached PHY...\n"); ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084); if (ret_val) goto out; ret_val = igb_phy_sw_reset(hw); out: return ret_val; }