Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixgbe/ixgbe_common.c
| /****************************************************************************** | /****************************************************************************** | ||||
| Copyright (c) 2001-2015, Intel Corporation | Copyright (c) 2001-2017, Intel Corporation | ||||
| All rights reserved. | All rights reserved. | ||||
| Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | modification, are permitted provided that the following conditions are met: | ||||
| 1. Redistributions of source code must retain the above copyright notice, | 1. Redistributions of source code must retain the above copyright notice, | ||||
| this list of conditions and the following disclaimer. | this list of conditions and the following disclaimer. | ||||
| 2. Redistributions in binary form must reproduce the above copyright | 2. Redistributions in binary form must reproduce the above copyright | ||||
| notice, this list of conditions and the following disclaimer in the | notice, this list of conditions and the following disclaimer in the | ||||
| documentation and/or other materials provided with the distribution. | documentation and/or other materials provided with the distribution. | ||||
| 3. Neither the name of the Intel Corporation nor the names of its | 3. Neither the name of the Intel Corporation nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | this software without specific prior written permission. | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||||
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | ||||
| ******************************************************************************/ | ******************************************************************************/ | ||||
| /*$FreeBSD$*/ | /*$FreeBSD$*/ | ||||
| #include "ixgbe_common.h" | #include "ixgbe_common.h" | ||||
| #include "ixgbe_phy.h" | #include "ixgbe_phy.h" | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) | ||||
| mac->ops.prot_autoc_read = prot_autoc_read_generic; | mac->ops.prot_autoc_read = prot_autoc_read_generic; | ||||
| mac->ops.prot_autoc_write = prot_autoc_write_generic; | mac->ops.prot_autoc_write = prot_autoc_write_generic; | ||||
| /* LEDs */ | /* LEDs */ | ||||
| mac->ops.led_on = ixgbe_led_on_generic; | mac->ops.led_on = ixgbe_led_on_generic; | ||||
| mac->ops.led_off = ixgbe_led_off_generic; | mac->ops.led_off = ixgbe_led_off_generic; | ||||
| mac->ops.blink_led_start = ixgbe_blink_led_start_generic; | mac->ops.blink_led_start = ixgbe_blink_led_start_generic; | ||||
| mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic; | mac->ops.blink_led_stop = ixgbe_blink_led_stop_generic; | ||||
| mac->ops.init_led_link_act = ixgbe_init_led_link_act_generic; | |||||
| /* RAR, Multicast, VLAN */ | /* RAR, Multicast, VLAN */ | ||||
| mac->ops.set_rar = ixgbe_set_rar_generic; | mac->ops.set_rar = ixgbe_set_rar_generic; | ||||
| mac->ops.clear_rar = ixgbe_clear_rar_generic; | mac->ops.clear_rar = ixgbe_clear_rar_generic; | ||||
| mac->ops.insert_mac_addr = NULL; | mac->ops.insert_mac_addr = NULL; | ||||
| mac->ops.set_vmdq = NULL; | mac->ops.set_vmdq = NULL; | ||||
| mac->ops.clear_vmdq = NULL; | mac->ops.clear_vmdq = NULL; | ||||
| mac->ops.init_rx_addrs = ixgbe_init_rx_addrs_generic; | mac->ops.init_rx_addrs = ixgbe_init_rx_addrs_generic; | ||||
| mac->ops.update_uc_addr_list = ixgbe_update_uc_addr_list_generic; | mac->ops.update_uc_addr_list = ixgbe_update_uc_addr_list_generic; | ||||
| mac->ops.update_mc_addr_list = ixgbe_update_mc_addr_list_generic; | mac->ops.update_mc_addr_list = ixgbe_update_mc_addr_list_generic; | ||||
| mac->ops.enable_mc = ixgbe_enable_mc_generic; | mac->ops.enable_mc = ixgbe_enable_mc_generic; | ||||
| mac->ops.disable_mc = ixgbe_disable_mc_generic; | mac->ops.disable_mc = ixgbe_disable_mc_generic; | ||||
| mac->ops.clear_vfta = NULL; | mac->ops.clear_vfta = NULL; | ||||
| mac->ops.set_vfta = NULL; | mac->ops.set_vfta = NULL; | ||||
| mac->ops.set_vlvf = NULL; | mac->ops.set_vlvf = NULL; | ||||
| mac->ops.init_uta_tables = NULL; | mac->ops.init_uta_tables = NULL; | ||||
| mac->ops.enable_rx = ixgbe_enable_rx_generic; | mac->ops.enable_rx = ixgbe_enable_rx_generic; | ||||
| mac->ops.disable_rx = ixgbe_disable_rx_generic; | mac->ops.disable_rx = ixgbe_disable_rx_generic; | ||||
| /* Flow Control */ | /* Flow Control */ | ||||
| mac->ops.fc_enable = ixgbe_fc_enable_generic; | mac->ops.fc_enable = ixgbe_fc_enable_generic; | ||||
| mac->ops.setup_fc = ixgbe_setup_fc_generic; | mac->ops.setup_fc = ixgbe_setup_fc_generic; | ||||
| mac->ops.fc_autoneg = ixgbe_fc_autoneg; | |||||
| /* Link */ | /* Link */ | ||||
| mac->ops.get_link_capabilities = NULL; | mac->ops.get_link_capabilities = NULL; | ||||
| mac->ops.setup_link = NULL; | mac->ops.setup_link = NULL; | ||||
| mac->ops.check_link = NULL; | mac->ops.check_link = NULL; | ||||
| mac->ops.dmac_config = NULL; | mac->ops.dmac_config = NULL; | ||||
| mac->ops.dmac_update_tcs = NULL; | mac->ops.dmac_update_tcs = NULL; | ||||
| mac->ops.dmac_config_tcs = NULL; | mac->ops.dmac_config_tcs = NULL; | ||||
| Show All 17 Lines | bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) | ||||
| bool link_up; | bool link_up; | ||||
| DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); | DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); | ||||
| switch (hw->phy.media_type) { | switch (hw->phy.media_type) { | ||||
| case ixgbe_media_type_fiber_fixed: | case ixgbe_media_type_fiber_fixed: | ||||
| case ixgbe_media_type_fiber_qsfp: | case ixgbe_media_type_fiber_qsfp: | ||||
| case ixgbe_media_type_fiber: | case ixgbe_media_type_fiber: | ||||
| /* flow control autoneg black list */ | |||||
| switch (hw->device_id) { | |||||
| case IXGBE_DEV_ID_X550EM_A_SFP: | |||||
| case IXGBE_DEV_ID_X550EM_A_SFP_N: | |||||
| case IXGBE_DEV_ID_X550EM_A_QSFP: | |||||
| case IXGBE_DEV_ID_X550EM_A_QSFP_N: | |||||
| supported = FALSE; | |||||
| break; | |||||
| default: | |||||
| hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); | hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); | ||||
| /* if link is down, assume supported */ | /* if link is down, assume supported */ | ||||
| if (link_up) | if (link_up) | ||||
| supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? | supported = speed == IXGBE_LINK_SPEED_1GB_FULL ? | ||||
| TRUE : FALSE; | TRUE : FALSE; | ||||
| else | else | ||||
| supported = TRUE; | supported = TRUE; | ||||
| } | |||||
| break; | break; | ||||
| case ixgbe_media_type_backplane: | case ixgbe_media_type_backplane: | ||||
| if (hw->device_id == IXGBE_DEV_ID_X550EM_X_XFI) | |||||
| supported = FALSE; | |||||
| else | |||||
| supported = TRUE; | supported = TRUE; | ||||
| break; | break; | ||||
| case ixgbe_media_type_copper: | case ixgbe_media_type_copper: | ||||
| /* only some copper devices support flow control autoneg */ | /* only some copper devices support flow control autoneg */ | ||||
| switch (hw->device_id) { | switch (hw->device_id) { | ||||
| case IXGBE_DEV_ID_82599_T3_LOM: | case IXGBE_DEV_ID_82599_T3_LOM: | ||||
| case IXGBE_DEV_ID_X540T: | case IXGBE_DEV_ID_X540T: | ||||
| case IXGBE_DEV_ID_X540T1: | case IXGBE_DEV_ID_X540T1: | ||||
| case IXGBE_DEV_ID_X540_BYPASS: | case IXGBE_DEV_ID_X540_BYPASS: | ||||
| case IXGBE_DEV_ID_X550T: | case IXGBE_DEV_ID_X550T: | ||||
| case IXGBE_DEV_ID_X550T1: | case IXGBE_DEV_ID_X550T1: | ||||
| case IXGBE_DEV_ID_X550EM_X_10G_T: | case IXGBE_DEV_ID_X550EM_X_10G_T: | ||||
| case IXGBE_DEV_ID_X550EM_A_10G_T: | |||||
| case IXGBE_DEV_ID_X550EM_A_1G_T: | |||||
| case IXGBE_DEV_ID_X550EM_A_1G_T_L: | |||||
| supported = TRUE; | supported = TRUE; | ||||
| break; | break; | ||||
| default: | default: | ||||
| supported = FALSE; | supported = FALSE; | ||||
| } | } | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | |||||
| * all on chip counters, initializes receive address registers, multicast | * all on chip counters, initializes receive address registers, multicast | ||||
| * table, VLAN filter table, calls routine to set up link and flow control | * table, VLAN filter table, calls routine to set up link and flow control | ||||
| * settings, and leaves transmit and receive units disabled and uninitialized | * settings, and leaves transmit and receive units disabled and uninitialized | ||||
| **/ | **/ | ||||
| s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) | s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) | ||||
| { | { | ||||
| s32 ret_val; | s32 ret_val; | ||||
| u32 ctrl_ext; | u32 ctrl_ext; | ||||
| u16 device_caps; | |||||
| DEBUGFUNC("ixgbe_start_hw_generic"); | DEBUGFUNC("ixgbe_start_hw_generic"); | ||||
| /* Set the media type */ | /* Set the media type */ | ||||
| hw->phy.media_type = hw->mac.ops.get_media_type(hw); | hw->phy.media_type = hw->mac.ops.get_media_type(hw); | ||||
| /* PHY ops initialization must be done in reset_hw() */ | /* PHY ops initialization must be done in reset_hw() */ | ||||
| /* Clear the VLAN filter table */ | /* Clear the VLAN filter table */ | ||||
| hw->mac.ops.clear_vfta(hw); | hw->mac.ops.clear_vfta(hw); | ||||
| /* Clear statistics registers */ | /* Clear statistics registers */ | ||||
| hw->mac.ops.clear_hw_cntrs(hw); | hw->mac.ops.clear_hw_cntrs(hw); | ||||
| /* Set No Snoop Disable */ | /* Set No Snoop Disable */ | ||||
| ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); | ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); | ||||
| ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; | ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; | ||||
| IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); | IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); | ||||
| IXGBE_WRITE_FLUSH(hw); | IXGBE_WRITE_FLUSH(hw); | ||||
| /* Setup flow control */ | /* Setup flow control */ | ||||
| ret_val = ixgbe_setup_fc(hw); | ret_val = ixgbe_setup_fc(hw); | ||||
| if (ret_val != IXGBE_SUCCESS) | if (ret_val != IXGBE_SUCCESS && ret_val != IXGBE_NOT_IMPLEMENTED) { | ||||
| goto out; | DEBUGOUT1("Flow control setup failed, returning %d\n", ret_val); | ||||
| return ret_val; | |||||
smh: bracing | |||||
| } | |||||
| /* Cache bit indicating need for crosstalk fix */ | |||||
| switch (hw->mac.type) { | |||||
| case ixgbe_mac_82599EB: | |||||
| case ixgbe_mac_X550EM_x: | |||||
| case ixgbe_mac_X550EM_a: | |||||
| hw->mac.ops.get_device_caps(hw, &device_caps); | |||||
| if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR) | |||||
Not Done Inline Actions!= 0 smh: != 0 | |||||
| hw->need_crosstalk_fix = FALSE; | |||||
| else | |||||
| hw->need_crosstalk_fix = TRUE; | |||||
| break; | |||||
| default: | |||||
| hw->need_crosstalk_fix = FALSE; | |||||
| break; | |||||
| } | |||||
| /* Clear adapter stopped flag */ | /* Clear adapter stopped flag */ | ||||
| hw->adapter_stopped = FALSE; | hw->adapter_stopped = FALSE; | ||||
| out: | return IXGBE_SUCCESS; | ||||
Not Done Inline Actionsbracing smh: bracing | |||||
| return ret_val; | |||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_start_hw_gen2 - Init sequence for common device family | * ixgbe_start_hw_gen2 - Init sequence for common device family | ||||
| * @hw: pointer to hw structure | * @hw: pointer to hw structure | ||||
| * | * | ||||
| * Performs the init sequence common to the second generation | * Performs the init sequence common to the second generation | ||||
| * of 10 GbE devices. | * of 10 GbE devices. | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| s32 status; | s32 status; | ||||
| DEBUGFUNC("ixgbe_init_hw_generic"); | DEBUGFUNC("ixgbe_init_hw_generic"); | ||||
| /* Reset the hardware */ | /* Reset the hardware */ | ||||
| status = hw->mac.ops.reset_hw(hw); | status = hw->mac.ops.reset_hw(hw); | ||||
| if (status == IXGBE_SUCCESS) { | if (status == IXGBE_SUCCESS || status == IXGBE_ERR_SFP_NOT_PRESENT) { | ||||
| /* Start the HW */ | /* Start the HW */ | ||||
| status = hw->mac.ops.start_hw(hw); | status = hw->mac.ops.start_hw(hw); | ||||
| } | } | ||||
| /* Initialize the LED link active for LED blink support */ | |||||
| hw->mac.ops.init_led_link_act(hw); | |||||
| if (status != IXGBE_SUCCESS) | |||||
| DEBUGOUT1("Failed to initialize HW, STATUS = %d\n", status); | |||||
| return status; | return status; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters | * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * | * | ||||
| * Clears all hardware statistics counters by reading them from the hardware | * Clears all hardware statistics counters by reading them from the hardware | ||||
| ▲ Show 20 Lines • Show All 539 Lines • ▼ Show 20 Lines | s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) | ||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices | * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices | ||||
| * @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
| * | * | ||||
| * Determines the LAN function id by reading memory-mapped registers | * Determines the LAN function id by reading memory-mapped registers and swaps | ||||
| * and swaps the port value if requested. | * the port value if requested, and set MAC instance for devices that share | ||||
| * CS4227. | |||||
| **/ | **/ | ||||
| void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) | void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) | ||||
| { | { | ||||
| struct ixgbe_bus_info *bus = &hw->bus; | struct ixgbe_bus_info *bus = &hw->bus; | ||||
| u32 reg; | u32 reg; | ||||
| u16 ee_ctrl_4; | |||||
| DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); | DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); | ||||
| reg = IXGBE_READ_REG(hw, IXGBE_STATUS); | reg = IXGBE_READ_REG(hw, IXGBE_STATUS); | ||||
| bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; | bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; | ||||
| bus->lan_id = bus->func; | bus->lan_id = (u8)bus->func; | ||||
| /* check for a port swap */ | /* check for a port swap */ | ||||
| reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); | reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw)); | ||||
| if (reg & IXGBE_FACTPS_LFS) | if (reg & IXGBE_FACTPS_LFS) | ||||
| bus->func ^= 0x1; | bus->func ^= 0x1; | ||||
| /* Get MAC instance from EEPROM for configuring CS4227 */ | |||||
| if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP) { | |||||
| hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_4, &ee_ctrl_4); | |||||
| bus->instance_id = (ee_ctrl_4 & IXGBE_EE_CTRL_4_INST_ID) >> | |||||
| IXGBE_EE_CTRL_4_INST_ID_SHIFT; | |||||
| } | } | ||||
| } | |||||
| /** | /** | ||||
| * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units | * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * | * | ||||
| * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, | * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, | ||||
| * disables transmit and receive units. The adapter_stopped flag is used by | * disables transmit and receive units. The adapter_stopped flag is used by | ||||
| * the shared code and drivers to determine if the adapter is in a stopped | * the shared code and drivers to determine if the adapter is in a stopped | ||||
| Show All 40 Lines | s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) | ||||
| /* | /* | ||||
| * Prevent the PCI-E bus from hanging by disabling PCI-E master | * Prevent the PCI-E bus from hanging by disabling PCI-E master | ||||
| * access and verify no pending requests | * access and verify no pending requests | ||||
| */ | */ | ||||
| return ixgbe_disable_pcie_master(hw); | return ixgbe_disable_pcie_master(hw); | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_init_led_link_act_generic - Store the LED index link/activity. | |||||
| * @hw: pointer to hardware structure | |||||
| * | |||||
| * Store the index for the link active LED. This will be used to support | |||||
| * blinking the LED. | |||||
| **/ | |||||
| s32 ixgbe_init_led_link_act_generic(struct ixgbe_hw *hw) | |||||
| { | |||||
| struct ixgbe_mac_info *mac = &hw->mac; | |||||
| u32 led_reg, led_mode; | |||||
| u8 i; | |||||
| led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | |||||
| /* Get LED link active from the LEDCTL register */ | |||||
| for (i = 0; i < 4; i++) { | |||||
| led_mode = led_reg >> IXGBE_LED_MODE_SHIFT(i); | |||||
| if ((led_mode & IXGBE_LED_MODE_MASK_BASE) == | |||||
| IXGBE_LED_LINK_ACTIVE) { | |||||
| mac->led_link_act = i; | |||||
| return IXGBE_SUCCESS; | |||||
| } | |||||
| } | |||||
| /* | |||||
| * If LEDCTL register does not have the LED link active set, then use | |||||
| * known MAC defaults. | |||||
| */ | |||||
| switch (hw->mac.type) { | |||||
| case ixgbe_mac_X550EM_a: | |||||
| case ixgbe_mac_X550EM_x: | |||||
| mac->led_link_act = 1; | |||||
| break; | |||||
| default: | |||||
| mac->led_link_act = 2; | |||||
| } | |||||
| return IXGBE_SUCCESS; | |||||
Not Done Inline Actionsbracing more below. smh: bracing more below. | |||||
| } | |||||
| /** | |||||
| * ixgbe_led_on_generic - Turns on the software controllable LEDs. | * ixgbe_led_on_generic - Turns on the software controllable LEDs. | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @index: led number to turn on | * @index: led number to turn on | ||||
| **/ | **/ | ||||
| s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) | s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) | ||||
| { | { | ||||
| u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||||
| DEBUGFUNC("ixgbe_led_on_generic"); | DEBUGFUNC("ixgbe_led_on_generic"); | ||||
| if (index > 3) | |||||
| return IXGBE_ERR_PARAM; | |||||
| /* To turn on the LED, set mode to ON. */ | /* To turn on the LED, set mode to ON. */ | ||||
| led_reg &= ~IXGBE_LED_MODE_MASK(index); | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||||
| led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); | led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); | ||||
| IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||||
| IXGBE_WRITE_FLUSH(hw); | IXGBE_WRITE_FLUSH(hw); | ||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_led_off_generic - Turns off the software controllable LEDs. | * ixgbe_led_off_generic - Turns off the software controllable LEDs. | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @index: led number to turn off | * @index: led number to turn off | ||||
| **/ | **/ | ||||
| s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) | s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) | ||||
| { | { | ||||
| u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||||
| DEBUGFUNC("ixgbe_led_off_generic"); | DEBUGFUNC("ixgbe_led_off_generic"); | ||||
| if (index > 3) | |||||
| return IXGBE_ERR_PARAM; | |||||
| /* To turn off the LED, set mode to OFF. */ | /* To turn off the LED, set mode to OFF. */ | ||||
| led_reg &= ~IXGBE_LED_MODE_MASK(index); | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||||
| led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); | led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); | ||||
| IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||||
| IXGBE_WRITE_FLUSH(hw); | IXGBE_WRITE_FLUSH(hw); | ||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,259 Lines • ▼ Show 20 Lines | if (ixgbe_validate_mac_addr(hw->mac.addr) == | ||||
| DEBUGOUT("Overriding MAC Address in RAR[0]\n"); | DEBUGOUT("Overriding MAC Address in RAR[0]\n"); | ||||
| DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ", | DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ", | ||||
| hw->mac.addr[0], hw->mac.addr[1], | hw->mac.addr[0], hw->mac.addr[1], | ||||
| hw->mac.addr[2]); | hw->mac.addr[2]); | ||||
| DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], | DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], | ||||
| hw->mac.addr[4], hw->mac.addr[5]); | hw->mac.addr[4], hw->mac.addr[5]); | ||||
| hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); | ||||
| } | |||||
| /* clear VMDq pool/queue selection for RAR 0 */ | /* clear VMDq pool/queue selection for RAR 0 */ | ||||
| hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); | hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); | ||||
| } | |||||
| hw->addr_ctrl.overflow_promisc = 0; | hw->addr_ctrl.overflow_promisc = 0; | ||||
| hw->addr_ctrl.rar_used_count = 1; | hw->addr_ctrl.rar_used_count = 1; | ||||
| /* Zero out the other receive addresses. */ | /* Zero out the other receive addresses. */ | ||||
| DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1); | DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1); | ||||
| for (i = 1; i < rar_entries; i++) { | for (i = 1; i < rar_entries; i++) { | ||||
| IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); | IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); | ||||
| ▲ Show 20 Lines • Show All 312 Lines • ▼ Show 20 Lines | if ((hw->fc.current_mode & ixgbe_fc_tx_pause) && | ||||
| DEBUGOUT("Invalid water mark configuration\n"); | DEBUGOUT("Invalid water mark configuration\n"); | ||||
| ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | ||||
| goto out; | goto out; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Negotiate the fc mode to use */ | /* Negotiate the fc mode to use */ | ||||
| ixgbe_fc_autoneg(hw); | hw->mac.ops.fc_autoneg(hw); | ||||
| /* Disable any previous flow control settings */ | /* Disable any previous flow control settings */ | ||||
| mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); | mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); | ||||
| mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE); | mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE); | ||||
| fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); | fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); | ||||
| fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); | fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | |||||
| * @adv_sym: symmetric pause bit in advertisement | * @adv_sym: symmetric pause bit in advertisement | ||||
| * @adv_asm: asymmetric pause bit in advertisement | * @adv_asm: asymmetric pause bit in advertisement | ||||
| * @lp_sym: symmetric pause bit in link partner advertisement | * @lp_sym: symmetric pause bit in link partner advertisement | ||||
| * @lp_asm: asymmetric pause bit in link partner advertisement | * @lp_asm: asymmetric pause bit in link partner advertisement | ||||
| * | * | ||||
| * Find the intersection between advertised settings and link partner's | * Find the intersection between advertised settings and link partner's | ||||
| * advertised settings | * advertised settings | ||||
| **/ | **/ | ||||
| static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, | s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, | ||||
| u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) | u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) | ||||
| { | { | ||||
| if ((!(adv_reg)) || (!(lp_reg))) { | if ((!(adv_reg)) || (!(lp_reg))) { | ||||
| ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED, | ERROR_REPORT3(IXGBE_ERROR_UNSUPPORTED, | ||||
| "Local or link partner's advertised flow control " | "Local or link partner's advertised flow control " | ||||
| "settings are NULL. Local: %x, link partner: %x\n", | "settings are NULL. Local: %x, link partner: %x\n", | ||||
| adv_reg, lp_reg); | adv_reg, lp_reg); | ||||
| return IXGBE_ERR_FC_NOT_NEGOTIATED; | return IXGBE_ERR_FC_NOT_NEGOTIATED; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 456 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * ixgbe_enable_sec_rx_path_generic - Enables the receive data path | * ixgbe_enable_sec_rx_path_generic - Enables the receive data path | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * | * | ||||
| * Enables the receive data path. | * Enables the receive data path. | ||||
| **/ | **/ | ||||
| s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw) | s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw) | ||||
| { | { | ||||
| int secrxreg; | u32 secrxreg; | ||||
| DEBUGFUNC("ixgbe_enable_sec_rx_path_generic"); | DEBUGFUNC("ixgbe_enable_sec_rx_path_generic"); | ||||
| secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); | secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); | ||||
| secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS; | secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS; | ||||
| IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg); | IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg); | ||||
| IXGBE_WRITE_FLUSH(hw); | IXGBE_WRITE_FLUSH(hw); | ||||
| Show All 30 Lines | s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) | ||||
| bool link_up = 0; | bool link_up = 0; | ||||
| u32 autoc_reg = 0; | u32 autoc_reg = 0; | ||||
| u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||||
| s32 ret_val = IXGBE_SUCCESS; | s32 ret_val = IXGBE_SUCCESS; | ||||
| bool locked = FALSE; | bool locked = FALSE; | ||||
| DEBUGFUNC("ixgbe_blink_led_start_generic"); | DEBUGFUNC("ixgbe_blink_led_start_generic"); | ||||
| if (index > 3) | |||||
| return IXGBE_ERR_PARAM; | |||||
| /* | /* | ||||
| * Link must be up to auto-blink the LEDs; | * Link must be up to auto-blink the LEDs; | ||||
| * Force it if link is down. | * Force it if link is down. | ||||
| */ | */ | ||||
| hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); | hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); | ||||
| if (!link_up) { | if (!link_up) { | ||||
| ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); | ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); | ||||
| Show All 29 Lines | |||||
| { | { | ||||
| u32 autoc_reg = 0; | u32 autoc_reg = 0; | ||||
| u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||||
| s32 ret_val = IXGBE_SUCCESS; | s32 ret_val = IXGBE_SUCCESS; | ||||
| bool locked = FALSE; | bool locked = FALSE; | ||||
| DEBUGFUNC("ixgbe_blink_led_stop_generic"); | DEBUGFUNC("ixgbe_blink_led_stop_generic"); | ||||
| if (index > 3) | |||||
| return IXGBE_ERR_PARAM; | |||||
| ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); | ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); | ||||
| if (ret_val != IXGBE_SUCCESS) | if (ret_val != IXGBE_SUCCESS) | ||||
| goto out; | goto out; | ||||
| autoc_reg &= ~IXGBE_AUTOC_FLU; | autoc_reg &= ~IXGBE_AUTOC_FLU; | ||||
| autoc_reg |= IXGBE_AUTOC_AN_RESTART; | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | ||||
| ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked); | ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked); | ||||
| ▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) | ||||
| case ixgbe_mac_82598EB: | case ixgbe_mac_82598EB: | ||||
| pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS; | pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS; | ||||
| max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598; | max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598; | ||||
| break; | break; | ||||
| case ixgbe_mac_82599EB: | case ixgbe_mac_82599EB: | ||||
| case ixgbe_mac_X540: | case ixgbe_mac_X540: | ||||
| case ixgbe_mac_X550: | case ixgbe_mac_X550: | ||||
| case ixgbe_mac_X550EM_x: | case ixgbe_mac_X550EM_x: | ||||
| case ixgbe_mac_X550EM_a: | |||||
| pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; | pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; | ||||
| max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; | max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; | ||||
| break; | break; | ||||
| default: | default: | ||||
| return msix_count; | return msix_count; | ||||
| } | } | ||||
| DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); | DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); | ||||
| ▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { | ||||
| mpsar_lo &= ~(1 << vmdq); | mpsar_lo &= ~(1 << vmdq); | ||||
| IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); | ||||
| } else { | } else { | ||||
| mpsar_hi &= ~(1 << (vmdq - 32)); | mpsar_hi &= ~(1 << (vmdq - 32)); | ||||
| IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); | ||||
| } | } | ||||
| /* was that the last pool using this rar? */ | /* was that the last pool using this rar? */ | ||||
| if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) | if (mpsar_lo == 0 && mpsar_hi == 0 && | ||||
| rar != 0 && rar != hw->mac.san_mac_rar_index) | |||||
| hw->mac.ops.clear_rar(hw, rar); | hw->mac.ops.clear_rar(hw, rar); | ||||
| done: | done: | ||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address | * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address | ||||
| * @hw: pointer to hardware struct | * @hw: pointer to hardware struct | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot | * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @vlan: VLAN id to write to VLAN filter | * @vlan: VLAN id to write to VLAN filter | ||||
| * | * | ||||
| * return the VLVF index where this VLAN id should be placed | * return the VLVF index where this VLAN id should be placed | ||||
| * | * | ||||
| **/ | **/ | ||||
| s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) | s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass) | ||||
| { | { | ||||
| u32 bits = 0; | s32 regindex, first_empty_slot; | ||||
| u32 first_empty_slot = 0; | u32 bits; | ||||
| s32 regindex; | |||||
| /* short cut the special case */ | /* short cut the special case */ | ||||
| if (vlan == 0) | if (vlan == 0) | ||||
| return 0; | return 0; | ||||
| /* | /* if vlvf_bypass is set we don't want to use an empty slot, we | ||||
| * Search for the vlan id in the VLVF entries. Save off the first empty | * will simply bypass the VLVF if there are no entries present in the | ||||
| * slot found along the way | * VLVF that contain our VLAN | ||||
| */ | */ | ||||
| for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { | first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0; | ||||
| /* add VLAN enable bit for comparison */ | |||||
| vlan |= IXGBE_VLVF_VIEN; | |||||
| /* Search for the vlan id in the VLVF entries. Save off the first empty | |||||
| * slot found along the way. | |||||
| * | |||||
| * pre-decrement loop covering (IXGBE_VLVF_ENTRIES - 1) .. 1 | |||||
| */ | |||||
| for (regindex = IXGBE_VLVF_ENTRIES; --regindex;) { | |||||
| bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); | bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); | ||||
| if (!bits && !(first_empty_slot)) | if (bits == vlan) | ||||
| return regindex; | |||||
| if (!first_empty_slot && !bits) | |||||
| first_empty_slot = regindex; | first_empty_slot = regindex; | ||||
| else if ((bits & 0x0FFF) == vlan) | |||||
| break; | |||||
| } | } | ||||
| /* | /* If we are here then we didn't find the VLAN. Return first empty | ||||
| * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan | * slot we found during our search, else error. | ||||
| * in the VLVF. Else use the first empty VLVF register for this | |||||
| * vlan id. | |||||
| */ | */ | ||||
| if (regindex >= IXGBE_VLVF_ENTRIES) { | if (!first_empty_slot) | ||||
| if (first_empty_slot) | ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "No space in VLVF.\n"); | ||||
| regindex = first_empty_slot; | |||||
| else { | |||||
| ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, | |||||
| "No space in VLVF.\n"); | |||||
| regindex = IXGBE_ERR_NO_SPACE; | |||||
| } | |||||
| } | |||||
| return regindex; | return first_empty_slot ? first_empty_slot : IXGBE_ERR_NO_SPACE; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_vfta_generic - Set VLAN filter table | * ixgbe_set_vfta_generic - Set VLAN filter table | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @vlan: VLAN id to write to VLAN filter | * @vlan: VLAN id to write to VLAN filter | ||||
| * @vind: VMDq output index that maps queue to VLAN id in VFVFB | * @vind: VMDq output index that maps queue to VLAN id in VLVFB | ||||
| * @vlan_on: boolean flag to turn on/off VLAN in VFVF | * @vlan_on: boolean flag to turn on/off VLAN | ||||
| * @vlvf_bypass: boolean flag indicating updating default pool is okay | |||||
| * | * | ||||
| * Turn on/off specified VLAN in the VLAN filter table. | * Turn on/off specified VLAN in the VLAN filter table. | ||||
| **/ | **/ | ||||
| s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, | s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, | ||||
| bool vlan_on) | bool vlan_on, bool vlvf_bypass) | ||||
| { | { | ||||
| s32 regindex; | u32 regidx, vfta_delta, vfta; | ||||
| u32 bitindex; | s32 ret_val; | ||||
| u32 vfta; | |||||
| u32 targetbit; | |||||
| s32 ret_val = IXGBE_SUCCESS; | |||||
| bool vfta_changed = FALSE; | |||||
| DEBUGFUNC("ixgbe_set_vfta_generic"); | DEBUGFUNC("ixgbe_set_vfta_generic"); | ||||
| if (vlan > 4095) | if (vlan > 4095 || vind > 63) | ||||
| return IXGBE_ERR_PARAM; | return IXGBE_ERR_PARAM; | ||||
| /* | /* | ||||
| * this is a 2 part operation - first the VFTA, then the | * this is a 2 part operation - first the VFTA, then the | ||||
| * VLVF and VLVFB if VT Mode is set | * VLVF and VLVFB if VT Mode is set | ||||
| * We don't write the VFTA until we know the VLVF part succeeded. | * We don't write the VFTA until we know the VLVF part succeeded. | ||||
| */ | */ | ||||
| /* Part 1 | /* Part 1 | ||||
| * The VFTA is a bitstring made up of 128 32-bit registers | * The VFTA is a bitstring made up of 128 32-bit registers | ||||
| * that enable the particular VLAN id, much like the MTA: | * that enable the particular VLAN id, much like the MTA: | ||||
| * bits[11-5]: which register | * bits[11-5]: which register | ||||
| * bits[4-0]: which bit in the register | * bits[4-0]: which bit in the register | ||||
| */ | */ | ||||
| regindex = (vlan >> 5) & 0x7F; | regidx = vlan / 32; | ||||
| bitindex = vlan & 0x1F; | vfta_delta = 1 << (vlan % 32); | ||||
| targetbit = (1 << bitindex); | vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regidx)); | ||||
| vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); | |||||
| if (vlan_on) { | /* | ||||
| if (!(vfta & targetbit)) { | * vfta_delta represents the difference between the current value | ||||
| vfta |= targetbit; | * of vfta and the value we want in the register. Since the diff | ||||
| vfta_changed = TRUE; | * is an XOR mask we can just update the vfta using an XOR | ||||
| } | */ | ||||
| } else { | vfta_delta &= vlan_on ? ~vfta : vfta; | ||||
| if ((vfta & targetbit)) { | vfta ^= vfta_delta; | ||||
| vfta &= ~targetbit; | |||||
| vfta_changed = TRUE; | |||||
| } | |||||
| } | |||||
| /* Part 2 | /* Part 2 | ||||
| * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF | * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF | ||||
| */ | */ | ||||
| ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, | ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, &vfta_delta, | ||||
| &vfta_changed); | vfta, vlvf_bypass); | ||||
| if (ret_val != IXGBE_SUCCESS) | if (ret_val != IXGBE_SUCCESS) { | ||||
| if (vlvf_bypass) | |||||
| goto vfta_update; | |||||
| return ret_val; | return ret_val; | ||||
| } | |||||
| if (vfta_changed) | vfta_update: | ||||
| IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); | /* Update VFTA now that we are ready for traffic */ | ||||
| if (vfta_delta) | |||||
| IXGBE_WRITE_REG(hw, IXGBE_VFTA(regidx), vfta); | |||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_vlvf_generic - Set VLAN Pool Filter | * ixgbe_set_vlvf_generic - Set VLAN Pool Filter | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @vlan: VLAN id to write to VLAN filter | * @vlan: VLAN id to write to VLAN filter | ||||
| * @vind: VMDq output index that maps queue to VLAN id in VFVFB | * @vind: VMDq output index that maps queue to VLAN id in VLVFB | ||||
| * @vlan_on: boolean flag to turn on/off VLAN in VFVF | * @vlan_on: boolean flag to turn on/off VLAN in VLVF | ||||
| * @vfta_changed: pointer to boolean flag which indicates whether VFTA | * @vfta_delta: pointer to the difference between the current value of VFTA | ||||
| * should be changed | * and the desired value | ||||
| * @vfta: the desired value of the VFTA | |||||
| * @vlvf_bypass: boolean flag indicating updating default pool is okay | |||||
| * | * | ||||
| * Turn on/off specified bit in VLVF table. | * Turn on/off specified bit in VLVF table. | ||||
| **/ | **/ | ||||
| s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, | s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, | ||||
| bool vlan_on, bool *vfta_changed) | bool vlan_on, u32 *vfta_delta, u32 vfta, | ||||
| bool vlvf_bypass) | |||||
| { | { | ||||
| u32 vt; | u32 bits; | ||||
| s32 vlvf_index; | |||||
| DEBUGFUNC("ixgbe_set_vlvf_generic"); | DEBUGFUNC("ixgbe_set_vlvf_generic"); | ||||
| if (vlan > 4095) | if (vlan > 4095 || vind > 63) | ||||
| return IXGBE_ERR_PARAM; | return IXGBE_ERR_PARAM; | ||||
| /* If VT Mode is set | /* If VT Mode is set | ||||
| * Either vlan_on | * Either vlan_on | ||||
| * make sure the vlan is in VLVF | * make sure the vlan is in VLVF | ||||
| * set the vind bit in the matching VLVFB | * set the vind bit in the matching VLVFB | ||||
| * Or !vlan_on | * Or !vlan_on | ||||
| * clear the pool bit and possibly the vind | * clear the pool bit and possibly the vind | ||||
| */ | */ | ||||
| vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); | if (!(IXGBE_READ_REG(hw, IXGBE_VT_CTL) & IXGBE_VT_CTL_VT_ENABLE)) | ||||
| if (vt & IXGBE_VT_CTL_VT_ENABLE) { | return IXGBE_SUCCESS; | ||||
| s32 vlvf_index; | |||||
| u32 bits; | |||||
| vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); | vlvf_index = ixgbe_find_vlvf_slot(hw, vlan, vlvf_bypass); | ||||
| if (vlvf_index < 0) | if (vlvf_index < 0) | ||||
| return vlvf_index; | return vlvf_index; | ||||
| if (vlan_on) { | bits = IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32)); | ||||
| /* set the pool bit */ | /* set the pool bit */ | ||||
| if (vind < 32) { | bits |= 1 << (vind % 32); | ||||
| bits = IXGBE_READ_REG(hw, | if (vlan_on) | ||||
| IXGBE_VLVFB(vlvf_index * 2)); | goto vlvf_update; | ||||
| bits |= (1 << vind); | |||||
| IXGBE_WRITE_REG(hw, | |||||
| IXGBE_VLVFB(vlvf_index * 2), | |||||
| bits); | |||||
| } else { | |||||
| bits = IXGBE_READ_REG(hw, | |||||
| IXGBE_VLVFB((vlvf_index * 2) + 1)); | |||||
| bits |= (1 << (vind - 32)); | |||||
| IXGBE_WRITE_REG(hw, | |||||
| IXGBE_VLVFB((vlvf_index * 2) + 1), | |||||
| bits); | |||||
| } | |||||
| } else { | |||||
| /* clear the pool bit */ | /* clear the pool bit */ | ||||
| if (vind < 32) { | bits ^= 1 << (vind % 32); | ||||
| bits = IXGBE_READ_REG(hw, | |||||
| IXGBE_VLVFB(vlvf_index * 2)); | if (!bits && | ||||
| bits &= ~(1 << vind); | !IXGBE_READ_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + 1 - vind / 32))) { | ||||
| IXGBE_WRITE_REG(hw, | /* Clear VFTA first, then disable VLVF. Otherwise | ||||
| IXGBE_VLVFB(vlvf_index * 2), | * we run the risk of stray packets leaking into | ||||
| bits); | * the PF via the default pool | ||||
| bits |= IXGBE_READ_REG(hw, | */ | ||||
| IXGBE_VLVFB((vlvf_index * 2) + 1)); | if (*vfta_delta) | ||||
| } else { | IXGBE_WRITE_REG(hw, IXGBE_VFTA(vlan / 32), vfta); | ||||
| bits = IXGBE_READ_REG(hw, | |||||
| IXGBE_VLVFB((vlvf_index * 2) + 1)); | /* disable VLVF and clear remaining bit from pool */ | ||||
| bits &= ~(1 << (vind - 32)); | IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); | ||||
| IXGBE_WRITE_REG(hw, | IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), 0); | ||||
| IXGBE_VLVFB((vlvf_index * 2) + 1), | |||||
| bits); | return IXGBE_SUCCESS; | ||||
| bits |= IXGBE_READ_REG(hw, | |||||
| IXGBE_VLVFB(vlvf_index * 2)); | |||||
| } | } | ||||
| } | |||||
| /* | /* If there are still bits set in the VLVFB registers | ||||
| * If there are still bits set in the VLVFB registers | |||||
| * for the VLAN ID indicated we need to see if the | * for the VLAN ID indicated we need to see if the | ||||
| * caller is requesting that we clear the VFTA entry bit. | * caller is requesting that we clear the VFTA entry bit. | ||||
| * If the caller has requested that we clear the VFTA | * If the caller has requested that we clear the VFTA | ||||
| * entry bit but there are still pools/VFs using this VLAN | * entry bit but there are still pools/VFs using this VLAN | ||||
| * ID entry then ignore the request. We're not worried | * ID entry then ignore the request. We're not worried | ||||
| * about the case where we're turning the VFTA VLAN ID | * about the case where we're turning the VFTA VLAN ID | ||||
| * entry bit on, only when requested to turn it off as | * entry bit on, only when requested to turn it off as | ||||
| * there may be multiple pools and/or VFs using the | * there may be multiple pools and/or VFs using the | ||||
| * VLAN ID entry. In that case we cannot clear the | * VLAN ID entry. In that case we cannot clear the | ||||
| * VFTA bit until all pools/VFs using that VLAN ID have also | * VFTA bit until all pools/VFs using that VLAN ID have also | ||||
| * been cleared. This will be indicated by "bits" being | * been cleared. This will be indicated by "bits" being | ||||
| * zero. | * zero. | ||||
| */ | */ | ||||
| if (bits) { | *vfta_delta = 0; | ||||
| IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), | |||||
| (IXGBE_VLVF_VIEN | vlan)); | |||||
| if ((!vlan_on) && (vfta_changed != NULL)) { | |||||
| /* someone wants to clear the vfta entry | |||||
| * but some pools/VFs are still using it. | |||||
| * Ignore it. */ | |||||
| *vfta_changed = FALSE; | |||||
| } | |||||
| } else | |||||
| IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); | |||||
| } | |||||
| vlvf_update: | |||||
| /* record pool change and enable VLAN ID if not already enabled */ | |||||
| IXGBE_WRITE_REG(hw, IXGBE_VLVFB(vlvf_index * 2 + vind / 32), bits); | |||||
| IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), IXGBE_VLVF_VIEN | vlan); | |||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_clear_vfta_generic - Clear VLAN filter table | * ixgbe_clear_vfta_generic - Clear VLAN filter table | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * | * | ||||
| * Clears the VLAN filer table, and the VMDq index associated with the filter | * Clears the VLAN filer table, and the VMDq index associated with the filter | ||||
| Show All 12 Lines | for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { | ||||
| IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0); | IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0); | ||||
| IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0); | IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0); | ||||
| } | } | ||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix | |||||
| * @hw: pointer to hardware structure | |||||
| * | |||||
| * Contains the logic to identify if we need to verify link for the | |||||
| * crosstalk fix | |||||
| **/ | |||||
| static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw) | |||||
| { | |||||
| /* Does FW say we need the fix */ | |||||
| if (!hw->need_crosstalk_fix) | |||||
| return FALSE; | |||||
| /* Only consider SFP+ PHYs i.e. media type fiber */ | |||||
| switch (hw->mac.ops.get_media_type(hw)) { | |||||
| case ixgbe_media_type_fiber: | |||||
| case ixgbe_media_type_fiber_qsfp: | |||||
| break; | |||||
| default: | |||||
| return FALSE; | |||||
| } | |||||
| return TRUE; | |||||
| } | |||||
| /** | |||||
| * ixgbe_check_mac_link_generic - Determine link and speed status | * ixgbe_check_mac_link_generic - Determine link and speed status | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @speed: pointer to link speed | * @speed: pointer to link speed | ||||
| * @link_up: TRUE when link is up | * @link_up: TRUE when link is up | ||||
| * @link_up_wait_to_complete: bool used to wait for link up or not | * @link_up_wait_to_complete: bool used to wait for link up or not | ||||
| * | * | ||||
| * Reads the links register to determine if link is up and the current speed | * Reads the links register to determine if link is up and the current speed | ||||
| **/ | **/ | ||||
| s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, | s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, | ||||
| bool *link_up, bool link_up_wait_to_complete) | bool *link_up, bool link_up_wait_to_complete) | ||||
| { | { | ||||
| u32 links_reg, links_orig; | u32 links_reg, links_orig; | ||||
| u32 i; | u32 i; | ||||
| DEBUGFUNC("ixgbe_check_mac_link_generic"); | DEBUGFUNC("ixgbe_check_mac_link_generic"); | ||||
| /* If Crosstalk fix enabled do the sanity check of making sure | |||||
| * the SFP+ cage is full. | |||||
| */ | |||||
| if (ixgbe_need_crosstalk_fix(hw)) { | |||||
| u32 sfp_cage_full; | |||||
| switch (hw->mac.type) { | |||||
| case ixgbe_mac_82599EB: | |||||
| sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & | |||||
| IXGBE_ESDP_SDP2; | |||||
| break; | |||||
| case ixgbe_mac_X550EM_x: | |||||
| case ixgbe_mac_X550EM_a: | |||||
| sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & | |||||
| IXGBE_ESDP_SDP0; | |||||
| break; | |||||
| default: | |||||
| /* sanity check - No SFP+ devices here */ | |||||
| sfp_cage_full = FALSE; | |||||
| break; | |||||
| } | |||||
| if (!sfp_cage_full) { | |||||
| *link_up = FALSE; | |||||
| *speed = IXGBE_LINK_SPEED_UNKNOWN; | |||||
| return IXGBE_SUCCESS; | |||||
| } | |||||
| } | |||||
| /* clear the old state */ | /* clear the old state */ | ||||
| links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); | links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); | ||||
| links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | ||||
| if (links_orig != links_reg) { | if (links_orig != links_reg) { | ||||
| DEBUGOUT2("LINKS changed from %08X to %08X\n", | DEBUGOUT2("LINKS changed from %08X to %08X\n", | ||||
| links_orig, links_reg); | links_orig, links_reg); | ||||
| Show All 25 Lines | if (hw->mac.type >= ixgbe_mac_X550) { | ||||
| *speed = IXGBE_LINK_SPEED_2_5GB_FULL; | *speed = IXGBE_LINK_SPEED_2_5GB_FULL; | ||||
| } | } | ||||
| break; | break; | ||||
| case IXGBE_LINKS_SPEED_1G_82599: | case IXGBE_LINKS_SPEED_1G_82599: | ||||
| *speed = IXGBE_LINK_SPEED_1GB_FULL; | *speed = IXGBE_LINK_SPEED_1GB_FULL; | ||||
| break; | break; | ||||
| case IXGBE_LINKS_SPEED_100_82599: | case IXGBE_LINKS_SPEED_100_82599: | ||||
| *speed = IXGBE_LINK_SPEED_100_FULL; | *speed = IXGBE_LINK_SPEED_100_FULL; | ||||
| if (hw->mac.type >= ixgbe_mac_X550) { | if (hw->mac.type == ixgbe_mac_X550) { | ||||
| if (links_reg & IXGBE_LINKS_SPEED_NON_STD) | if (links_reg & IXGBE_LINKS_SPEED_NON_STD) | ||||
| *speed = IXGBE_LINK_SPEED_5GB_FULL; | *speed = IXGBE_LINK_SPEED_5GB_FULL; | ||||
| } | } | ||||
| break; | break; | ||||
| case IXGBE_LINKS_SPEED_10_X550EM_A: | |||||
| *speed = IXGBE_LINK_SPEED_UNKNOWN; | |||||
| if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || | |||||
| hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) { | |||||
| *speed = IXGBE_LINK_SPEED_10_FULL; | |||||
| } | |||||
| break; | |||||
| default: | default: | ||||
| *speed = IXGBE_LINK_SPEED_UNKNOWN; | *speed = IXGBE_LINK_SPEED_UNKNOWN; | ||||
| } | } | ||||
| return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
| } | } | ||||
| /** | /** | ||||
| ▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
| out: | out: | ||||
| return status; | return status; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing | * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @enable: enable or disable switch for anti-spoofing | * @enable: enable or disable switch for MAC anti-spoofing | ||||
| * @pf: Physical Function pool - do not enable anti-spoofing for the PF | * @vf: Virtual Function pool - VF Pool to set for MAC anti-spoofing | ||||
| * | * | ||||
| **/ | **/ | ||||
| void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf) | void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) | ||||
| { | { | ||||
| int j; | int vf_target_reg = vf >> 3; | ||||
| int pf_target_reg = pf >> 3; | int vf_target_shift = vf % 8; | ||||
| int pf_target_shift = pf % 8; | u32 pfvfspoof; | ||||
| u32 pfvfspoof = 0; | |||||
| if (hw->mac.type == ixgbe_mac_82598EB) | if (hw->mac.type == ixgbe_mac_82598EB) | ||||
| return; | return; | ||||
| pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); | |||||
| if (enable) | if (enable) | ||||
| pfvfspoof = IXGBE_SPOOF_MACAS_MASK; | pfvfspoof |= (1 << vf_target_shift); | ||||
| else | |||||
| /* | pfvfspoof &= ~(1 << vf_target_shift); | ||||
| * PFVFSPOOF register array is size 8 with 8 bits assigned to | IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); | ||||
| * MAC anti-spoof enables in each register array element. | |||||
| */ | |||||
| for (j = 0; j < pf_target_reg; j++) | |||||
| IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); | |||||
| /* | |||||
| * The PF should be allowed to spoof so that it can support | |||||
| * emulation mode NICs. Do not set the bits assigned to the PF | |||||
| */ | |||||
| pfvfspoof &= (1 << pf_target_shift) - 1; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); | |||||
| /* | |||||
| * Remaining pools belong to the PF so they do not need to have | |||||
| * anti-spoofing enabled. | |||||
| */ | |||||
| for (j++; j < IXGBE_PFVFSPOOF_REG_COUNT; j++) | |||||
| IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), 0); | |||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing | * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @enable: enable or disable switch for VLAN anti-spoofing | * @enable: enable or disable switch for VLAN anti-spoofing | ||||
| * @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing | * @vf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) | ||||
| for (i = 0; i < length; i++) | for (i = 0; i < length; i++) | ||||
| sum += buffer[i]; | sum += buffer[i]; | ||||
| return (u8) (0 - sum); | return (u8) (0 - sum); | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_host_interface_command - Issue command to manageability block | * ixgbe_hic_unlocked - Issue command to manageability block unlocked | ||||
| * @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
| * @buffer: contains the command to write and where the return status will | * @buffer: command to write and where the return status will be placed | ||||
| * be placed | |||||
| * @length: length of buffer, must be multiple of 4 bytes | * @length: length of buffer, must be multiple of 4 bytes | ||||
| * @timeout: time in ms to wait for command completion | * @timeout: time in ms to wait for command completion | ||||
| * @return_data: read and return data from the buffer (TRUE) or not (FALSE) | |||||
| * Needed because FW structures are big endian and decoding of | |||||
| * these fields can be 8 bit or 16 bit based on command. Decoding | |||||
| * is not easily understood without making a table of commands. | |||||
| * So we will leave this up to the caller to read back the data | |||||
| * in these cases. | |||||
| * | * | ||||
| * Communicates with the manageability block. On success return IXGBE_SUCCESS | * Communicates with the manageability block. On success return IXGBE_SUCCESS | ||||
| * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. | * else returns semaphore error when encountering an error acquiring | ||||
| * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. | |||||
| * | |||||
| * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held | |||||
| * by the caller. | |||||
| **/ | **/ | ||||
| s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, | s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length, | ||||
| u32 length, u32 timeout, bool return_data) | u32 timeout) | ||||
| { | { | ||||
| u32 hicr, i, bi, fwsts; | u32 hicr, i, fwsts; | ||||
| u32 hdr_size = sizeof(struct ixgbe_hic_hdr); | |||||
| u16 buf_len; | |||||
| u16 dword_len; | u16 dword_len; | ||||
| DEBUGFUNC("ixgbe_host_interface_command"); | DEBUGFUNC("ixgbe_hic_unlocked"); | ||||
| if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { | if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { | ||||
| DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); | DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); | ||||
| return IXGBE_ERR_HOST_INTERFACE_COMMAND; | return IXGBE_ERR_HOST_INTERFACE_COMMAND; | ||||
| } | } | ||||
| /* Set bit 9 of FWSTS clearing FW reset indication */ | /* Set bit 9 of FWSTS clearing FW reset indication */ | ||||
| fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS); | fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS); | ||||
| IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI); | IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI); | ||||
| /* Check that the host interface is enabled. */ | /* Check that the host interface is enabled. */ | ||||
| hicr = IXGBE_READ_REG(hw, IXGBE_HICR); | hicr = IXGBE_READ_REG(hw, IXGBE_HICR); | ||||
| if ((hicr & IXGBE_HICR_EN) == 0) { | if (!(hicr & IXGBE_HICR_EN)) { | ||||
| DEBUGOUT("IXGBE_HOST_EN bit disabled.\n"); | DEBUGOUT("IXGBE_HOST_EN bit disabled.\n"); | ||||
| return IXGBE_ERR_HOST_INTERFACE_COMMAND; | return IXGBE_ERR_HOST_INTERFACE_COMMAND; | ||||
| } | } | ||||
| /* Calculate length in DWORDs. We must be DWORD aligned */ | /* Calculate length in DWORDs. We must be DWORD aligned */ | ||||
| if ((length % (sizeof(u32))) != 0) { | if (length % sizeof(u32)) { | ||||
| DEBUGOUT("Buffer length failure, not aligned to dword"); | DEBUGOUT("Buffer length failure, not aligned to dword"); | ||||
| return IXGBE_ERR_INVALID_ARGUMENT; | return IXGBE_ERR_INVALID_ARGUMENT; | ||||
| } | } | ||||
| dword_len = length >> 2; | dword_len = length >> 2; | ||||
| /* The device driver writes the relevant command block | /* The device driver writes the relevant command block | ||||
| * into the ram area. | * into the ram area. | ||||
| */ | */ | ||||
| for (i = 0; i < dword_len; i++) | for (i = 0; i < dword_len; i++) | ||||
| IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, | IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, | ||||
| i, IXGBE_CPU_TO_LE32(buffer[i])); | i, IXGBE_CPU_TO_LE32(buffer[i])); | ||||
| /* Setting this bit tells the ARC that a new command is pending. */ | /* Setting this bit tells the ARC that a new command is pending. */ | ||||
| IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); | IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); | ||||
| for (i = 0; i < timeout; i++) { | for (i = 0; i < timeout; i++) { | ||||
| hicr = IXGBE_READ_REG(hw, IXGBE_HICR); | hicr = IXGBE_READ_REG(hw, IXGBE_HICR); | ||||
| if (!(hicr & IXGBE_HICR_C)) | if (!(hicr & IXGBE_HICR_C)) | ||||
| break; | break; | ||||
| msec_delay(1); | msec_delay(1); | ||||
| } | } | ||||
| /* Check command completion */ | /* Check command completion */ | ||||
| if ((timeout != 0 && i == timeout) || | if ((timeout && i == timeout) || | ||||
| !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { | !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { | ||||
| ERROR_REPORT1(IXGBE_ERROR_CAUTION, | ERROR_REPORT1(IXGBE_ERROR_CAUTION, | ||||
| "Command has failed with no status valid.\n"); | "Command has failed with no status valid.\n"); | ||||
| return IXGBE_ERR_HOST_INTERFACE_COMMAND; | return IXGBE_ERR_HOST_INTERFACE_COMMAND; | ||||
| } | } | ||||
| return IXGBE_SUCCESS; | |||||
| } | |||||
| /** | |||||
| * ixgbe_host_interface_command - Issue command to manageability block | |||||
| * @hw: pointer to the HW structure | |||||
| * @buffer: contains the command to write and where the return status will | |||||
| * be placed | |||||
| * @length: length of buffer, must be multiple of 4 bytes | |||||
| * @timeout: time in ms to wait for command completion | |||||
| * @return_data: read and return data from the buffer (TRUE) or not (FALSE) | |||||
| * Needed because FW structures are big endian and decoding of | |||||
| * these fields can be 8 bit or 16 bit based on command. Decoding | |||||
| * is not easily understood without making a table of commands. | |||||
| * So we will leave this up to the caller to read back the data | |||||
| * in these cases. | |||||
| * | |||||
| * Communicates with the manageability block. On success return IXGBE_SUCCESS | |||||
| * else returns semaphore error when encountering an error acquiring | |||||
| * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. | |||||
| **/ | |||||
| s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, | |||||
| u32 length, u32 timeout, bool return_data) | |||||
| { | |||||
| u32 hdr_size = sizeof(struct ixgbe_hic_hdr); | |||||
| u16 dword_len; | |||||
| u16 buf_len; | |||||
| s32 status; | |||||
| u32 bi; | |||||
| DEBUGFUNC("ixgbe_host_interface_command"); | |||||
| if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { | |||||
| DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); | |||||
| return IXGBE_ERR_HOST_INTERFACE_COMMAND; | |||||
| } | |||||
| /* Take management host interface semaphore */ | |||||
| status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); | |||||
| if (status) | |||||
| return status; | |||||
| status = ixgbe_hic_unlocked(hw, buffer, length, timeout); | |||||
| if (status) | |||||
| goto rel_out; | |||||
| if (!return_data) | if (!return_data) | ||||
| return 0; | goto rel_out; | ||||
| /* Calculate length in DWORDs */ | /* Calculate length in DWORDs */ | ||||
| dword_len = hdr_size >> 2; | dword_len = hdr_size >> 2; | ||||
| /* first pull in the header so we know the buffer length */ | /* first pull in the header so we know the buffer length */ | ||||
| for (bi = 0; bi < dword_len; bi++) { | for (bi = 0; bi < dword_len; bi++) { | ||||
| buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | ||||
| IXGBE_LE32_TO_CPUS(&buffer[bi]); | IXGBE_LE32_TO_CPUS(&buffer[bi]); | ||||
| } | } | ||||
| /* If there is any thing in data position pull it in */ | /* If there is any thing in data position pull it in */ | ||||
| buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; | buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; | ||||
| if (buf_len == 0) | if (!buf_len) | ||||
| return 0; | goto rel_out; | ||||
| if (length < buf_len + hdr_size) { | if (length < buf_len + hdr_size) { | ||||
| DEBUGOUT("Buffer not large enough for reply message.\n"); | DEBUGOUT("Buffer not large enough for reply message.\n"); | ||||
| return IXGBE_ERR_HOST_INTERFACE_COMMAND; | status = IXGBE_ERR_HOST_INTERFACE_COMMAND; | ||||
| goto rel_out; | |||||
| } | } | ||||
| /* Calculate length in DWORDs, add 3 for odd lengths */ | /* Calculate length in DWORDs, add 3 for odd lengths */ | ||||
| dword_len = (buf_len + 3) >> 2; | dword_len = (buf_len + 3) >> 2; | ||||
| /* Pull in the rest of the buffer (bi is where we left off) */ | /* Pull in the rest of the buffer (bi is where we left off) */ | ||||
| for (; bi <= dword_len; bi++) { | for (; bi <= dword_len; bi++) { | ||||
| buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | ||||
| IXGBE_LE32_TO_CPUS(&buffer[bi]); | IXGBE_LE32_TO_CPUS(&buffer[bi]); | ||||
| } | } | ||||
| return 0; | rel_out: | ||||
| hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); | |||||
| return status; | |||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware | * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware | ||||
| * @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
| * @maj: driver version major number | * @maj: driver version major number | ||||
| * @min: driver version minor number | * @min: driver version minor number | ||||
| * @build: driver version build number | * @build: driver version build number | ||||
| * @sub: driver version sub build number | * @sub: driver version sub build number | ||||
| * | * | ||||
| * Sends driver version number to firmware through the manageability | * Sends driver version number to firmware through the manageability | ||||
| * block. On success return IXGBE_SUCCESS | * block. On success return IXGBE_SUCCESS | ||||
| * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring | * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring | ||||
| * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. | * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. | ||||
| **/ | **/ | ||||
| s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, | s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, | ||||
| u8 build, u8 sub) | u8 build, u8 sub, u16 len, | ||||
| const char *driver_ver) | |||||
| { | { | ||||
| struct ixgbe_hic_drv_info fw_cmd; | struct ixgbe_hic_drv_info fw_cmd; | ||||
| int i; | int i; | ||||
| s32 ret_val = IXGBE_SUCCESS; | s32 ret_val = IXGBE_SUCCESS; | ||||
| DEBUGFUNC("ixgbe_set_fw_drv_ver_generic"); | DEBUGFUNC("ixgbe_set_fw_drv_ver_generic"); | ||||
| UNREFERENCED_2PARAMETER(len, driver_ver); | |||||
| if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM) | |||||
| != IXGBE_SUCCESS) { | |||||
| ret_val = IXGBE_ERR_SWFW_SYNC; | |||||
| goto out; | |||||
| } | |||||
| fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; | fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; | ||||
| fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; | fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; | ||||
| fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; | fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; | ||||
| fw_cmd.port_num = (u8)hw->bus.func; | fw_cmd.port_num = (u8)hw->bus.func; | ||||
| fw_cmd.ver_maj = maj; | fw_cmd.ver_maj = maj; | ||||
| fw_cmd.ver_min = min; | fw_cmd.ver_min = min; | ||||
| fw_cmd.ver_build = build; | fw_cmd.ver_build = build; | ||||
| fw_cmd.ver_sub = sub; | fw_cmd.ver_sub = sub; | ||||
| Show All 15 Lines | if (fw_cmd.hdr.cmd_or_resp.ret_status == | ||||
| FW_CEM_RESP_STATUS_SUCCESS) | FW_CEM_RESP_STATUS_SUCCESS) | ||||
| ret_val = IXGBE_SUCCESS; | ret_val = IXGBE_SUCCESS; | ||||
| else | else | ||||
| ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; | ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; | ||||
| break; | break; | ||||
| } | } | ||||
| hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); | |||||
| out: | |||||
| return ret_val; | return ret_val; | ||||
| } | } | ||||
| /** | /** | ||||
| * ixgbe_set_rxpba_generic - Initialize Rx packet buffer | * ixgbe_set_rxpba_generic - Initialize Rx packet buffer | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @num_pb: number of packet buffers to allocate | * @num_pb: number of packet buffers to allocate | ||||
| * @headroom: reserve n KB of headroom | * @headroom: reserve n KB of headroom | ||||
| ▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | out: | ||||
| IXGBE_WRITE_FLUSH(hw); | IXGBE_WRITE_FLUSH(hw); | ||||
| usec_delay(20); | usec_delay(20); | ||||
| /* restore previous register values */ | /* restore previous register values */ | ||||
| IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); | IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); | ||||
| IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); | IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); | ||||
| } | } | ||||
| /** | |||||
| * ixgbe_bypass_rw_generic - Bit bang data into by_pass FW | |||||
| * | |||||
| * @hw: pointer to hardware structure | |||||
| * @cmd: Command we send to the FW | |||||
| * @status: The reply from the FW | |||||
| * | |||||
| * Bit-bangs the cmd to the by_pass FW status points to what is returned. | |||||
| **/ | |||||
| #define IXGBE_BYPASS_BB_WAIT 1 | |||||
| s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status) | |||||
| { | |||||
| int i; | |||||
| u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo; | |||||
| u32 esdp; | |||||
| if (!status) | |||||
| return IXGBE_ERR_PARAM; | |||||
| *status = 0; | |||||
| /* SDP vary by MAC type */ | |||||
| switch (hw->mac.type) { | |||||
| case ixgbe_mac_82599EB: | |||||
| sck = IXGBE_ESDP_SDP7; | |||||
| sdi = IXGBE_ESDP_SDP0; | |||||
| sdo = IXGBE_ESDP_SDP6; | |||||
| dir_sck = IXGBE_ESDP_SDP7_DIR; | |||||
| dir_sdi = IXGBE_ESDP_SDP0_DIR; | |||||
| dir_sdo = IXGBE_ESDP_SDP6_DIR; | |||||
| break; | |||||
| case ixgbe_mac_X540: | |||||
| sck = IXGBE_ESDP_SDP2; | |||||
| sdi = IXGBE_ESDP_SDP0; | |||||
| sdo = IXGBE_ESDP_SDP1; | |||||
| dir_sck = IXGBE_ESDP_SDP2_DIR; | |||||
| dir_sdi = IXGBE_ESDP_SDP0_DIR; | |||||
| dir_sdo = IXGBE_ESDP_SDP1_DIR; | |||||
| break; | |||||
| default: | |||||
| return IXGBE_ERR_DEVICE_NOT_SUPPORTED; | |||||
| } | |||||
| /* Set SDP pins direction */ | |||||
| esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); | |||||
| esdp |= dir_sck; /* SCK as output */ | |||||
| esdp |= dir_sdi; /* SDI as output */ | |||||
| esdp &= ~dir_sdo; /* SDO as input */ | |||||
| esdp |= sck; | |||||
| esdp |= sdi; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| /* Generate start condition */ | |||||
| esdp &= ~sdi; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| esdp &= ~sck; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| /* Clock out the new control word and clock in the status */ | |||||
| for (i = 0; i < 32; i++) { | |||||
| if ((cmd >> (31 - i)) & 0x01) { | |||||
| esdp |= sdi; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| } else { | |||||
| esdp &= ~sdi; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| } | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| esdp |= sck; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| esdp &= ~sck; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); | |||||
| if (esdp & sdo) | |||||
| *status = (*status << 1) | 0x01; | |||||
| else | |||||
| *status = (*status << 1) | 0x00; | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| } | |||||
| /* stop condition */ | |||||
| esdp |= sck; | |||||
| esdp &= ~sdi; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| msec_delay(IXGBE_BYPASS_BB_WAIT); | |||||
| esdp |= sdi; | |||||
| IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |||||
| IXGBE_WRITE_FLUSH(hw); | |||||
| /* set the page bits to match the cmd that the status it belongs to */ | |||||
| *status = (*status & 0x3fffffff) | (cmd & 0xc0000000); | |||||
| return IXGBE_SUCCESS; | |||||
| } | |||||
| /** | /** | ||||
| * ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang. | |||||
| * | |||||
| * If we send a write we can't be sure it took until we can read back | |||||
| * that same register. It can be a problem as some of the feilds may | |||||
| * for valid reasons change inbetween the time wrote the register and | |||||
| * we read it again to verify. So this function check everything we | |||||
| * can check and then assumes it worked. | |||||
| * | |||||
| * @u32 in_reg - The register cmd for the bit-bang read. | |||||
| * @u32 out_reg - The register returned from a bit-bang read. | |||||
| **/ | |||||
| bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg) | |||||
| { | |||||
| u32 mask; | |||||
| /* Page must match for all control pages */ | |||||
| if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M)) | |||||
| return FALSE; | |||||
| switch (in_reg & BYPASS_PAGE_M) { | |||||
| case BYPASS_PAGE_CTL0: | |||||
| /* All the following can't change since the last write | |||||
| * - All the event actions | |||||
| * - The timeout value | |||||
| */ | |||||
| mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M | | |||||
| BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M | | |||||
| BYPASS_WDTIMEOUT_M | | |||||
| BYPASS_WDT_VALUE_M; | |||||
| if ((out_reg & mask) != (in_reg & mask)) | |||||
| return FALSE; | |||||
| /* 0x0 is never a valid value for bypass status */ | |||||
| if (!(out_reg & BYPASS_STATUS_OFF_M)) | |||||
| return FALSE; | |||||
| break; | |||||
| case BYPASS_PAGE_CTL1: | |||||
| /* All the following can't change since the last write | |||||
| * - time valid bit | |||||
| * - time we last sent | |||||
| */ | |||||
| mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M; | |||||
| if ((out_reg & mask) != (in_reg & mask)) | |||||
| return FALSE; | |||||
| break; | |||||
| case BYPASS_PAGE_CTL2: | |||||
| /* All we can check in this page is control number | |||||
| * which is already done above. | |||||
| */ | |||||
| break; | |||||
| } | |||||
| /* We are as sure as we can be return TRUE */ | |||||
| return TRUE; | |||||
| } | |||||
| /** | |||||
| * ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Regiter. | |||||
| * | |||||
| * @hw: pointer to hardware structure | |||||
| * @cmd: The control word we are setting. | |||||
| * @event: The event we are setting in the FW. This also happens to | |||||
| * be the mask for the event we are setting (handy) | |||||
| * @action: The action we set the event to in the FW. This is in a | |||||
| * bit field that happens to be what we want to put in | |||||
| * the event spot (also handy) | |||||
| **/ | |||||
| s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event, | |||||
| u32 action) | |||||
| { | |||||
| u32 by_ctl = 0; | |||||
| u32 cmd, verify; | |||||
| u32 count = 0; | |||||
| /* Get current values */ | |||||
| cmd = ctrl; /* just reading only need control number */ | |||||
| if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl)) | |||||
| return IXGBE_ERR_INVALID_ARGUMENT; | |||||
| /* Set to new action */ | |||||
| cmd = (by_ctl & ~event) | BYPASS_WE | action; | |||||
| if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl)) | |||||
| return IXGBE_ERR_INVALID_ARGUMENT; | |||||
| /* Page 0 force a FW eeprom write which is slow so verify */ | |||||
| if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) { | |||||
| verify = BYPASS_PAGE_CTL0; | |||||
| do { | |||||
| if (count++ > 5) | |||||
| return IXGBE_BYPASS_FW_WRITE_FAILURE; | |||||
| if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl)) | |||||
| return IXGBE_ERR_INVALID_ARGUMENT; | |||||
| } while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl)); | |||||
| } else { | |||||
| /* We have give the FW time for the write to stick */ | |||||
| msec_delay(100); | |||||
| } | |||||
| return IXGBE_SUCCESS; | |||||
| } | |||||
| /** | |||||
| * ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom addres. | |||||
| * | |||||
| * @hw: pointer to hardware structure | |||||
| * @addr: The bypass eeprom address to read. | |||||
| * @value: The 8b of data at the address above. | |||||
| **/ | |||||
| s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value) | |||||
| { | |||||
| u32 cmd; | |||||
| u32 status; | |||||
| /* send the request */ | |||||
| cmd = BYPASS_PAGE_CTL2 | BYPASS_WE; | |||||
| cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M; | |||||
| if (ixgbe_bypass_rw_generic(hw, cmd, &status)) | |||||
| return IXGBE_ERR_INVALID_ARGUMENT; | |||||
| /* We have give the FW time for the write to stick */ | |||||
| msec_delay(100); | |||||
| /* now read the results */ | |||||
| cmd &= ~BYPASS_WE; | |||||
| if (ixgbe_bypass_rw_generic(hw, cmd, &status)) | |||||
| return IXGBE_ERR_INVALID_ARGUMENT; | |||||
| *value = status & BYPASS_CTL2_DATA_M; | |||||
| return IXGBE_SUCCESS; | |||||
| } | |||||
| /** | |||||
| * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg | * ixgbe_dcb_get_rtrup2tc_generic - read rtrup2tc reg | ||||
| * @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
| * @map: pointer to u8 arr for returning map | * @map: pointer to u8 arr for returning map | ||||
| * | * | ||||
| * Read the rtrup2tc HW register and resolve its content into map | * Read the rtrup2tc HW register and resolve its content into map | ||||
| **/ | **/ | ||||
| void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map) | void ixgbe_dcb_get_rtrup2tc_generic(struct ixgbe_hw *hw, u8 *map) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, | ||||
| /* Try each speed one by one, highest priority first. We do this in | /* Try each speed one by one, highest priority first. We do this in | ||||
| * software because 10Gb fiber doesn't support speed autonegotiation. | * software because 10Gb fiber doesn't support speed autonegotiation. | ||||
| */ | */ | ||||
| if (speed & IXGBE_LINK_SPEED_10GB_FULL) { | if (speed & IXGBE_LINK_SPEED_10GB_FULL) { | ||||
| speedcnt++; | speedcnt++; | ||||
| highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; | highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; | ||||
| /* If we already have link at this speed, just jump out */ | |||||
| status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); | |||||
| if (status != IXGBE_SUCCESS) | |||||
| return status; | |||||
| if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up) | |||||
| goto out; | |||||
| /* Set the module link speed */ | /* Set the module link speed */ | ||||
| switch (hw->phy.media_type) { | switch (hw->phy.media_type) { | ||||
| case ixgbe_media_type_fiber_fixed: | case ixgbe_media_type_fiber_fixed: | ||||
| case ixgbe_media_type_fiber: | case ixgbe_media_type_fiber: | ||||
| ixgbe_set_rate_select_speed(hw, | ixgbe_set_rate_select_speed(hw, | ||||
| IXGBE_LINK_SPEED_10GB_FULL); | IXGBE_LINK_SPEED_10GB_FULL); | ||||
| break; | break; | ||||
| case ixgbe_media_type_fiber_qsfp: | case ixgbe_media_type_fiber_qsfp: | ||||
| Show All 34 Lines | for (i = 0; i < 5; i++) { | ||||
| goto out; | goto out; | ||||
| } | } | ||||
| } | } | ||||
| if (speed & IXGBE_LINK_SPEED_1GB_FULL) { | if (speed & IXGBE_LINK_SPEED_1GB_FULL) { | ||||
| speedcnt++; | speedcnt++; | ||||
| if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) | if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) | ||||
| highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; | highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; | ||||
| /* If we already have link at this speed, just jump out */ | |||||
| status = ixgbe_check_link(hw, &link_speed, &link_up, FALSE); | |||||
| if (status != IXGBE_SUCCESS) | |||||
| return status; | |||||
| if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up) | |||||
| goto out; | |||||
| /* Set the module link speed */ | /* Set the module link speed */ | ||||
| switch (hw->phy.media_type) { | switch (hw->phy.media_type) { | ||||
| case ixgbe_media_type_fiber_fixed: | case ixgbe_media_type_fiber_fixed: | ||||
| case ixgbe_media_type_fiber: | case ixgbe_media_type_fiber: | ||||
| ixgbe_set_rate_select_speed(hw, | ixgbe_set_rate_select_speed(hw, | ||||
| IXGBE_LINK_SPEED_1GB_FULL); | IXGBE_LINK_SPEED_1GB_FULL); | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 120 Lines • Show Last 20 Lines | |||||
bracing