Loading drivers/net/igb/e1000_82575.c +280 −5 Original line number Diff line number Diff line Loading @@ -64,7 +64,14 @@ static s32 igb_reset_init_script_82575(struct e1000_hw *); static s32 igb_read_mac_addr_82575(struct e1000_hw *); static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw); static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw); static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset); static s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset); static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw); static const u16 e1000_82580_rxpbs_table[] = { 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 }; Loading Loading @@ -195,7 +202,11 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->arc_subsystem_valid = (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) ? true : false; /* enable EEE on i350 parts */ if (mac->type == e1000_i350) dev_spec->eee_disable = false; else dev_spec->eee_disable = true; /* physical interface link setup */ mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) Loading Loading @@ -233,10 +244,32 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) */ size += NVM_WORD_SIZE_BASE_SHIFT; /* EEPROM access above 16k is unsupported */ if (size > 14) size = 14; nvm->word_size = 1 << size; if (nvm->word_size == (1 << 15)) nvm->page_size = 128; /* NVM Function Pointers */ nvm->ops.acquire = igb_acquire_nvm_82575; if (nvm->word_size < (1 << 15)) nvm->ops.read = igb_read_nvm_eerd; else nvm->ops.read = igb_read_nvm_spi; nvm->ops.release = igb_release_nvm_82575; switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = igb_validate_nvm_checksum_82580; nvm->ops.update = igb_update_nvm_checksum_82580; break; case e1000_i350: nvm->ops.validate = igb_validate_nvm_checksum_i350; nvm->ops.update = igb_update_nvm_checksum_i350; break; default: nvm->ops.validate = igb_validate_nvm_checksum; nvm->ops.update = igb_update_nvm_checksum; } nvm->ops.write = igb_write_nvm_spi; /* if part supports SR-IOV then initialize mailbox parameters */ switch (mac->type) { Loading Loading @@ -1754,6 +1787,248 @@ u16 igb_rxpbs_adjust_82580(u32 data) return ret_val; } /** * igb_validate_nvm_checksum_with_offset - Validate EEPROM * checksum * @hw: pointer to the HW structure * @offset: offset in words of the checksum protected region * * Calculates the EEPROM checksum by reading/adding each word of the EEPROM * and then verifies that the sum of the EEPROM is equal to 0xBABA. **/ 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_update_nvm_checksum_with_offset - Update EEPROM * checksum * @hw: pointer to the HW structure * @offset: offset in words of the checksum protected region * * Updates the EEPROM checksum by reading/adding each word of the EEPROM * up to the checksum. Then calculates the EEPROM checksum and writes the * value to the EEPROM. **/ 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; } /** * igb_validate_nvm_checksum_82580 - Validate EEPROM checksum * @hw: pointer to the HW structure * * Calculates the EEPROM section checksum by reading/adding each word of * the EEPROM and then verifies that the sum of the EEPROM is * equal to 0xBABA. **/ 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) { /* if chekcsums compatibility bit is set validate checksums * for all 4 ports. */ 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_update_nvm_checksum_82580 - Update EEPROM checksum * @hw: pointer to the HW structure * * Updates the EEPROM section checksums for all 4 ports by reading/adding * each word of the EEPROM up to the checksum. Then calculates the EEPROM * checksum and writes the value to the EEPROM. **/ 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) { /* set compatibility bit to validate checksums appropriately */ 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_validate_nvm_checksum_i350 - Validate EEPROM checksum * @hw: pointer to the HW structure * * Calculates the EEPROM section checksum by reading/adding each word of * the EEPROM and then verifies that the sum of the EEPROM is * equal to 0xBABA. **/ static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw) { s32 ret_val = 0; u16 j; u16 nvm_offset; for (j = 0; j < 4; 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_update_nvm_checksum_i350 - Update EEPROM checksum * @hw: pointer to the HW structure * * Updates the EEPROM section checksums for all 4 ports by reading/adding * each word of the EEPROM up to the checksum. Then calculates the EEPROM * checksum and writes the value to the EEPROM. **/ static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw) { s32 ret_val = 0; u16 j; u16 nvm_offset; 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 != 0) goto out; } out: return ret_val; } /** * igb_set_eee_i350 - Enable/disable EEE support * @hw: pointer to the HW structure * * Enable/disable EEE based on setting in dev_spec structure. * **/ s32 igb_set_eee_i350(struct e1000_hw *hw) { s32 ret_val = 0; u32 ipcnfg, eeer, ctrl_ext; ctrl_ext = rd32(E1000_CTRL_EXT); if ((hw->mac.type != e1000_i350) || (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK)) goto out; ipcnfg = rd32(E1000_IPCNFG); eeer = rd32(E1000_EEER); /* enable or disable per user setting */ if (!(hw->dev_spec._82575.eee_disable)) { ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | E1000_EEER_LPI_FC); } else { ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | E1000_EEER_LPI_FC); } wr32(E1000_IPCNFG, ipcnfg); wr32(E1000_EEER, eeer); out: return ret_val; } static struct e1000_mac_operations e1000_mac_ops_82575 = { .init_hw = igb_init_hw_82575, .check_for_link = igb_check_for_link_82575, Loading drivers/net/igb/e1000_82575.h +1 −0 Original line number Diff line number Diff line Loading @@ -251,5 +251,6 @@ void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int); void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool); void igb_vmdq_set_replication_pf(struct e1000_hw *, bool); u16 igb_rxpbs_adjust_82580(u32 data); s32 igb_set_eee_i350(struct e1000_hw *); #endif drivers/net/igb/e1000_defines.h +38 −1 Original line number Diff line number Diff line Loading @@ -287,7 +287,34 @@ #define E1000_TCTL_COLD 0x003ff000 /* collision distance */ #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ /* Transmit Arbitration Count */ /* DMA Coalescing register fields */ #define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing * Watchdog Timer */ #define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Receive * Threshold */ #define E1000_DMACR_DMACTHR_SHIFT 16 #define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe * transactions */ #define E1000_DMACR_DMAC_LX_SHIFT 28 #define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ #define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit * Threshold */ #define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */ #define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Receive Traffic Rate * Threshold */ #define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rcv packet rate in * current window */ #define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rcv Traffic * Current Cnt */ #define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rcv Threshold * High val */ #define E1000_FCRTC_RTH_COAL_SHIFT 4 #define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision */ /* SerDes Control */ #define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 Loading Loading @@ -566,6 +593,8 @@ #define NVM_INIT_CONTROL3_PORT_A 0x0024 #define NVM_ALT_MAC_ADDR_PTR 0x0037 #define NVM_CHECKSUM_REG 0x003F #define NVM_COMPATIBILITY_REG_3 0x0003 #define NVM_COMPATIBILITY_BIT_MASK 0x8000 #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ Loading Loading @@ -600,6 +629,7 @@ /* NVM Commands - SPI */ #define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ #define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */ #define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */ #define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ #define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */ #define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */ Loading Loading @@ -758,6 +788,13 @@ #define E1000_MDIC_ERROR 0x40000000 #define E1000_MDIC_DEST 0x80000000 /* Energy Efficient Ethernet */ #define E1000_IPCNFG_EEE_1G_AN 0x00000008 /* EEE Enable 1G AN */ #define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* EEE Enable 100M AN */ #define E1000_EEER_TX_LPI_EN 0x00010000 /* EEE Tx LPI Enable */ #define E1000_EEER_RX_LPI_EN 0x00020000 /* EEE Rx LPI Enable */ #define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */ /* SerDes Control */ #define E1000_GEN_CTL_READY 0x80000000 #define E1000_GEN_CTL_ADDRESS_SHIFT 8 Loading drivers/net/igb/e1000_hw.h +3 −1 Original line number Diff line number Diff line Loading @@ -336,6 +336,8 @@ struct e1000_nvm_operations { s32 (*read)(struct e1000_hw *, u16, u16, u16 *); void (*release)(struct e1000_hw *); s32 (*write)(struct e1000_hw *, u16, u16, u16 *); s32 (*update)(struct e1000_hw *); s32 (*validate)(struct e1000_hw *); }; struct e1000_info { Loading Loading @@ -422,7 +424,6 @@ struct e1000_phy_info { struct e1000_nvm_info { struct e1000_nvm_operations ops; enum e1000_nvm_type type; enum e1000_nvm_override override; Loading Loading @@ -488,6 +489,7 @@ struct e1000_mbx_info { struct e1000_dev_spec_82575 { bool sgmii_active; bool global_device_reset; bool eee_disable; }; struct e1000_hw { Loading drivers/net/igb/e1000_nvm.c +63 −1 Original line number Diff line number Diff line Loading @@ -317,6 +317,68 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw) return ret_val; } /** * igb_read_nvm_spi - Read EEPROM's using SPI * @hw: pointer to the HW structure * @offset: offset of word in the EEPROM to read * @words: number of words to read * @data: word read from the EEPROM * * Reads a 16 bit word from the EEPROM. **/ s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i = 0; s32 ret_val; u16 word_in; u8 read_opcode = NVM_READ_OPCODE_SPI; /* * A check for invalid values: offset too large, too many words, * 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; } ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; ret_val = igb_ready_nvm_eeprom(hw); if (ret_val) goto release; igb_standby_nvm(hw); if ((nvm->address_bits == 8) && (offset >= 128)) read_opcode |= NVM_A8_OPCODE_SPI; /* Send the READ command (opcode + addr) */ igb_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); igb_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); /* * Read the data. SPI NVMs increment the address with each byte * read and will roll over if reading beyond the end. This allows * us to read the whole NVM from any offset */ for (i = 0; i < words; i++) { word_in = igb_shift_in_eec_bits(hw, 16); data[i] = (word_in >> 8) | (word_in << 8); } release: nvm->ops.release(hw); out: return ret_val; } /** * igb_read_nvm_eerd - Reads EEPROM using EERD register * @hw: pointer to the HW structure Loading Loading
drivers/net/igb/e1000_82575.c +280 −5 Original line number Diff line number Diff line Loading @@ -64,7 +64,14 @@ static s32 igb_reset_init_script_82575(struct e1000_hw *); static s32 igb_read_mac_addr_82575(struct e1000_hw *); static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw); static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw); static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset); static s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset); static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw); static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw); static const u16 e1000_82580_rxpbs_table[] = { 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 }; Loading Loading @@ -195,7 +202,11 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->arc_subsystem_valid = (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) ? true : false; /* enable EEE on i350 parts */ if (mac->type == e1000_i350) dev_spec->eee_disable = false; else dev_spec->eee_disable = true; /* physical interface link setup */ mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) Loading Loading @@ -233,10 +244,32 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) */ size += NVM_WORD_SIZE_BASE_SHIFT; /* EEPROM access above 16k is unsupported */ if (size > 14) size = 14; nvm->word_size = 1 << size; if (nvm->word_size == (1 << 15)) nvm->page_size = 128; /* NVM Function Pointers */ nvm->ops.acquire = igb_acquire_nvm_82575; if (nvm->word_size < (1 << 15)) nvm->ops.read = igb_read_nvm_eerd; else nvm->ops.read = igb_read_nvm_spi; nvm->ops.release = igb_release_nvm_82575; switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = igb_validate_nvm_checksum_82580; nvm->ops.update = igb_update_nvm_checksum_82580; break; case e1000_i350: nvm->ops.validate = igb_validate_nvm_checksum_i350; nvm->ops.update = igb_update_nvm_checksum_i350; break; default: nvm->ops.validate = igb_validate_nvm_checksum; nvm->ops.update = igb_update_nvm_checksum; } nvm->ops.write = igb_write_nvm_spi; /* if part supports SR-IOV then initialize mailbox parameters */ switch (mac->type) { Loading Loading @@ -1754,6 +1787,248 @@ u16 igb_rxpbs_adjust_82580(u32 data) return ret_val; } /** * igb_validate_nvm_checksum_with_offset - Validate EEPROM * checksum * @hw: pointer to the HW structure * @offset: offset in words of the checksum protected region * * Calculates the EEPROM checksum by reading/adding each word of the EEPROM * and then verifies that the sum of the EEPROM is equal to 0xBABA. **/ 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_update_nvm_checksum_with_offset - Update EEPROM * checksum * @hw: pointer to the HW structure * @offset: offset in words of the checksum protected region * * Updates the EEPROM checksum by reading/adding each word of the EEPROM * up to the checksum. Then calculates the EEPROM checksum and writes the * value to the EEPROM. **/ 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; } /** * igb_validate_nvm_checksum_82580 - Validate EEPROM checksum * @hw: pointer to the HW structure * * Calculates the EEPROM section checksum by reading/adding each word of * the EEPROM and then verifies that the sum of the EEPROM is * equal to 0xBABA. **/ 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) { /* if chekcsums compatibility bit is set validate checksums * for all 4 ports. */ 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_update_nvm_checksum_82580 - Update EEPROM checksum * @hw: pointer to the HW structure * * Updates the EEPROM section checksums for all 4 ports by reading/adding * each word of the EEPROM up to the checksum. Then calculates the EEPROM * checksum and writes the value to the EEPROM. **/ 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) { /* set compatibility bit to validate checksums appropriately */ 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_validate_nvm_checksum_i350 - Validate EEPROM checksum * @hw: pointer to the HW structure * * Calculates the EEPROM section checksum by reading/adding each word of * the EEPROM and then verifies that the sum of the EEPROM is * equal to 0xBABA. **/ static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw) { s32 ret_val = 0; u16 j; u16 nvm_offset; for (j = 0; j < 4; 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_update_nvm_checksum_i350 - Update EEPROM checksum * @hw: pointer to the HW structure * * Updates the EEPROM section checksums for all 4 ports by reading/adding * each word of the EEPROM up to the checksum. Then calculates the EEPROM * checksum and writes the value to the EEPROM. **/ static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw) { s32 ret_val = 0; u16 j; u16 nvm_offset; 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 != 0) goto out; } out: return ret_val; } /** * igb_set_eee_i350 - Enable/disable EEE support * @hw: pointer to the HW structure * * Enable/disable EEE based on setting in dev_spec structure. * **/ s32 igb_set_eee_i350(struct e1000_hw *hw) { s32 ret_val = 0; u32 ipcnfg, eeer, ctrl_ext; ctrl_ext = rd32(E1000_CTRL_EXT); if ((hw->mac.type != e1000_i350) || (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK)) goto out; ipcnfg = rd32(E1000_IPCNFG); eeer = rd32(E1000_EEER); /* enable or disable per user setting */ if (!(hw->dev_spec._82575.eee_disable)) { ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | E1000_EEER_LPI_FC); } else { ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | E1000_EEER_LPI_FC); } wr32(E1000_IPCNFG, ipcnfg); wr32(E1000_EEER, eeer); out: return ret_val; } static struct e1000_mac_operations e1000_mac_ops_82575 = { .init_hw = igb_init_hw_82575, .check_for_link = igb_check_for_link_82575, Loading
drivers/net/igb/e1000_82575.h +1 −0 Original line number Diff line number Diff line Loading @@ -251,5 +251,6 @@ void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int); void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool); void igb_vmdq_set_replication_pf(struct e1000_hw *, bool); u16 igb_rxpbs_adjust_82580(u32 data); s32 igb_set_eee_i350(struct e1000_hw *); #endif
drivers/net/igb/e1000_defines.h +38 −1 Original line number Diff line number Diff line Loading @@ -287,7 +287,34 @@ #define E1000_TCTL_COLD 0x003ff000 /* collision distance */ #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ /* Transmit Arbitration Count */ /* DMA Coalescing register fields */ #define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing * Watchdog Timer */ #define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Receive * Threshold */ #define E1000_DMACR_DMACTHR_SHIFT 16 #define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe * transactions */ #define E1000_DMACR_DMAC_LX_SHIFT 28 #define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ #define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit * Threshold */ #define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */ #define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Receive Traffic Rate * Threshold */ #define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rcv packet rate in * current window */ #define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rcv Traffic * Current Cnt */ #define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rcv Threshold * High val */ #define E1000_FCRTC_RTH_COAL_SHIFT 4 #define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision */ /* SerDes Control */ #define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 Loading Loading @@ -566,6 +593,8 @@ #define NVM_INIT_CONTROL3_PORT_A 0x0024 #define NVM_ALT_MAC_ADDR_PTR 0x0037 #define NVM_CHECKSUM_REG 0x003F #define NVM_COMPATIBILITY_REG_3 0x0003 #define NVM_COMPATIBILITY_BIT_MASK 0x8000 #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ Loading Loading @@ -600,6 +629,7 @@ /* NVM Commands - SPI */ #define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ #define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */ #define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */ #define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ #define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */ #define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */ Loading Loading @@ -758,6 +788,13 @@ #define E1000_MDIC_ERROR 0x40000000 #define E1000_MDIC_DEST 0x80000000 /* Energy Efficient Ethernet */ #define E1000_IPCNFG_EEE_1G_AN 0x00000008 /* EEE Enable 1G AN */ #define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* EEE Enable 100M AN */ #define E1000_EEER_TX_LPI_EN 0x00010000 /* EEE Tx LPI Enable */ #define E1000_EEER_RX_LPI_EN 0x00020000 /* EEE Rx LPI Enable */ #define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */ /* SerDes Control */ #define E1000_GEN_CTL_READY 0x80000000 #define E1000_GEN_CTL_ADDRESS_SHIFT 8 Loading
drivers/net/igb/e1000_hw.h +3 −1 Original line number Diff line number Diff line Loading @@ -336,6 +336,8 @@ struct e1000_nvm_operations { s32 (*read)(struct e1000_hw *, u16, u16, u16 *); void (*release)(struct e1000_hw *); s32 (*write)(struct e1000_hw *, u16, u16, u16 *); s32 (*update)(struct e1000_hw *); s32 (*validate)(struct e1000_hw *); }; struct e1000_info { Loading Loading @@ -422,7 +424,6 @@ struct e1000_phy_info { struct e1000_nvm_info { struct e1000_nvm_operations ops; enum e1000_nvm_type type; enum e1000_nvm_override override; Loading Loading @@ -488,6 +489,7 @@ struct e1000_mbx_info { struct e1000_dev_spec_82575 { bool sgmii_active; bool global_device_reset; bool eee_disable; }; struct e1000_hw { Loading
drivers/net/igb/e1000_nvm.c +63 −1 Original line number Diff line number Diff line Loading @@ -317,6 +317,68 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw) return ret_val; } /** * igb_read_nvm_spi - Read EEPROM's using SPI * @hw: pointer to the HW structure * @offset: offset of word in the EEPROM to read * @words: number of words to read * @data: word read from the EEPROM * * Reads a 16 bit word from the EEPROM. **/ s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i = 0; s32 ret_val; u16 word_in; u8 read_opcode = NVM_READ_OPCODE_SPI; /* * A check for invalid values: offset too large, too many words, * 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; } ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; ret_val = igb_ready_nvm_eeprom(hw); if (ret_val) goto release; igb_standby_nvm(hw); if ((nvm->address_bits == 8) && (offset >= 128)) read_opcode |= NVM_A8_OPCODE_SPI; /* Send the READ command (opcode + addr) */ igb_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); igb_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); /* * Read the data. SPI NVMs increment the address with each byte * read and will roll over if reading beyond the end. This allows * us to read the whole NVM from any offset */ for (i = 0; i < words; i++) { word_in = igb_shift_in_eec_bits(hw, 16); data[i] = (word_in >> 8) | (word_in << 8); } release: nvm->ops.release(hw); out: return ret_val; } /** * igb_read_nvm_eerd - Reads EEPROM using EERD register * @hw: pointer to the HW structure Loading