diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc_base.c')
-rw-r--r-- | drivers/net/ethernet/intel/igc/igc_base.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c index 4efb47497e6b..2d49814966d3 100644 --- a/drivers/net/ethernet/intel/igc/igc_base.c +++ b/drivers/net/ethernet/intel/igc/igc_base.c @@ -54,6 +54,22 @@ out: } /** + * igc_check_for_link_base - Check for link + * @hw: pointer to the HW structure + * + * If sgmii is enabled, then use the pcs register to determine link, otherwise + * use the generic interface for determining link. + */ +static s32 igc_check_for_link_base(struct igc_hw *hw) +{ + s32 ret_val = 0; + + ret_val = igc_check_for_copper_link(hw); + + return ret_val; +} + +/** * igc_reset_hw_base - Reset hardware * @hw: pointer to the HW structure * @@ -108,11 +124,50 @@ static s32 igc_reset_hw_base(struct igc_hw *hw) } /** + * igc_init_nvm_params_base - Init NVM func ptrs. + * @hw: pointer to the HW structure + */ +static s32 igc_init_nvm_params_base(struct igc_hw *hw) +{ + struct igc_nvm_info *nvm = &hw->nvm; + u32 eecd = rd32(IGC_EECD); + u16 size; + + size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >> + IGC_EECD_SIZE_EX_SHIFT); + + /* Added to a constant, "size" becomes the left-shift value + * for setting word_size. + */ + size += NVM_WORD_SIZE_BASE_SHIFT; + + /* Just in case size is out of range, cap it to the largest + * EEPROM size supported + */ + if (size > 15) + size = 15; + + nvm->word_size = BIT(size); + nvm->opcode_bits = 8; + nvm->delay_usec = 1; + + nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8; + nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ? + 16 : 8; + + if (nvm->word_size == BIT(15)) + nvm->page_size = 128; + + return 0; +} + +/** * igc_init_mac_params_base - Init MAC func ptrs. * @hw: pointer to the HW structure */ static s32 igc_init_mac_params_base(struct igc_hw *hw) { + struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base; struct igc_mac_info *mac = &hw->mac; /* Set mta register count */ @@ -125,6 +180,10 @@ static s32 igc_init_mac_params_base(struct igc_hw *hw) mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225; mac->ops.release_swfw_sync = igc_release_swfw_sync_i225; + /* Allow a single clear of the SW semaphore on I225 */ + if (mac->type == igc_i225) + dev_spec->clear_semaphore_once = true; + return 0; } @@ -142,11 +201,44 @@ static s32 igc_get_invariants_base(struct igc_hw *hw) if (ret_val) goto out; + /* NVM initialization */ + ret_val = igc_init_nvm_params_base(hw); + switch (hw->mac.type) { + case igc_i225: + ret_val = igc_init_nvm_params_i225(hw); + break; + default: + break; + } + + if (ret_val) + goto out; + out: return ret_val; } /** + * igc_get_link_up_info_base - Get link speed/duplex info + * @hw: pointer to the HW structure + * @speed: stores the current speed + * @duplex: stores the current duplex + * + * This is a wrapper function, if using the serial gigabit media independent + * interface, use PCS to retrieve the link speed and duplex information. + * Otherwise, use the generic function to get the link speed and duplex info. + */ +static s32 igc_get_link_up_info_base(struct igc_hw *hw, u16 *speed, + u16 *duplex) +{ + s32 ret_val; + + ret_val = igc_get_speed_and_duplex_copper(hw, speed, duplex); + + return ret_val; +} + +/** * igc_init_hw_base - Initialize hardware * @hw: pointer to the HW structure * @@ -185,6 +277,19 @@ static s32 igc_init_hw_base(struct igc_hw *hw) } /** + * igc_read_mac_addr_base - Read device MAC address + * @hw: pointer to the HW structure + */ +static s32 igc_read_mac_addr_base(struct igc_hw *hw) +{ + s32 ret_val = 0; + + ret_val = igc_read_mac_addr(hw); + + return ret_val; +} + +/** * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable * @hw: pointer to the HW structure * @@ -262,6 +367,10 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw) static struct igc_mac_operations igc_mac_ops_base = { .init_hw = igc_init_hw_base, + .check_for_link = igc_check_for_link_base, + .rar_set = igc_rar_set, + .read_mac_addr = igc_read_mac_addr_base, + .get_speed_and_duplex = igc_get_link_up_info_base, }; const struct igc_info igc_base_info = { |