19ca4041bSJack F Vogel /****************************************************************************** 213705f88SJack F Vogel 3c0014855SJack F Vogel Copyright (c) 2001-2010, Intel Corporation 413705f88SJack F Vogel All rights reserved. 513705f88SJack F Vogel 613705f88SJack F Vogel Redistribution and use in source and binary forms, with or without 713705f88SJack F Vogel modification, are permitted provided that the following conditions are met: 813705f88SJack F Vogel 913705f88SJack F Vogel 1. Redistributions of source code must retain the above copyright notice, 1013705f88SJack F Vogel this list of conditions and the following disclaimer. 1113705f88SJack F Vogel 1213705f88SJack F Vogel 2. Redistributions in binary form must reproduce the above copyright 1313705f88SJack F Vogel notice, this list of conditions and the following disclaimer in the 1413705f88SJack F Vogel documentation and/or other materials provided with the distribution. 1513705f88SJack F Vogel 1613705f88SJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its 1713705f88SJack F Vogel contributors may be used to endorse or promote products derived from 1813705f88SJack F Vogel this software without specific prior written permission. 1913705f88SJack F Vogel 2013705f88SJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2113705f88SJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2213705f88SJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2313705f88SJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2413705f88SJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2513705f88SJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2613705f88SJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2713705f88SJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2813705f88SJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2913705f88SJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3013705f88SJack F Vogel POSSIBILITY OF SUCH DAMAGE. 3113705f88SJack F Vogel 329ca4041bSJack F Vogel ******************************************************************************/ 3313705f88SJack F Vogel /*$FreeBSD$*/ 3413705f88SJack F Vogel 3513705f88SJack F Vogel #include "ixgbe_common.h" 36*1a4e3449SJack F Vogel #include "ixgbe_phy.h" 3713705f88SJack F Vogel #include "ixgbe_api.h" 3813705f88SJack F Vogel 3913705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); 4013705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); 4113705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); 4213705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw); 4313705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw); 4413705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, 4513705f88SJack F Vogel u16 count); 4613705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); 4713705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); 4813705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); 4913705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw); 5013705f88SJack F Vogel 5113705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); 522969bf0eSJack F Vogel static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, 532969bf0eSJack F Vogel u16 *san_mac_offset); 54*1a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw); 55*1a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw); 56*1a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw); 57*1a4e3449SJack F Vogel static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); 58*1a4e3449SJack F Vogel static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, 59*1a4e3449SJack F Vogel u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); 60*1a4e3449SJack F Vogel 612969bf0eSJack F Vogel s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan); 6213705f88SJack F Vogel 6313705f88SJack F Vogel /** 649ca4041bSJack F Vogel * ixgbe_init_ops_generic - Inits function ptrs 659ca4041bSJack F Vogel * @hw: pointer to the hardware structure 6613705f88SJack F Vogel * 679ca4041bSJack F Vogel * Initialize the function pointers. 6813705f88SJack F Vogel **/ 699ca4041bSJack F Vogel s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) 7013705f88SJack F Vogel { 719ca4041bSJack F Vogel struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 729ca4041bSJack F Vogel struct ixgbe_mac_info *mac = &hw->mac; 739ca4041bSJack F Vogel u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC); 7413705f88SJack F Vogel 752969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_ops_generic"); 762969bf0eSJack F Vogel 7713705f88SJack F Vogel /* EEPROM */ 789ca4041bSJack F Vogel eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic; 799ca4041bSJack F Vogel /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */ 809ca4041bSJack F Vogel if (eec & (1 << 8)) 812969bf0eSJack F Vogel eeprom->ops.read = &ixgbe_read_eerd_generic; 829ca4041bSJack F Vogel else 839ca4041bSJack F Vogel eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic; 849ca4041bSJack F Vogel eeprom->ops.write = &ixgbe_write_eeprom_generic; 859ca4041bSJack F Vogel eeprom->ops.validate_checksum = 8613705f88SJack F Vogel &ixgbe_validate_eeprom_checksum_generic; 879ca4041bSJack F Vogel eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic; 882969bf0eSJack F Vogel eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_generic; 899ca4041bSJack F Vogel 909ca4041bSJack F Vogel /* MAC */ 919ca4041bSJack F Vogel mac->ops.init_hw = &ixgbe_init_hw_generic; 929ca4041bSJack F Vogel mac->ops.reset_hw = NULL; 939ca4041bSJack F Vogel mac->ops.start_hw = &ixgbe_start_hw_generic; 949ca4041bSJack F Vogel mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic; 959ca4041bSJack F Vogel mac->ops.get_media_type = NULL; 961b6e0dbaSJack F Vogel mac->ops.get_supported_physical_layer = NULL; 970ac6dfecSJack F Vogel mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic; 989ca4041bSJack F Vogel mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic; 999ca4041bSJack F Vogel mac->ops.stop_adapter = &ixgbe_stop_adapter_generic; 1009ca4041bSJack F Vogel mac->ops.get_bus_info = &ixgbe_get_bus_info_generic; 1011b6e0dbaSJack F Vogel mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie; 102d8602bb9SJack F Vogel mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync; 103d8602bb9SJack F Vogel mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync; 1049ca4041bSJack F Vogel 1059ca4041bSJack F Vogel /* LEDs */ 1069ca4041bSJack F Vogel mac->ops.led_on = &ixgbe_led_on_generic; 1079ca4041bSJack F Vogel mac->ops.led_off = &ixgbe_led_off_generic; 1080ac6dfecSJack F Vogel mac->ops.blink_led_start = &ixgbe_blink_led_start_generic; 1090ac6dfecSJack F Vogel mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic; 1109ca4041bSJack F Vogel 11113705f88SJack F Vogel /* RAR, Multicast, VLAN */ 1129ca4041bSJack F Vogel mac->ops.set_rar = &ixgbe_set_rar_generic; 1135b7f4cedSJack F Vogel mac->ops.clear_rar = &ixgbe_clear_rar_generic; 1140ac6dfecSJack F Vogel mac->ops.insert_mac_addr = NULL; 1159ca4041bSJack F Vogel mac->ops.set_vmdq = NULL; 1165b7f4cedSJack F Vogel mac->ops.clear_vmdq = NULL; 1179ca4041bSJack F Vogel mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic; 1189ca4041bSJack F Vogel mac->ops.update_uc_addr_list = &ixgbe_update_uc_addr_list_generic; 1199ca4041bSJack F Vogel mac->ops.update_mc_addr_list = &ixgbe_update_mc_addr_list_generic; 1209ca4041bSJack F Vogel mac->ops.enable_mc = &ixgbe_enable_mc_generic; 1219ca4041bSJack F Vogel mac->ops.disable_mc = &ixgbe_disable_mc_generic; 1225b7f4cedSJack F Vogel mac->ops.clear_vfta = NULL; 1235b7f4cedSJack F Vogel mac->ops.set_vfta = NULL; 1245b7f4cedSJack F Vogel mac->ops.init_uta_tables = NULL; 1259ca4041bSJack F Vogel 1260ac6dfecSJack F Vogel /* Flow Control */ 1270ac6dfecSJack F Vogel mac->ops.fc_enable = &ixgbe_fc_enable_generic; 1289ca4041bSJack F Vogel 1299ca4041bSJack F Vogel /* Link */ 1309ca4041bSJack F Vogel mac->ops.get_link_capabilities = NULL; 1319ca4041bSJack F Vogel mac->ops.setup_link = NULL; 1329ca4041bSJack F Vogel mac->ops.check_link = NULL; 13313705f88SJack F Vogel 13413705f88SJack F Vogel return IXGBE_SUCCESS; 13513705f88SJack F Vogel } 13613705f88SJack F Vogel 13713705f88SJack F Vogel /** 1389ca4041bSJack F Vogel * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx 13913705f88SJack F Vogel * @hw: pointer to hardware structure 14013705f88SJack F Vogel * 14113705f88SJack F Vogel * Starts the hardware by filling the bus info structure and media type, clears 14213705f88SJack F Vogel * all on chip counters, initializes receive address registers, multicast 14313705f88SJack F Vogel * table, VLAN filter table, calls routine to set up link and flow control 14413705f88SJack F Vogel * settings, and leaves transmit and receive units disabled and uninitialized 14513705f88SJack F Vogel **/ 14613705f88SJack F Vogel s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) 14713705f88SJack F Vogel { 14813705f88SJack F Vogel u32 ctrl_ext; 14913705f88SJack F Vogel 1502969bf0eSJack F Vogel DEBUGFUNC("ixgbe_start_hw_generic"); 1512969bf0eSJack F Vogel 15213705f88SJack F Vogel /* Set the media type */ 1539ca4041bSJack F Vogel hw->phy.media_type = hw->mac.ops.get_media_type(hw); 15413705f88SJack F Vogel 1550ac6dfecSJack F Vogel /* PHY ops initialization must be done in reset_hw() */ 15613705f88SJack F Vogel 15713705f88SJack F Vogel /* Clear the VLAN filter table */ 1589ca4041bSJack F Vogel hw->mac.ops.clear_vfta(hw); 15913705f88SJack F Vogel 16013705f88SJack F Vogel /* Clear statistics registers */ 1619ca4041bSJack F Vogel hw->mac.ops.clear_hw_cntrs(hw); 16213705f88SJack F Vogel 16313705f88SJack F Vogel /* Set No Snoop Disable */ 16413705f88SJack F Vogel ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); 16513705f88SJack F Vogel ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; 16613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); 1679ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 16813705f88SJack F Vogel 1690ac6dfecSJack F Vogel /* Setup flow control */ 1700ac6dfecSJack F Vogel ixgbe_setup_fc(hw, 0); 1710ac6dfecSJack F Vogel 17213705f88SJack F Vogel /* Clear adapter stopped flag */ 17313705f88SJack F Vogel hw->adapter_stopped = FALSE; 17413705f88SJack F Vogel 175*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 176*1a4e3449SJack F Vogel } 177*1a4e3449SJack F Vogel 178*1a4e3449SJack F Vogel /** 179*1a4e3449SJack F Vogel * ixgbe_start_hw_gen2 - Init sequence for common device family 180*1a4e3449SJack F Vogel * @hw: pointer to hw structure 181*1a4e3449SJack F Vogel * 182*1a4e3449SJack F Vogel * Performs the init sequence common to the second generation 183*1a4e3449SJack F Vogel * of 10 GbE devices. 184*1a4e3449SJack F Vogel * Devices in the second generation: 185*1a4e3449SJack F Vogel * 82599 186*1a4e3449SJack F Vogel **/ 187*1a4e3449SJack F Vogel s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) 188*1a4e3449SJack F Vogel { 189*1a4e3449SJack F Vogel u32 i; 190*1a4e3449SJack F Vogel u32 regval; 191*1a4e3449SJack F Vogel 192*1a4e3449SJack F Vogel /* Clear the rate limiters */ 193*1a4e3449SJack F Vogel for (i = 0; i < hw->mac.max_tx_queues; i++) { 194*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i); 195*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0); 196*1a4e3449SJack F Vogel } 197*1a4e3449SJack F Vogel IXGBE_WRITE_FLUSH(hw); 198*1a4e3449SJack F Vogel 199*1a4e3449SJack F Vogel /* Disable relaxed ordering */ 200*1a4e3449SJack F Vogel for (i = 0; i < hw->mac.max_tx_queues; i++) { 201*1a4e3449SJack F Vogel regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); 202*1a4e3449SJack F Vogel regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; 203*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); 204*1a4e3449SJack F Vogel } 205*1a4e3449SJack F Vogel 206*1a4e3449SJack F Vogel for (i = 0; i < hw->mac.max_rx_queues; i++) { 207*1a4e3449SJack F Vogel regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); 208*1a4e3449SJack F Vogel regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | 209*1a4e3449SJack F Vogel IXGBE_DCA_RXCTRL_DESC_HSRO_EN); 210*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); 211*1a4e3449SJack F Vogel } 212*1a4e3449SJack F Vogel 213*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 21413705f88SJack F Vogel } 21513705f88SJack F Vogel 21613705f88SJack F Vogel /** 21713705f88SJack F Vogel * ixgbe_init_hw_generic - Generic hardware initialization 21813705f88SJack F Vogel * @hw: pointer to hardware structure 21913705f88SJack F Vogel * 2209ca4041bSJack F Vogel * Initialize the hardware by resetting the hardware, filling the bus info 22113705f88SJack F Vogel * structure and media type, clears all on chip counters, initializes receive 22213705f88SJack F Vogel * address registers, multicast table, VLAN filter table, calls routine to set 22313705f88SJack F Vogel * up link and flow control settings, and leaves transmit and receive units 22413705f88SJack F Vogel * disabled and uninitialized 22513705f88SJack F Vogel **/ 22613705f88SJack F Vogel s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) 22713705f88SJack F Vogel { 228*1a4e3449SJack F Vogel s32 status; 2290ac6dfecSJack F Vogel 2302969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_hw_generic"); 2312969bf0eSJack F Vogel 23213705f88SJack F Vogel /* Reset the hardware */ 2330ac6dfecSJack F Vogel status = hw->mac.ops.reset_hw(hw); 23413705f88SJack F Vogel 2350ac6dfecSJack F Vogel if (status == IXGBE_SUCCESS) { 23613705f88SJack F Vogel /* Start the HW */ 2370ac6dfecSJack F Vogel status = hw->mac.ops.start_hw(hw); 2380ac6dfecSJack F Vogel } 23913705f88SJack F Vogel 2400ac6dfecSJack F Vogel return status; 24113705f88SJack F Vogel } 24213705f88SJack F Vogel 24313705f88SJack F Vogel /** 24413705f88SJack F Vogel * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters 24513705f88SJack F Vogel * @hw: pointer to hardware structure 24613705f88SJack F Vogel * 24713705f88SJack F Vogel * Clears all hardware statistics counters by reading them from the hardware 24813705f88SJack F Vogel * Statistics counters are clear on read. 24913705f88SJack F Vogel **/ 25013705f88SJack F Vogel s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) 25113705f88SJack F Vogel { 25213705f88SJack F Vogel u16 i = 0; 25313705f88SJack F Vogel 2542969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_hw_cntrs_generic"); 2552969bf0eSJack F Vogel 25613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_CRCERRS); 25713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ILLERRC); 25813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ERRBC); 25913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MSPDC); 26013705f88SJack F Vogel for (i = 0; i < 8; i++) 26113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPC(i)); 26213705f88SJack F Vogel 26313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MLFC); 26413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MRFC); 26513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RLEC); 26613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONTXC); 26713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); 2680ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 2690ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); 2700ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); 2710ac6dfecSJack F Vogel } else { 2721b6e0dbaSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONRXC); 27313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); 2740ac6dfecSJack F Vogel } 27513705f88SJack F Vogel 27613705f88SJack F Vogel for (i = 0; i < 8; i++) { 27713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); 27813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); 2790ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 2800ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); 2810ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); 2820ac6dfecSJack F Vogel } else { 2831b6e0dbaSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); 28413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); 28513705f88SJack F Vogel } 2860ac6dfecSJack F Vogel } 2870ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) 2880ac6dfecSJack F Vogel for (i = 0; i < 8; i++) 2890ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); 29013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC64); 29113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC127); 29213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC255); 29313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC511); 29413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1023); 29513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1522); 29613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPRC); 29713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPRC); 29813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPRC); 29913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPTC); 30013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCL); 30113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCH); 30213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCL); 30313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCH); 30413705f88SJack F Vogel for (i = 0; i < 8; i++) 30513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RNBC(i)); 30613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RUC); 30713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RFC); 30813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ROC); 30913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RJC); 31013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPRC); 31113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPDC); 31213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPTC); 31313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORL); 31413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORH); 31513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPR); 31613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPT); 31713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC64); 31813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC127); 31913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC255); 32013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC511); 32113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1023); 32213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1522); 32313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPTC); 32413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPTC); 32513705f88SJack F Vogel for (i = 0; i < 16; i++) { 32613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPRC(i)); 32713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPTC(i)); 328*1a4e3449SJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 329*1a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); 330*1a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); 331*1a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); 332*1a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); 333*1a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); 334*1a4e3449SJack F Vogel } else { 335*1a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC(i)); 33613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC(i)); 33713705f88SJack F Vogel } 338*1a4e3449SJack F Vogel } 339*1a4e3449SJack F Vogel 340*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 341*1a4e3449SJack F Vogel } 342*1a4e3449SJack F Vogel 343*1a4e3449SJack F Vogel /** 344*1a4e3449SJack F Vogel * ixgbe_read_pba_string_generic - Reads part number string from EEPROM 345*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 346*1a4e3449SJack F Vogel * @pba_num: stores the part number string from the EEPROM 347*1a4e3449SJack F Vogel * @pba_num_size: part number string buffer length 348*1a4e3449SJack F Vogel * 349*1a4e3449SJack F Vogel * Reads the part number string from the EEPROM. 350*1a4e3449SJack F Vogel **/ 351*1a4e3449SJack F Vogel s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, 352*1a4e3449SJack F Vogel u32 pba_num_size) 353*1a4e3449SJack F Vogel { 354*1a4e3449SJack F Vogel s32 ret_val; 355*1a4e3449SJack F Vogel u16 data; 356*1a4e3449SJack F Vogel u16 pba_ptr; 357*1a4e3449SJack F Vogel u16 offset; 358*1a4e3449SJack F Vogel u16 length; 359*1a4e3449SJack F Vogel 360*1a4e3449SJack F Vogel DEBUGFUNC("ixgbe_read_pba_string_generic"); 361*1a4e3449SJack F Vogel 362*1a4e3449SJack F Vogel if (pba_num == NULL) { 363*1a4e3449SJack F Vogel DEBUGOUT("PBA string buffer was null\n"); 364*1a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 365*1a4e3449SJack F Vogel } 366*1a4e3449SJack F Vogel 367*1a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); 368*1a4e3449SJack F Vogel if (ret_val) { 369*1a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 370*1a4e3449SJack F Vogel return ret_val; 371*1a4e3449SJack F Vogel } 372*1a4e3449SJack F Vogel 373*1a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr); 374*1a4e3449SJack F Vogel if (ret_val) { 375*1a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 376*1a4e3449SJack F Vogel return ret_val; 377*1a4e3449SJack F Vogel } 378*1a4e3449SJack F Vogel 379*1a4e3449SJack F Vogel /* 380*1a4e3449SJack F Vogel * if data is not ptr guard the PBA must be in legacy format which 381*1a4e3449SJack F Vogel * means pba_ptr is actually our second data word for the PBA number 382*1a4e3449SJack F Vogel * and we can decode it into an ascii string 383*1a4e3449SJack F Vogel */ 384*1a4e3449SJack F Vogel if (data != IXGBE_PBANUM_PTR_GUARD) { 385*1a4e3449SJack F Vogel DEBUGOUT("NVM PBA number is not stored as string\n"); 386*1a4e3449SJack F Vogel 387*1a4e3449SJack F Vogel /* we will need 11 characters to store the PBA */ 388*1a4e3449SJack F Vogel if (pba_num_size < 11) { 389*1a4e3449SJack F Vogel DEBUGOUT("PBA string buffer too small\n"); 390*1a4e3449SJack F Vogel return IXGBE_ERR_NO_SPACE; 391*1a4e3449SJack F Vogel } 392*1a4e3449SJack F Vogel 393*1a4e3449SJack F Vogel /* extract hex string from data and pba_ptr */ 394*1a4e3449SJack F Vogel pba_num[0] = (data >> 12) & 0xF; 395*1a4e3449SJack F Vogel pba_num[1] = (data >> 8) & 0xF; 396*1a4e3449SJack F Vogel pba_num[2] = (data >> 4) & 0xF; 397*1a4e3449SJack F Vogel pba_num[3] = data & 0xF; 398*1a4e3449SJack F Vogel pba_num[4] = (pba_ptr >> 12) & 0xF; 399*1a4e3449SJack F Vogel pba_num[5] = (pba_ptr >> 8) & 0xF; 400*1a4e3449SJack F Vogel pba_num[6] = '-'; 401*1a4e3449SJack F Vogel pba_num[7] = 0; 402*1a4e3449SJack F Vogel pba_num[8] = (pba_ptr >> 4) & 0xF; 403*1a4e3449SJack F Vogel pba_num[9] = pba_ptr & 0xF; 404*1a4e3449SJack F Vogel 405*1a4e3449SJack F Vogel /* put a null character on the end of our string */ 406*1a4e3449SJack F Vogel pba_num[10] = '\0'; 407*1a4e3449SJack F Vogel 408*1a4e3449SJack F Vogel /* switch all the data but the '-' to hex char */ 409*1a4e3449SJack F Vogel for (offset = 0; offset < 10; offset++) { 410*1a4e3449SJack F Vogel if (pba_num[offset] < 0xA) 411*1a4e3449SJack F Vogel pba_num[offset] += '0'; 412*1a4e3449SJack F Vogel else if (pba_num[offset] < 0x10) 413*1a4e3449SJack F Vogel pba_num[offset] += 'A' - 0xA; 414*1a4e3449SJack F Vogel } 415*1a4e3449SJack F Vogel 416*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 417*1a4e3449SJack F Vogel } 418*1a4e3449SJack F Vogel 419*1a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length); 420*1a4e3449SJack F Vogel if (ret_val) { 421*1a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 422*1a4e3449SJack F Vogel return ret_val; 423*1a4e3449SJack F Vogel } 424*1a4e3449SJack F Vogel 425*1a4e3449SJack F Vogel if (length == 0xFFFF || length == 0) { 426*1a4e3449SJack F Vogel DEBUGOUT("NVM PBA number section invalid length\n"); 427*1a4e3449SJack F Vogel return IXGBE_ERR_PBA_SECTION; 428*1a4e3449SJack F Vogel } 429*1a4e3449SJack F Vogel 430*1a4e3449SJack F Vogel /* check if pba_num buffer is big enough */ 431*1a4e3449SJack F Vogel if (pba_num_size < (((u32)length * 2) - 1)) { 432*1a4e3449SJack F Vogel DEBUGOUT("PBA string buffer too small\n"); 433*1a4e3449SJack F Vogel return IXGBE_ERR_NO_SPACE; 434*1a4e3449SJack F Vogel } 435*1a4e3449SJack F Vogel 436*1a4e3449SJack F Vogel /* trim pba length from start of string */ 437*1a4e3449SJack F Vogel pba_ptr++; 438*1a4e3449SJack F Vogel length--; 439*1a4e3449SJack F Vogel 440*1a4e3449SJack F Vogel for (offset = 0; offset < length; offset++) { 441*1a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data); 442*1a4e3449SJack F Vogel if (ret_val) { 443*1a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 444*1a4e3449SJack F Vogel return ret_val; 445*1a4e3449SJack F Vogel } 446*1a4e3449SJack F Vogel pba_num[offset * 2] = (u8)(data >> 8); 447*1a4e3449SJack F Vogel pba_num[(offset * 2) + 1] = (u8)(data & 0xFF); 448*1a4e3449SJack F Vogel } 449*1a4e3449SJack F Vogel pba_num[offset * 2] = '\0'; 450*1a4e3449SJack F Vogel 451*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 452*1a4e3449SJack F Vogel } 453*1a4e3449SJack F Vogel 454*1a4e3449SJack F Vogel /** 455*1a4e3449SJack F Vogel * ixgbe_read_pba_length_generic - Reads part number length from EEPROM 456*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 457*1a4e3449SJack F Vogel * @pba_num_size: part number string buffer length 458*1a4e3449SJack F Vogel * 459*1a4e3449SJack F Vogel * Reads the part number length from the EEPROM. 460*1a4e3449SJack F Vogel * Returns expected buffer size in pba_num_size 461*1a4e3449SJack F Vogel **/ 462*1a4e3449SJack F Vogel s32 ixgbe_read_pba_length_generic(struct ixgbe_hw *hw, u32 *pba_num_size) 463*1a4e3449SJack F Vogel { 464*1a4e3449SJack F Vogel s32 ret_val; 465*1a4e3449SJack F Vogel u16 data; 466*1a4e3449SJack F Vogel u16 pba_ptr; 467*1a4e3449SJack F Vogel u16 length; 468*1a4e3449SJack F Vogel 469*1a4e3449SJack F Vogel DEBUGFUNC("ixgbe_read_pba_length_generic"); 470*1a4e3449SJack F Vogel 471*1a4e3449SJack F Vogel if (pba_num_size == NULL) { 472*1a4e3449SJack F Vogel DEBUGOUT("PBA buffer size was null\n"); 473*1a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 474*1a4e3449SJack F Vogel } 475*1a4e3449SJack F Vogel 476*1a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); 477*1a4e3449SJack F Vogel if (ret_val) { 478*1a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 479*1a4e3449SJack F Vogel return ret_val; 480*1a4e3449SJack F Vogel } 481*1a4e3449SJack F Vogel 482*1a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr); 483*1a4e3449SJack F Vogel if (ret_val) { 484*1a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 485*1a4e3449SJack F Vogel return ret_val; 486*1a4e3449SJack F Vogel } 487*1a4e3449SJack F Vogel 488*1a4e3449SJack F Vogel /* if data is not ptr guard the PBA must be in legacy format */ 489*1a4e3449SJack F Vogel if (data != IXGBE_PBANUM_PTR_GUARD) { 490*1a4e3449SJack F Vogel *pba_num_size = 11; 491*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 492*1a4e3449SJack F Vogel } 493*1a4e3449SJack F Vogel 494*1a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length); 495*1a4e3449SJack F Vogel if (ret_val) { 496*1a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 497*1a4e3449SJack F Vogel return ret_val; 498*1a4e3449SJack F Vogel } 499*1a4e3449SJack F Vogel 500*1a4e3449SJack F Vogel if (length == 0xFFFF || length == 0) { 501*1a4e3449SJack F Vogel DEBUGOUT("NVM PBA number section invalid length\n"); 502*1a4e3449SJack F Vogel return IXGBE_ERR_PBA_SECTION; 503*1a4e3449SJack F Vogel } 504*1a4e3449SJack F Vogel 505*1a4e3449SJack F Vogel /* 506*1a4e3449SJack F Vogel * Convert from length in u16 values to u8 chars, add 1 for NULL, 507*1a4e3449SJack F Vogel * and subtract 2 because length field is included in length. 508*1a4e3449SJack F Vogel */ 509*1a4e3449SJack F Vogel *pba_num_size = ((u32)length * 2) - 1; 51013705f88SJack F Vogel 51113705f88SJack F Vogel return IXGBE_SUCCESS; 51213705f88SJack F Vogel } 51313705f88SJack F Vogel 51413705f88SJack F Vogel /** 5151b6e0dbaSJack F Vogel * ixgbe_read_pba_num_generic - Reads part number from EEPROM 5169ca4041bSJack F Vogel * @hw: pointer to hardware structure 5179ca4041bSJack F Vogel * @pba_num: stores the part number from the EEPROM 5189ca4041bSJack F Vogel * 5199ca4041bSJack F Vogel * Reads the part number from the EEPROM. 5209ca4041bSJack F Vogel **/ 5219ca4041bSJack F Vogel s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) 5229ca4041bSJack F Vogel { 5239ca4041bSJack F Vogel s32 ret_val; 5249ca4041bSJack F Vogel u16 data; 5259ca4041bSJack F Vogel 5269ca4041bSJack F Vogel DEBUGFUNC("ixgbe_read_pba_num_generic"); 5279ca4041bSJack F Vogel 5289ca4041bSJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); 5299ca4041bSJack F Vogel if (ret_val) { 5309ca4041bSJack F Vogel DEBUGOUT("NVM Read Error\n"); 5319ca4041bSJack F Vogel return ret_val; 532*1a4e3449SJack F Vogel } else if (data == IXGBE_PBANUM_PTR_GUARD) { 533*1a4e3449SJack F Vogel DEBUGOUT("NVM Not supported\n"); 534*1a4e3449SJack F Vogel return IXGBE_NOT_IMPLEMENTED; 5359ca4041bSJack F Vogel } 5369ca4041bSJack F Vogel *pba_num = (u32)(data << 16); 5379ca4041bSJack F Vogel 5389ca4041bSJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data); 5399ca4041bSJack F Vogel if (ret_val) { 5409ca4041bSJack F Vogel DEBUGOUT("NVM Read Error\n"); 5419ca4041bSJack F Vogel return ret_val; 5429ca4041bSJack F Vogel } 5439ca4041bSJack F Vogel *pba_num |= data; 5449ca4041bSJack F Vogel 5459ca4041bSJack F Vogel return IXGBE_SUCCESS; 5469ca4041bSJack F Vogel } 5479ca4041bSJack F Vogel 5489ca4041bSJack F Vogel /** 54913705f88SJack F Vogel * ixgbe_get_mac_addr_generic - Generic get MAC address 55013705f88SJack F Vogel * @hw: pointer to hardware structure 55113705f88SJack F Vogel * @mac_addr: Adapter MAC address 55213705f88SJack F Vogel * 55313705f88SJack F Vogel * Reads the adapter's MAC address from first Receive Address Register (RAR0) 55413705f88SJack F Vogel * A reset of the adapter must be performed prior to calling this function 55513705f88SJack F Vogel * in order for the MAC address to have been loaded from the EEPROM into RAR0 55613705f88SJack F Vogel **/ 55713705f88SJack F Vogel s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) 55813705f88SJack F Vogel { 55913705f88SJack F Vogel u32 rar_high; 56013705f88SJack F Vogel u32 rar_low; 56113705f88SJack F Vogel u16 i; 56213705f88SJack F Vogel 5632969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_mac_addr_generic"); 5642969bf0eSJack F Vogel 56513705f88SJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0)); 56613705f88SJack F Vogel rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0)); 56713705f88SJack F Vogel 56813705f88SJack F Vogel for (i = 0; i < 4; i++) 56913705f88SJack F Vogel mac_addr[i] = (u8)(rar_low >> (i*8)); 57013705f88SJack F Vogel 57113705f88SJack F Vogel for (i = 0; i < 2; i++) 57213705f88SJack F Vogel mac_addr[i+4] = (u8)(rar_high >> (i*8)); 57313705f88SJack F Vogel 57413705f88SJack F Vogel return IXGBE_SUCCESS; 57513705f88SJack F Vogel } 57613705f88SJack F Vogel 57713705f88SJack F Vogel /** 57813705f88SJack F Vogel * ixgbe_get_bus_info_generic - Generic set PCI bus info 57913705f88SJack F Vogel * @hw: pointer to hardware structure 58013705f88SJack F Vogel * 58113705f88SJack F Vogel * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure 58213705f88SJack F Vogel **/ 58313705f88SJack F Vogel s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) 58413705f88SJack F Vogel { 5851b6e0dbaSJack F Vogel struct ixgbe_mac_info *mac = &hw->mac; 58613705f88SJack F Vogel u16 link_status; 58713705f88SJack F Vogel 5882969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_bus_info_generic"); 5892969bf0eSJack F Vogel 59013705f88SJack F Vogel hw->bus.type = ixgbe_bus_type_pci_express; 59113705f88SJack F Vogel 59213705f88SJack F Vogel /* Get the negotiated link width and speed from PCI config space */ 59313705f88SJack F Vogel link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); 59413705f88SJack F Vogel 59513705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_WIDTH) { 59613705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_1: 59713705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x1; 59813705f88SJack F Vogel break; 59913705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_2: 60013705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x2; 60113705f88SJack F Vogel break; 60213705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_4: 60313705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x4; 60413705f88SJack F Vogel break; 60513705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_8: 60613705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x8; 60713705f88SJack F Vogel break; 60813705f88SJack F Vogel default: 60913705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_unknown; 61013705f88SJack F Vogel break; 61113705f88SJack F Vogel } 61213705f88SJack F Vogel 61313705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_SPEED) { 61413705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_2500: 61513705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_2500; 61613705f88SJack F Vogel break; 61713705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_5000: 61813705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_5000; 61913705f88SJack F Vogel break; 62013705f88SJack F Vogel default: 62113705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_unknown; 62213705f88SJack F Vogel break; 62313705f88SJack F Vogel } 62413705f88SJack F Vogel 6251b6e0dbaSJack F Vogel mac->ops.set_lan_id(hw); 6261b6e0dbaSJack F Vogel 62713705f88SJack F Vogel return IXGBE_SUCCESS; 62813705f88SJack F Vogel } 62913705f88SJack F Vogel 63013705f88SJack F Vogel /** 6311b6e0dbaSJack F Vogel * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices 6321b6e0dbaSJack F Vogel * @hw: pointer to the HW structure 6331b6e0dbaSJack F Vogel * 6341b6e0dbaSJack F Vogel * Determines the LAN function id by reading memory-mapped registers 6351b6e0dbaSJack F Vogel * and swaps the port value if requested. 6361b6e0dbaSJack F Vogel **/ 6371b6e0dbaSJack F Vogel void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) 6381b6e0dbaSJack F Vogel { 6391b6e0dbaSJack F Vogel struct ixgbe_bus_info *bus = &hw->bus; 6401b6e0dbaSJack F Vogel u32 reg; 6411b6e0dbaSJack F Vogel 6422969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); 6432969bf0eSJack F Vogel 6441b6e0dbaSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_STATUS); 6451b6e0dbaSJack F Vogel bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; 6460ac6dfecSJack F Vogel bus->lan_id = bus->func; 6471b6e0dbaSJack F Vogel 6481b6e0dbaSJack F Vogel /* check for a port swap */ 6491b6e0dbaSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_FACTPS); 6501b6e0dbaSJack F Vogel if (reg & IXGBE_FACTPS_LFS) 6511b6e0dbaSJack F Vogel bus->func ^= 0x1; 6521b6e0dbaSJack F Vogel } 6531b6e0dbaSJack F Vogel 6541b6e0dbaSJack F Vogel /** 6559ca4041bSJack F Vogel * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units 65613705f88SJack F Vogel * @hw: pointer to hardware structure 65713705f88SJack F Vogel * 65813705f88SJack F Vogel * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, 65913705f88SJack F Vogel * disables transmit and receive units. The adapter_stopped flag is used by 66013705f88SJack F Vogel * the shared code and drivers to determine if the adapter is in a stopped 66113705f88SJack F Vogel * state and should not touch the hardware. 66213705f88SJack F Vogel **/ 66313705f88SJack F Vogel s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) 66413705f88SJack F Vogel { 66513705f88SJack F Vogel u32 number_of_queues; 66613705f88SJack F Vogel u32 reg_val; 66713705f88SJack F Vogel u16 i; 66813705f88SJack F Vogel 6692969bf0eSJack F Vogel DEBUGFUNC("ixgbe_stop_adapter_generic"); 6702969bf0eSJack F Vogel 67113705f88SJack F Vogel /* 67213705f88SJack F Vogel * Set the adapter_stopped flag so other driver functions stop touching 67313705f88SJack F Vogel * the hardware 67413705f88SJack F Vogel */ 67513705f88SJack F Vogel hw->adapter_stopped = TRUE; 67613705f88SJack F Vogel 67713705f88SJack F Vogel /* Disable the receive unit */ 67813705f88SJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 67913705f88SJack F Vogel reg_val &= ~(IXGBE_RXCTRL_RXEN); 68013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val); 6819ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 68213705f88SJack F Vogel msec_delay(2); 68313705f88SJack F Vogel 68413705f88SJack F Vogel /* Clear interrupt mask to stop from interrupts being generated */ 68513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); 68613705f88SJack F Vogel 68713705f88SJack F Vogel /* Clear any pending interrupts */ 68813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_EICR); 68913705f88SJack F Vogel 69013705f88SJack F Vogel /* Disable the transmit unit. Each queue must be disabled. */ 6919ca4041bSJack F Vogel number_of_queues = hw->mac.max_tx_queues; 69213705f88SJack F Vogel for (i = 0; i < number_of_queues; i++) { 69313705f88SJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); 69413705f88SJack F Vogel if (reg_val & IXGBE_TXDCTL_ENABLE) { 69513705f88SJack F Vogel reg_val &= ~IXGBE_TXDCTL_ENABLE; 69613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), reg_val); 69713705f88SJack F Vogel } 69813705f88SJack F Vogel } 69913705f88SJack F Vogel 7009ca4041bSJack F Vogel /* 7019ca4041bSJack F Vogel * Prevent the PCI-E bus from from hanging by disabling PCI-E master 7029ca4041bSJack F Vogel * access and verify no pending requests 7039ca4041bSJack F Vogel */ 704c0014855SJack F Vogel ixgbe_disable_pcie_master(hw); 7059ca4041bSJack F Vogel 70613705f88SJack F Vogel return IXGBE_SUCCESS; 70713705f88SJack F Vogel } 70813705f88SJack F Vogel 70913705f88SJack F Vogel /** 71013705f88SJack F Vogel * ixgbe_led_on_generic - Turns on the software controllable LEDs. 71113705f88SJack F Vogel * @hw: pointer to hardware structure 71213705f88SJack F Vogel * @index: led number to turn on 71313705f88SJack F Vogel **/ 71413705f88SJack F Vogel s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) 71513705f88SJack F Vogel { 71613705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 71713705f88SJack F Vogel 7182969bf0eSJack F Vogel DEBUGFUNC("ixgbe_led_on_generic"); 7192969bf0eSJack F Vogel 72013705f88SJack F Vogel /* To turn on the LED, set mode to ON. */ 72113705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 72213705f88SJack F Vogel led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); 72313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 7249ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 72513705f88SJack F Vogel 72613705f88SJack F Vogel return IXGBE_SUCCESS; 72713705f88SJack F Vogel } 72813705f88SJack F Vogel 72913705f88SJack F Vogel /** 73013705f88SJack F Vogel * ixgbe_led_off_generic - Turns off the software controllable LEDs. 73113705f88SJack F Vogel * @hw: pointer to hardware structure 73213705f88SJack F Vogel * @index: led number to turn off 73313705f88SJack F Vogel **/ 73413705f88SJack F Vogel s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) 73513705f88SJack F Vogel { 73613705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 73713705f88SJack F Vogel 7382969bf0eSJack F Vogel DEBUGFUNC("ixgbe_led_off_generic"); 7392969bf0eSJack F Vogel 74013705f88SJack F Vogel /* To turn off the LED, set mode to OFF. */ 74113705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 74213705f88SJack F Vogel led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); 74313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 7449ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 74513705f88SJack F Vogel 74613705f88SJack F Vogel return IXGBE_SUCCESS; 74713705f88SJack F Vogel } 74813705f88SJack F Vogel 74913705f88SJack F Vogel /** 75013705f88SJack F Vogel * ixgbe_init_eeprom_params_generic - Initialize EEPROM params 75113705f88SJack F Vogel * @hw: pointer to hardware structure 75213705f88SJack F Vogel * 75313705f88SJack F Vogel * Initializes the EEPROM parameters ixgbe_eeprom_info within the 75413705f88SJack F Vogel * ixgbe_hw struct in order to set up EEPROM access. 75513705f88SJack F Vogel **/ 75613705f88SJack F Vogel s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) 75713705f88SJack F Vogel { 75813705f88SJack F Vogel struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 75913705f88SJack F Vogel u32 eec; 76013705f88SJack F Vogel u16 eeprom_size; 76113705f88SJack F Vogel 7622969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_eeprom_params_generic"); 7632969bf0eSJack F Vogel 76413705f88SJack F Vogel if (eeprom->type == ixgbe_eeprom_uninitialized) { 76513705f88SJack F Vogel eeprom->type = ixgbe_eeprom_none; 7665b7f4cedSJack F Vogel /* Set default semaphore delay to 10ms which is a well 7675b7f4cedSJack F Vogel * tested value */ 7685b7f4cedSJack F Vogel eeprom->semaphore_delay = 10; 76913705f88SJack F Vogel 77013705f88SJack F Vogel /* 77113705f88SJack F Vogel * Check for EEPROM present first. 77213705f88SJack F Vogel * If not present leave as none 77313705f88SJack F Vogel */ 77413705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 77513705f88SJack F Vogel if (eec & IXGBE_EEC_PRES) { 77613705f88SJack F Vogel eeprom->type = ixgbe_eeprom_spi; 77713705f88SJack F Vogel 77813705f88SJack F Vogel /* 77913705f88SJack F Vogel * SPI EEPROM is assumed here. This code would need to 78013705f88SJack F Vogel * change if a future EEPROM is not SPI. 78113705f88SJack F Vogel */ 78213705f88SJack F Vogel eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 78313705f88SJack F Vogel IXGBE_EEC_SIZE_SHIFT); 78413705f88SJack F Vogel eeprom->word_size = 1 << (eeprom_size + 7852969bf0eSJack F Vogel IXGBE_EEPROM_WORD_SIZE_BASE_SHIFT); 78613705f88SJack F Vogel } 78713705f88SJack F Vogel 78813705f88SJack F Vogel if (eec & IXGBE_EEC_ADDR_SIZE) 78913705f88SJack F Vogel eeprom->address_bits = 16; 79013705f88SJack F Vogel else 79113705f88SJack F Vogel eeprom->address_bits = 8; 79213705f88SJack F Vogel DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: " 79313705f88SJack F Vogel "%d\n", eeprom->type, eeprom->word_size, 79413705f88SJack F Vogel eeprom->address_bits); 79513705f88SJack F Vogel } 79613705f88SJack F Vogel 79713705f88SJack F Vogel return IXGBE_SUCCESS; 79813705f88SJack F Vogel } 79913705f88SJack F Vogel 80013705f88SJack F Vogel /** 80113705f88SJack F Vogel * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM 80213705f88SJack F Vogel * @hw: pointer to hardware structure 80313705f88SJack F Vogel * @offset: offset within the EEPROM to be written to 80413705f88SJack F Vogel * @data: 16 bit word to be written to the EEPROM 80513705f88SJack F Vogel * 80613705f88SJack F Vogel * If ixgbe_eeprom_update_checksum is not called after this function, the 80713705f88SJack F Vogel * EEPROM will most likely contain an invalid checksum. 80813705f88SJack F Vogel **/ 80913705f88SJack F Vogel s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) 81013705f88SJack F Vogel { 81113705f88SJack F Vogel s32 status; 81213705f88SJack F Vogel u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI; 81313705f88SJack F Vogel 8142969bf0eSJack F Vogel DEBUGFUNC("ixgbe_write_eeprom_generic"); 8152969bf0eSJack F Vogel 8169ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 8179ca4041bSJack F Vogel 8189ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 8199ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 8209ca4041bSJack F Vogel goto out; 8219ca4041bSJack F Vogel } 8229ca4041bSJack F Vogel 82313705f88SJack F Vogel /* Prepare the EEPROM for writing */ 82413705f88SJack F Vogel status = ixgbe_acquire_eeprom(hw); 82513705f88SJack F Vogel 82613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 82713705f88SJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 82813705f88SJack F Vogel ixgbe_release_eeprom(hw); 82913705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 83013705f88SJack F Vogel } 83113705f88SJack F Vogel } 83213705f88SJack F Vogel 83313705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 83413705f88SJack F Vogel ixgbe_standby_eeprom(hw); 83513705f88SJack F Vogel 83613705f88SJack F Vogel /* Send the WRITE ENABLE command (8 bit opcode ) */ 83713705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI, 83813705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 83913705f88SJack F Vogel 84013705f88SJack F Vogel ixgbe_standby_eeprom(hw); 84113705f88SJack F Vogel 84213705f88SJack F Vogel /* 84313705f88SJack F Vogel * Some SPI eeproms use the 8th address bit embedded in the 84413705f88SJack F Vogel * opcode 84513705f88SJack F Vogel */ 84613705f88SJack F Vogel if ((hw->eeprom.address_bits == 8) && (offset >= 128)) 84713705f88SJack F Vogel write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 84813705f88SJack F Vogel 84913705f88SJack F Vogel /* Send the Write command (8-bit opcode + addr) */ 85013705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, write_opcode, 85113705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 85213705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), 85313705f88SJack F Vogel hw->eeprom.address_bits); 85413705f88SJack F Vogel 85513705f88SJack F Vogel /* Send the data */ 85613705f88SJack F Vogel data = (data >> 8) | (data << 8); 85713705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, data, 16); 85813705f88SJack F Vogel ixgbe_standby_eeprom(hw); 85913705f88SJack F Vogel 86013705f88SJack F Vogel /* Done with writing - release the EEPROM */ 86113705f88SJack F Vogel ixgbe_release_eeprom(hw); 86213705f88SJack F Vogel } 86313705f88SJack F Vogel 8649ca4041bSJack F Vogel out: 86513705f88SJack F Vogel return status; 86613705f88SJack F Vogel } 86713705f88SJack F Vogel 86813705f88SJack F Vogel /** 86913705f88SJack F Vogel * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang 87013705f88SJack F Vogel * @hw: pointer to hardware structure 87113705f88SJack F Vogel * @offset: offset within the EEPROM to be read 87213705f88SJack F Vogel * @data: read 16 bit value from EEPROM 87313705f88SJack F Vogel * 87413705f88SJack F Vogel * Reads 16 bit value from EEPROM through bit-bang method 87513705f88SJack F Vogel **/ 87613705f88SJack F Vogel s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, 87713705f88SJack F Vogel u16 *data) 87813705f88SJack F Vogel { 87913705f88SJack F Vogel s32 status; 88013705f88SJack F Vogel u16 word_in; 88113705f88SJack F Vogel u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; 88213705f88SJack F Vogel 8832969bf0eSJack F Vogel DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic"); 8842969bf0eSJack F Vogel 8859ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 8869ca4041bSJack F Vogel 8879ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 8889ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 8899ca4041bSJack F Vogel goto out; 8909ca4041bSJack F Vogel } 8919ca4041bSJack F Vogel 89213705f88SJack F Vogel /* Prepare the EEPROM for reading */ 89313705f88SJack F Vogel status = ixgbe_acquire_eeprom(hw); 89413705f88SJack F Vogel 89513705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 89613705f88SJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 89713705f88SJack F Vogel ixgbe_release_eeprom(hw); 89813705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 89913705f88SJack F Vogel } 90013705f88SJack F Vogel } 90113705f88SJack F Vogel 90213705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 90313705f88SJack F Vogel ixgbe_standby_eeprom(hw); 90413705f88SJack F Vogel 90513705f88SJack F Vogel /* 90613705f88SJack F Vogel * Some SPI eeproms use the 8th address bit embedded in the 90713705f88SJack F Vogel * opcode 90813705f88SJack F Vogel */ 90913705f88SJack F Vogel if ((hw->eeprom.address_bits == 8) && (offset >= 128)) 91013705f88SJack F Vogel read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 91113705f88SJack F Vogel 91213705f88SJack F Vogel /* Send the READ command (opcode + addr) */ 91313705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, read_opcode, 91413705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 91513705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), 91613705f88SJack F Vogel hw->eeprom.address_bits); 91713705f88SJack F Vogel 91813705f88SJack F Vogel /* Read the data. */ 91913705f88SJack F Vogel word_in = ixgbe_shift_in_eeprom_bits(hw, 16); 92013705f88SJack F Vogel *data = (word_in >> 8) | (word_in << 8); 92113705f88SJack F Vogel 92213705f88SJack F Vogel /* End this read operation */ 92313705f88SJack F Vogel ixgbe_release_eeprom(hw); 92413705f88SJack F Vogel } 92513705f88SJack F Vogel 9269ca4041bSJack F Vogel out: 92713705f88SJack F Vogel return status; 92813705f88SJack F Vogel } 92913705f88SJack F Vogel 93013705f88SJack F Vogel /** 9312969bf0eSJack F Vogel * ixgbe_read_eerd_generic - Read EEPROM word using EERD 93213705f88SJack F Vogel * @hw: pointer to hardware structure 93313705f88SJack F Vogel * @offset: offset of word in the EEPROM to read 93413705f88SJack F Vogel * @data: word read from the EEPROM 93513705f88SJack F Vogel * 93613705f88SJack F Vogel * Reads a 16 bit word from the EEPROM using the EERD register. 93713705f88SJack F Vogel **/ 9382969bf0eSJack F Vogel s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) 93913705f88SJack F Vogel { 94013705f88SJack F Vogel u32 eerd; 94113705f88SJack F Vogel s32 status; 94213705f88SJack F Vogel 9432969bf0eSJack F Vogel DEBUGFUNC("ixgbe_read_eerd_generic"); 9442969bf0eSJack F Vogel 9459ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 9469ca4041bSJack F Vogel 9479ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 9489ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 9499ca4041bSJack F Vogel goto out; 9509ca4041bSJack F Vogel } 9519ca4041bSJack F Vogel 9522969bf0eSJack F Vogel eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) + 9532969bf0eSJack F Vogel IXGBE_EEPROM_RW_REG_START; 95413705f88SJack F Vogel 95513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); 9562969bf0eSJack F Vogel status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ); 95713705f88SJack F Vogel 95813705f88SJack F Vogel if (status == IXGBE_SUCCESS) 95913705f88SJack F Vogel *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >> 9602969bf0eSJack F Vogel IXGBE_EEPROM_RW_REG_DATA); 96113705f88SJack F Vogel else 96213705f88SJack F Vogel DEBUGOUT("Eeprom read timed out\n"); 96313705f88SJack F Vogel 9649ca4041bSJack F Vogel out: 96513705f88SJack F Vogel return status; 96613705f88SJack F Vogel } 96713705f88SJack F Vogel 96813705f88SJack F Vogel /** 969*1a4e3449SJack F Vogel * ixgbe_write_eewr_generic - Write EEPROM word using EEWR 970*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 971*1a4e3449SJack F Vogel * @offset: offset of word in the EEPROM to write 972*1a4e3449SJack F Vogel * @data: word write to the EEPROM 973*1a4e3449SJack F Vogel * 974*1a4e3449SJack F Vogel * Write a 16 bit word to the EEPROM using the EEWR register. 975*1a4e3449SJack F Vogel **/ 976*1a4e3449SJack F Vogel s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data) 977*1a4e3449SJack F Vogel { 978*1a4e3449SJack F Vogel u32 eewr; 979*1a4e3449SJack F Vogel s32 status; 980*1a4e3449SJack F Vogel 981*1a4e3449SJack F Vogel DEBUGFUNC("ixgbe_write_eewr_generic"); 982*1a4e3449SJack F Vogel 983*1a4e3449SJack F Vogel hw->eeprom.ops.init_params(hw); 984*1a4e3449SJack F Vogel 985*1a4e3449SJack F Vogel if (offset >= hw->eeprom.word_size) { 986*1a4e3449SJack F Vogel status = IXGBE_ERR_EEPROM; 987*1a4e3449SJack F Vogel goto out; 988*1a4e3449SJack F Vogel } 989*1a4e3449SJack F Vogel 990*1a4e3449SJack F Vogel eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) | 991*1a4e3449SJack F Vogel (data << IXGBE_EEPROM_RW_REG_DATA) | IXGBE_EEPROM_RW_REG_START; 992*1a4e3449SJack F Vogel 993*1a4e3449SJack F Vogel status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); 994*1a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) { 995*1a4e3449SJack F Vogel DEBUGOUT("Eeprom write EEWR timed out\n"); 996*1a4e3449SJack F Vogel goto out; 997*1a4e3449SJack F Vogel } 998*1a4e3449SJack F Vogel 999*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr); 1000*1a4e3449SJack F Vogel 1001*1a4e3449SJack F Vogel status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); 1002*1a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) { 1003*1a4e3449SJack F Vogel DEBUGOUT("Eeprom write EEWR timed out\n"); 1004*1a4e3449SJack F Vogel goto out; 1005*1a4e3449SJack F Vogel } 1006*1a4e3449SJack F Vogel 1007*1a4e3449SJack F Vogel out: 1008*1a4e3449SJack F Vogel return status; 1009*1a4e3449SJack F Vogel } 1010*1a4e3449SJack F Vogel 1011*1a4e3449SJack F Vogel /** 10122969bf0eSJack F Vogel * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status 101313705f88SJack F Vogel * @hw: pointer to hardware structure 10142969bf0eSJack F Vogel * @ee_reg: EEPROM flag for polling 101513705f88SJack F Vogel * 10162969bf0eSJack F Vogel * Polls the status bit (bit 1) of the EERD or EEWR to determine when the 10172969bf0eSJack F Vogel * read or write is done respectively. 101813705f88SJack F Vogel **/ 10192969bf0eSJack F Vogel s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) 102013705f88SJack F Vogel { 102113705f88SJack F Vogel u32 i; 102213705f88SJack F Vogel u32 reg; 102313705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 102413705f88SJack F Vogel 10252969bf0eSJack F Vogel DEBUGFUNC("ixgbe_poll_eerd_eewr_done"); 10262969bf0eSJack F Vogel 10272969bf0eSJack F Vogel for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) { 10282969bf0eSJack F Vogel if (ee_reg == IXGBE_NVM_POLL_READ) 102913705f88SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_EERD); 10302969bf0eSJack F Vogel else 10312969bf0eSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_EEWR); 10322969bf0eSJack F Vogel 10332969bf0eSJack F Vogel if (reg & IXGBE_EEPROM_RW_REG_DONE) { 103413705f88SJack F Vogel status = IXGBE_SUCCESS; 103513705f88SJack F Vogel break; 103613705f88SJack F Vogel } 103713705f88SJack F Vogel usec_delay(5); 103813705f88SJack F Vogel } 103913705f88SJack F Vogel return status; 104013705f88SJack F Vogel } 104113705f88SJack F Vogel 104213705f88SJack F Vogel /** 104313705f88SJack F Vogel * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang 104413705f88SJack F Vogel * @hw: pointer to hardware structure 104513705f88SJack F Vogel * 104613705f88SJack F Vogel * Prepares EEPROM for access using bit-bang method. This function should 104713705f88SJack F Vogel * be called before issuing a command to the EEPROM. 104813705f88SJack F Vogel **/ 104913705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) 105013705f88SJack F Vogel { 105113705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 105213705f88SJack F Vogel u32 eec; 105313705f88SJack F Vogel u32 i; 105413705f88SJack F Vogel 10552969bf0eSJack F Vogel DEBUGFUNC("ixgbe_acquire_eeprom"); 10562969bf0eSJack F Vogel 105713705f88SJack F Vogel if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != IXGBE_SUCCESS) 105813705f88SJack F Vogel status = IXGBE_ERR_SWFW_SYNC; 105913705f88SJack F Vogel 106013705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 106113705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 106213705f88SJack F Vogel 106313705f88SJack F Vogel /* Request EEPROM Access */ 106413705f88SJack F Vogel eec |= IXGBE_EEC_REQ; 106513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 106613705f88SJack F Vogel 106713705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { 106813705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 106913705f88SJack F Vogel if (eec & IXGBE_EEC_GNT) 107013705f88SJack F Vogel break; 107113705f88SJack F Vogel usec_delay(5); 107213705f88SJack F Vogel } 107313705f88SJack F Vogel 10749ca4041bSJack F Vogel /* Release if grant not acquired */ 107513705f88SJack F Vogel if (!(eec & IXGBE_EEC_GNT)) { 107613705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 107713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 107813705f88SJack F Vogel DEBUGOUT("Could not acquire EEPROM grant\n"); 107913705f88SJack F Vogel 108013705f88SJack F Vogel ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 108113705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 108213705f88SJack F Vogel } 108313705f88SJack F Vogel 108413705f88SJack F Vogel /* Setup EEPROM for Read/Write */ 108513705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 108613705f88SJack F Vogel /* Clear CS and SK */ 108713705f88SJack F Vogel eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); 108813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 108913705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 109013705f88SJack F Vogel usec_delay(1); 109113705f88SJack F Vogel } 1092*1a4e3449SJack F Vogel } 109313705f88SJack F Vogel return status; 109413705f88SJack F Vogel } 109513705f88SJack F Vogel 109613705f88SJack F Vogel /** 109713705f88SJack F Vogel * ixgbe_get_eeprom_semaphore - Get hardware semaphore 109813705f88SJack F Vogel * @hw: pointer to hardware structure 109913705f88SJack F Vogel * 110013705f88SJack F Vogel * Sets the hardware semaphores so EEPROM access can occur for bit-bang method 110113705f88SJack F Vogel **/ 110213705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) 110313705f88SJack F Vogel { 110413705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 1105d8602bb9SJack F Vogel u32 timeout = 2000; 110613705f88SJack F Vogel u32 i; 110713705f88SJack F Vogel u32 swsm; 110813705f88SJack F Vogel 11092969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_eeprom_semaphore"); 11102969bf0eSJack F Vogel 1111*1a4e3449SJack F Vogel 111213705f88SJack F Vogel /* Get SMBI software semaphore between device drivers first */ 111313705f88SJack F Vogel for (i = 0; i < timeout; i++) { 111413705f88SJack F Vogel /* 111513705f88SJack F Vogel * If the SMBI bit is 0 when we read it, then the bit will be 111613705f88SJack F Vogel * set and we have the semaphore 111713705f88SJack F Vogel */ 111813705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 111913705f88SJack F Vogel if (!(swsm & IXGBE_SWSM_SMBI)) { 112013705f88SJack F Vogel status = IXGBE_SUCCESS; 112113705f88SJack F Vogel break; 112213705f88SJack F Vogel } 11230ac6dfecSJack F Vogel usec_delay(50); 112413705f88SJack F Vogel } 112513705f88SJack F Vogel 112613705f88SJack F Vogel /* Now get the semaphore between SW/FW through the SWESMBI bit */ 112713705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 112813705f88SJack F Vogel for (i = 0; i < timeout; i++) { 112913705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 113013705f88SJack F Vogel 113113705f88SJack F Vogel /* Set the SW EEPROM semaphore bit to request access */ 113213705f88SJack F Vogel swsm |= IXGBE_SWSM_SWESMBI; 113313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 113413705f88SJack F Vogel 113513705f88SJack F Vogel /* 113613705f88SJack F Vogel * If we set the bit successfully then we got the 113713705f88SJack F Vogel * semaphore. 113813705f88SJack F Vogel */ 113913705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 114013705f88SJack F Vogel if (swsm & IXGBE_SWSM_SWESMBI) 114113705f88SJack F Vogel break; 114213705f88SJack F Vogel 114313705f88SJack F Vogel usec_delay(50); 114413705f88SJack F Vogel } 114513705f88SJack F Vogel 114613705f88SJack F Vogel /* 114713705f88SJack F Vogel * Release semaphores and return error if SW EEPROM semaphore 114813705f88SJack F Vogel * was not granted because we don't have access to the EEPROM 114913705f88SJack F Vogel */ 115013705f88SJack F Vogel if (i >= timeout) { 11510ac6dfecSJack F Vogel DEBUGOUT("SWESMBI Software EEPROM semaphore " 115213705f88SJack F Vogel "not granted.\n"); 115313705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 115413705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 115513705f88SJack F Vogel } 11560ac6dfecSJack F Vogel } else { 11570ac6dfecSJack F Vogel DEBUGOUT("Software semaphore SMBI between device drivers " 11580ac6dfecSJack F Vogel "not granted.\n"); 115913705f88SJack F Vogel } 116013705f88SJack F Vogel 116113705f88SJack F Vogel return status; 116213705f88SJack F Vogel } 116313705f88SJack F Vogel 116413705f88SJack F Vogel /** 116513705f88SJack F Vogel * ixgbe_release_eeprom_semaphore - Release hardware semaphore 116613705f88SJack F Vogel * @hw: pointer to hardware structure 116713705f88SJack F Vogel * 116813705f88SJack F Vogel * This function clears hardware semaphore bits. 116913705f88SJack F Vogel **/ 117013705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) 117113705f88SJack F Vogel { 117213705f88SJack F Vogel u32 swsm; 117313705f88SJack F Vogel 11742969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_eeprom_semaphore"); 11752969bf0eSJack F Vogel 117613705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 117713705f88SJack F Vogel 117813705f88SJack F Vogel /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ 117913705f88SJack F Vogel swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI); 118013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 11819ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 118213705f88SJack F Vogel } 118313705f88SJack F Vogel 118413705f88SJack F Vogel /** 118513705f88SJack F Vogel * ixgbe_ready_eeprom - Polls for EEPROM ready 118613705f88SJack F Vogel * @hw: pointer to hardware structure 118713705f88SJack F Vogel **/ 118813705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) 118913705f88SJack F Vogel { 119013705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 119113705f88SJack F Vogel u16 i; 119213705f88SJack F Vogel u8 spi_stat_reg; 119313705f88SJack F Vogel 11942969bf0eSJack F Vogel DEBUGFUNC("ixgbe_ready_eeprom"); 11952969bf0eSJack F Vogel 119613705f88SJack F Vogel /* 119713705f88SJack F Vogel * Read "Status Register" repeatedly until the LSB is cleared. The 119813705f88SJack F Vogel * EEPROM will signal that the command has been completed by clearing 119913705f88SJack F Vogel * bit 0 of the internal status register. If it's not cleared within 120013705f88SJack F Vogel * 5 milliseconds, then error out. 120113705f88SJack F Vogel */ 120213705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) { 120313705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI, 120413705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 120513705f88SJack F Vogel spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8); 120613705f88SJack F Vogel if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI)) 120713705f88SJack F Vogel break; 120813705f88SJack F Vogel 120913705f88SJack F Vogel usec_delay(5); 121013705f88SJack F Vogel ixgbe_standby_eeprom(hw); 121113705f88SJack F Vogel }; 121213705f88SJack F Vogel 121313705f88SJack F Vogel /* 121413705f88SJack F Vogel * On some parts, SPI write time could vary from 0-20mSec on 3.3V 121513705f88SJack F Vogel * devices (and only 0-5mSec on 5V devices) 121613705f88SJack F Vogel */ 121713705f88SJack F Vogel if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { 121813705f88SJack F Vogel DEBUGOUT("SPI EEPROM Status error\n"); 121913705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 122013705f88SJack F Vogel } 122113705f88SJack F Vogel 122213705f88SJack F Vogel return status; 122313705f88SJack F Vogel } 122413705f88SJack F Vogel 122513705f88SJack F Vogel /** 122613705f88SJack F Vogel * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state 122713705f88SJack F Vogel * @hw: pointer to hardware structure 122813705f88SJack F Vogel **/ 122913705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw) 123013705f88SJack F Vogel { 123113705f88SJack F Vogel u32 eec; 123213705f88SJack F Vogel 12332969bf0eSJack F Vogel DEBUGFUNC("ixgbe_standby_eeprom"); 12342969bf0eSJack F Vogel 123513705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 123613705f88SJack F Vogel 123713705f88SJack F Vogel /* Toggle CS to flush commands */ 123813705f88SJack F Vogel eec |= IXGBE_EEC_CS; 123913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 124013705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 124113705f88SJack F Vogel usec_delay(1); 124213705f88SJack F Vogel eec &= ~IXGBE_EEC_CS; 124313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 124413705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 124513705f88SJack F Vogel usec_delay(1); 124613705f88SJack F Vogel } 124713705f88SJack F Vogel 124813705f88SJack F Vogel /** 124913705f88SJack F Vogel * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM. 125013705f88SJack F Vogel * @hw: pointer to hardware structure 125113705f88SJack F Vogel * @data: data to send to the EEPROM 125213705f88SJack F Vogel * @count: number of bits to shift out 125313705f88SJack F Vogel **/ 125413705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, 125513705f88SJack F Vogel u16 count) 125613705f88SJack F Vogel { 125713705f88SJack F Vogel u32 eec; 125813705f88SJack F Vogel u32 mask; 125913705f88SJack F Vogel u32 i; 126013705f88SJack F Vogel 12612969bf0eSJack F Vogel DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); 12622969bf0eSJack F Vogel 126313705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 126413705f88SJack F Vogel 126513705f88SJack F Vogel /* 126613705f88SJack F Vogel * Mask is used to shift "count" bits of "data" out to the EEPROM 126713705f88SJack F Vogel * one bit at a time. Determine the starting bit based on count 126813705f88SJack F Vogel */ 126913705f88SJack F Vogel mask = 0x01 << (count - 1); 127013705f88SJack F Vogel 127113705f88SJack F Vogel for (i = 0; i < count; i++) { 127213705f88SJack F Vogel /* 127313705f88SJack F Vogel * A "1" is shifted out to the EEPROM by setting bit "DI" to a 127413705f88SJack F Vogel * "1", and then raising and then lowering the clock (the SK 127513705f88SJack F Vogel * bit controls the clock input to the EEPROM). A "0" is 127613705f88SJack F Vogel * shifted out to the EEPROM by setting "DI" to "0" and then 127713705f88SJack F Vogel * raising and then lowering the clock. 127813705f88SJack F Vogel */ 127913705f88SJack F Vogel if (data & mask) 128013705f88SJack F Vogel eec |= IXGBE_EEC_DI; 128113705f88SJack F Vogel else 128213705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 128313705f88SJack F Vogel 128413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 128513705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 128613705f88SJack F Vogel 128713705f88SJack F Vogel usec_delay(1); 128813705f88SJack F Vogel 128913705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 129013705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 129113705f88SJack F Vogel 129213705f88SJack F Vogel /* 129313705f88SJack F Vogel * Shift mask to signify next bit of data to shift in to the 129413705f88SJack F Vogel * EEPROM 129513705f88SJack F Vogel */ 129613705f88SJack F Vogel mask = mask >> 1; 129713705f88SJack F Vogel }; 129813705f88SJack F Vogel 129913705f88SJack F Vogel /* We leave the "DI" bit set to "0" when we leave this routine. */ 130013705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 130113705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 130213705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 130313705f88SJack F Vogel } 130413705f88SJack F Vogel 130513705f88SJack F Vogel /** 130613705f88SJack F Vogel * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM 130713705f88SJack F Vogel * @hw: pointer to hardware structure 130813705f88SJack F Vogel **/ 130913705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) 131013705f88SJack F Vogel { 131113705f88SJack F Vogel u32 eec; 131213705f88SJack F Vogel u32 i; 131313705f88SJack F Vogel u16 data = 0; 131413705f88SJack F Vogel 13152969bf0eSJack F Vogel DEBUGFUNC("ixgbe_shift_in_eeprom_bits"); 13162969bf0eSJack F Vogel 131713705f88SJack F Vogel /* 131813705f88SJack F Vogel * In order to read a register from the EEPROM, we need to shift 131913705f88SJack F Vogel * 'count' bits in from the EEPROM. Bits are "shifted in" by raising 132013705f88SJack F Vogel * the clock input to the EEPROM (setting the SK bit), and then reading 132113705f88SJack F Vogel * the value of the "DO" bit. During this "shifting in" process the 132213705f88SJack F Vogel * "DI" bit should always be clear. 132313705f88SJack F Vogel */ 132413705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 132513705f88SJack F Vogel 132613705f88SJack F Vogel eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); 132713705f88SJack F Vogel 132813705f88SJack F Vogel for (i = 0; i < count; i++) { 132913705f88SJack F Vogel data = data << 1; 133013705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 133113705f88SJack F Vogel 133213705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 133313705f88SJack F Vogel 133413705f88SJack F Vogel eec &= ~(IXGBE_EEC_DI); 133513705f88SJack F Vogel if (eec & IXGBE_EEC_DO) 133613705f88SJack F Vogel data |= 1; 133713705f88SJack F Vogel 133813705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 133913705f88SJack F Vogel } 134013705f88SJack F Vogel 134113705f88SJack F Vogel return data; 134213705f88SJack F Vogel } 134313705f88SJack F Vogel 134413705f88SJack F Vogel /** 134513705f88SJack F Vogel * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input. 134613705f88SJack F Vogel * @hw: pointer to hardware structure 134713705f88SJack F Vogel * @eec: EEC register's current value 134813705f88SJack F Vogel **/ 134913705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 135013705f88SJack F Vogel { 13512969bf0eSJack F Vogel DEBUGFUNC("ixgbe_raise_eeprom_clk"); 13522969bf0eSJack F Vogel 135313705f88SJack F Vogel /* 135413705f88SJack F Vogel * Raise the clock input to the EEPROM 135513705f88SJack F Vogel * (setting the SK bit), then delay 135613705f88SJack F Vogel */ 135713705f88SJack F Vogel *eec = *eec | IXGBE_EEC_SK; 135813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 135913705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 136013705f88SJack F Vogel usec_delay(1); 136113705f88SJack F Vogel } 136213705f88SJack F Vogel 136313705f88SJack F Vogel /** 136413705f88SJack F Vogel * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input. 136513705f88SJack F Vogel * @hw: pointer to hardware structure 136613705f88SJack F Vogel * @eecd: EECD's current value 136713705f88SJack F Vogel **/ 136813705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 136913705f88SJack F Vogel { 13702969bf0eSJack F Vogel DEBUGFUNC("ixgbe_lower_eeprom_clk"); 13712969bf0eSJack F Vogel 137213705f88SJack F Vogel /* 137313705f88SJack F Vogel * Lower the clock input to the EEPROM (clearing the SK bit), then 137413705f88SJack F Vogel * delay 137513705f88SJack F Vogel */ 137613705f88SJack F Vogel *eec = *eec & ~IXGBE_EEC_SK; 137713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 137813705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 137913705f88SJack F Vogel usec_delay(1); 138013705f88SJack F Vogel } 138113705f88SJack F Vogel 138213705f88SJack F Vogel /** 138313705f88SJack F Vogel * ixgbe_release_eeprom - Release EEPROM, release semaphores 138413705f88SJack F Vogel * @hw: pointer to hardware structure 138513705f88SJack F Vogel **/ 138613705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw) 138713705f88SJack F Vogel { 138813705f88SJack F Vogel u32 eec; 138913705f88SJack F Vogel 13902969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_eeprom"); 13912969bf0eSJack F Vogel 139213705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 139313705f88SJack F Vogel 139413705f88SJack F Vogel eec |= IXGBE_EEC_CS; /* Pull CS high */ 139513705f88SJack F Vogel eec &= ~IXGBE_EEC_SK; /* Lower SCK */ 139613705f88SJack F Vogel 139713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 139813705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 139913705f88SJack F Vogel 140013705f88SJack F Vogel usec_delay(1); 140113705f88SJack F Vogel 140213705f88SJack F Vogel /* Stop requesting EEPROM access */ 140313705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 140413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 140513705f88SJack F Vogel 140613705f88SJack F Vogel ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 1407d8602bb9SJack F Vogel 1408d8602bb9SJack F Vogel /* Delay before attempt to obtain semaphore again to allow FW access */ 1409d8602bb9SJack F Vogel msec_delay(hw->eeprom.semaphore_delay); 141013705f88SJack F Vogel } 141113705f88SJack F Vogel 141213705f88SJack F Vogel /** 14132969bf0eSJack F Vogel * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum 141413705f88SJack F Vogel * @hw: pointer to hardware structure 141513705f88SJack F Vogel **/ 14162969bf0eSJack F Vogel u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) 141713705f88SJack F Vogel { 141813705f88SJack F Vogel u16 i; 141913705f88SJack F Vogel u16 j; 142013705f88SJack F Vogel u16 checksum = 0; 142113705f88SJack F Vogel u16 length = 0; 142213705f88SJack F Vogel u16 pointer = 0; 142313705f88SJack F Vogel u16 word = 0; 142413705f88SJack F Vogel 14252969bf0eSJack F Vogel DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic"); 14262969bf0eSJack F Vogel 142713705f88SJack F Vogel /* Include 0x0-0x3F in the checksum */ 142813705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 14299ca4041bSJack F Vogel if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) { 143013705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 143113705f88SJack F Vogel break; 143213705f88SJack F Vogel } 143313705f88SJack F Vogel checksum += word; 143413705f88SJack F Vogel } 143513705f88SJack F Vogel 143613705f88SJack F Vogel /* Include all data from pointers except for the fw pointer */ 143713705f88SJack F Vogel for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 14389ca4041bSJack F Vogel hw->eeprom.ops.read(hw, i, &pointer); 143913705f88SJack F Vogel 144013705f88SJack F Vogel /* Make sure the pointer seems valid */ 144113705f88SJack F Vogel if (pointer != 0xFFFF && pointer != 0) { 14429ca4041bSJack F Vogel hw->eeprom.ops.read(hw, pointer, &length); 144313705f88SJack F Vogel 144413705f88SJack F Vogel if (length != 0xFFFF && length != 0) { 144513705f88SJack F Vogel for (j = pointer+1; j <= pointer+length; j++) { 14469ca4041bSJack F Vogel hw->eeprom.ops.read(hw, j, &word); 144713705f88SJack F Vogel checksum += word; 144813705f88SJack F Vogel } 144913705f88SJack F Vogel } 145013705f88SJack F Vogel } 145113705f88SJack F Vogel } 145213705f88SJack F Vogel 145313705f88SJack F Vogel checksum = (u16)IXGBE_EEPROM_SUM - checksum; 145413705f88SJack F Vogel 145513705f88SJack F Vogel return checksum; 145613705f88SJack F Vogel } 145713705f88SJack F Vogel 145813705f88SJack F Vogel /** 145913705f88SJack F Vogel * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum 146013705f88SJack F Vogel * @hw: pointer to hardware structure 146113705f88SJack F Vogel * @checksum_val: calculated checksum 146213705f88SJack F Vogel * 146313705f88SJack F Vogel * Performs checksum calculation and validates the EEPROM checksum. If the 146413705f88SJack F Vogel * caller does not need checksum_val, the value can be NULL. 146513705f88SJack F Vogel **/ 146613705f88SJack F Vogel s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, 146713705f88SJack F Vogel u16 *checksum_val) 146813705f88SJack F Vogel { 146913705f88SJack F Vogel s32 status; 147013705f88SJack F Vogel u16 checksum; 147113705f88SJack F Vogel u16 read_checksum = 0; 147213705f88SJack F Vogel 14732969bf0eSJack F Vogel DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic"); 14742969bf0eSJack F Vogel 147513705f88SJack F Vogel /* 147613705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 147713705f88SJack F Vogel * not continue or we could be in for a very long wait while every 147813705f88SJack F Vogel * EEPROM read fails 147913705f88SJack F Vogel */ 14809ca4041bSJack F Vogel status = hw->eeprom.ops.read(hw, 0, &checksum); 148113705f88SJack F Vogel 148213705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 14832969bf0eSJack F Vogel checksum = hw->eeprom.ops.calc_checksum(hw); 148413705f88SJack F Vogel 14859ca4041bSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); 148613705f88SJack F Vogel 148713705f88SJack F Vogel /* 148813705f88SJack F Vogel * Verify read checksum from EEPROM is the same as 148913705f88SJack F Vogel * calculated checksum 149013705f88SJack F Vogel */ 14919ca4041bSJack F Vogel if (read_checksum != checksum) 149213705f88SJack F Vogel status = IXGBE_ERR_EEPROM_CHECKSUM; 149313705f88SJack F Vogel 149413705f88SJack F Vogel /* If the user cares, return the calculated checksum */ 14959ca4041bSJack F Vogel if (checksum_val) 149613705f88SJack F Vogel *checksum_val = checksum; 149713705f88SJack F Vogel } else { 149813705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 149913705f88SJack F Vogel } 150013705f88SJack F Vogel 150113705f88SJack F Vogel return status; 150213705f88SJack F Vogel } 150313705f88SJack F Vogel 150413705f88SJack F Vogel /** 15059ca4041bSJack F Vogel * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum 150613705f88SJack F Vogel * @hw: pointer to hardware structure 150713705f88SJack F Vogel **/ 150813705f88SJack F Vogel s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) 150913705f88SJack F Vogel { 151013705f88SJack F Vogel s32 status; 151113705f88SJack F Vogel u16 checksum; 151213705f88SJack F Vogel 15132969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_eeprom_checksum_generic"); 15142969bf0eSJack F Vogel 151513705f88SJack F Vogel /* 151613705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 151713705f88SJack F Vogel * not continue or we could be in for a very long wait while every 151813705f88SJack F Vogel * EEPROM read fails 151913705f88SJack F Vogel */ 15209ca4041bSJack F Vogel status = hw->eeprom.ops.read(hw, 0, &checksum); 152113705f88SJack F Vogel 152213705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 15232969bf0eSJack F Vogel checksum = hw->eeprom.ops.calc_checksum(hw); 15249ca4041bSJack F Vogel status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, 152513705f88SJack F Vogel checksum); 152613705f88SJack F Vogel } else { 152713705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 152813705f88SJack F Vogel } 152913705f88SJack F Vogel 153013705f88SJack F Vogel return status; 153113705f88SJack F Vogel } 153213705f88SJack F Vogel 153313705f88SJack F Vogel /** 153413705f88SJack F Vogel * ixgbe_validate_mac_addr - Validate MAC address 153513705f88SJack F Vogel * @mac_addr: pointer to MAC address. 153613705f88SJack F Vogel * 153713705f88SJack F Vogel * Tests a MAC address to ensure it is a valid Individual Address 153813705f88SJack F Vogel **/ 153913705f88SJack F Vogel s32 ixgbe_validate_mac_addr(u8 *mac_addr) 154013705f88SJack F Vogel { 154113705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 154213705f88SJack F Vogel 15432969bf0eSJack F Vogel DEBUGFUNC("ixgbe_validate_mac_addr"); 15442969bf0eSJack F Vogel 154513705f88SJack F Vogel /* Make sure it is not a multicast address */ 154613705f88SJack F Vogel if (IXGBE_IS_MULTICAST(mac_addr)) { 154713705f88SJack F Vogel DEBUGOUT("MAC address is multicast\n"); 154813705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 154913705f88SJack F Vogel /* Not a broadcast address */ 155013705f88SJack F Vogel } else if (IXGBE_IS_BROADCAST(mac_addr)) { 155113705f88SJack F Vogel DEBUGOUT("MAC address is broadcast\n"); 155213705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 155313705f88SJack F Vogel /* Reject the zero address */ 155413705f88SJack F Vogel } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && 155513705f88SJack F Vogel mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { 155613705f88SJack F Vogel DEBUGOUT("MAC address is all zeros\n"); 155713705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 155813705f88SJack F Vogel } 155913705f88SJack F Vogel return status; 156013705f88SJack F Vogel } 156113705f88SJack F Vogel 156213705f88SJack F Vogel /** 15639ca4041bSJack F Vogel * ixgbe_set_rar_generic - Set Rx address register 156413705f88SJack F Vogel * @hw: pointer to hardware structure 156513705f88SJack F Vogel * @index: Receive address register to write 15669ca4041bSJack F Vogel * @addr: Address to put into receive address register 15679ca4041bSJack F Vogel * @vmdq: VMDq "set" or "pool" index 156813705f88SJack F Vogel * @enable_addr: set flag that address is active 156913705f88SJack F Vogel * 157013705f88SJack F Vogel * Puts an ethernet address into a receive address register. 157113705f88SJack F Vogel **/ 15729ca4041bSJack F Vogel s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, 157313705f88SJack F Vogel u32 enable_addr) 157413705f88SJack F Vogel { 157513705f88SJack F Vogel u32 rar_low, rar_high; 15769ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 157713705f88SJack F Vogel 15782969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_rar_generic"); 15792969bf0eSJack F Vogel 1580*1a4e3449SJack F Vogel /* Make sure we are using a valid rar index range */ 1581*1a4e3449SJack F Vogel if (index >= rar_entries) { 1582*1a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", index); 1583*1a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 1584*1a4e3449SJack F Vogel } 1585*1a4e3449SJack F Vogel 15869ca4041bSJack F Vogel /* setup VMDq pool selection before this RAR gets enabled */ 15879ca4041bSJack F Vogel hw->mac.ops.set_vmdq(hw, index, vmdq); 15889ca4041bSJack F Vogel 158913705f88SJack F Vogel /* 15909ca4041bSJack F Vogel * HW expects these in little endian so we reverse the byte 15919ca4041bSJack F Vogel * order from network order (big endian) to little endian 159213705f88SJack F Vogel */ 159313705f88SJack F Vogel rar_low = ((u32)addr[0] | 159413705f88SJack F Vogel ((u32)addr[1] << 8) | 159513705f88SJack F Vogel ((u32)addr[2] << 16) | 159613705f88SJack F Vogel ((u32)addr[3] << 24)); 15979ca4041bSJack F Vogel /* 15989ca4041bSJack F Vogel * Some parts put the VMDq setting in the extra RAH bits, 15999ca4041bSJack F Vogel * so save everything except the lower 16 bits that hold part 16009ca4041bSJack F Vogel * of the address and the address valid bit. 16019ca4041bSJack F Vogel */ 16029ca4041bSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 16039ca4041bSJack F Vogel rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); 16049ca4041bSJack F Vogel rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); 160513705f88SJack F Vogel 160613705f88SJack F Vogel if (enable_addr != 0) 160713705f88SJack F Vogel rar_high |= IXGBE_RAH_AV; 160813705f88SJack F Vogel 160913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); 161013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 161113705f88SJack F Vogel 161213705f88SJack F Vogel return IXGBE_SUCCESS; 161313705f88SJack F Vogel } 161413705f88SJack F Vogel 161513705f88SJack F Vogel /** 16165b7f4cedSJack F Vogel * ixgbe_clear_rar_generic - Remove Rx address register 16175b7f4cedSJack F Vogel * @hw: pointer to hardware structure 16185b7f4cedSJack F Vogel * @index: Receive address register to write 16195b7f4cedSJack F Vogel * 16205b7f4cedSJack F Vogel * Clears an ethernet address from a receive address register. 16215b7f4cedSJack F Vogel **/ 16225b7f4cedSJack F Vogel s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) 16235b7f4cedSJack F Vogel { 16245b7f4cedSJack F Vogel u32 rar_high; 16255b7f4cedSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 16265b7f4cedSJack F Vogel 16272969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_rar_generic"); 16282969bf0eSJack F Vogel 16295b7f4cedSJack F Vogel /* Make sure we are using a valid rar index range */ 1630*1a4e3449SJack F Vogel if (index >= rar_entries) { 1631*1a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", index); 1632*1a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 1633*1a4e3449SJack F Vogel } 1634*1a4e3449SJack F Vogel 16355b7f4cedSJack F Vogel /* 16365b7f4cedSJack F Vogel * Some parts put the VMDq setting in the extra RAH bits, 16375b7f4cedSJack F Vogel * so save everything except the lower 16 bits that hold part 16385b7f4cedSJack F Vogel * of the address and the address valid bit. 16395b7f4cedSJack F Vogel */ 16405b7f4cedSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 16415b7f4cedSJack F Vogel rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); 16425b7f4cedSJack F Vogel 16435b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); 16445b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 16455b7f4cedSJack F Vogel 16465b7f4cedSJack F Vogel /* clear VMDq pool/queue selection for this RAR */ 16475b7f4cedSJack F Vogel hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL); 16485b7f4cedSJack F Vogel 16495b7f4cedSJack F Vogel return IXGBE_SUCCESS; 16505b7f4cedSJack F Vogel } 16515b7f4cedSJack F Vogel 16525b7f4cedSJack F Vogel /** 165313705f88SJack F Vogel * ixgbe_init_rx_addrs_generic - Initializes receive address filters. 165413705f88SJack F Vogel * @hw: pointer to hardware structure 165513705f88SJack F Vogel * 165613705f88SJack F Vogel * Places the MAC address in receive address register 0 and clears the rest 16579ca4041bSJack F Vogel * of the receive address registers. Clears the multicast table. Assumes 165813705f88SJack F Vogel * the receiver is in reset when the routine is called. 165913705f88SJack F Vogel **/ 166013705f88SJack F Vogel s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) 166113705f88SJack F Vogel { 166213705f88SJack F Vogel u32 i; 16639ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 166413705f88SJack F Vogel 16652969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_rx_addrs_generic"); 16662969bf0eSJack F Vogel 166713705f88SJack F Vogel /* 166813705f88SJack F Vogel * If the current mac address is valid, assume it is a software override 166913705f88SJack F Vogel * to the permanent address. 167013705f88SJack F Vogel * Otherwise, use the permanent address from the eeprom. 167113705f88SJack F Vogel */ 167213705f88SJack F Vogel if (ixgbe_validate_mac_addr(hw->mac.addr) == 167313705f88SJack F Vogel IXGBE_ERR_INVALID_MAC_ADDR) { 167413705f88SJack F Vogel /* Get the MAC address from the RAR0 for later reference */ 16759ca4041bSJack F Vogel hw->mac.ops.get_mac_addr(hw, hw->mac.addr); 167613705f88SJack F Vogel 167713705f88SJack F Vogel DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ", 167813705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 167913705f88SJack F Vogel hw->mac.addr[2]); 168013705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 168113705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 168213705f88SJack F Vogel } else { 168313705f88SJack F Vogel /* Setup the receive address. */ 168413705f88SJack F Vogel DEBUGOUT("Overriding MAC Address in RAR[0]\n"); 168513705f88SJack F Vogel DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ", 168613705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 168713705f88SJack F Vogel hw->mac.addr[2]); 168813705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 168913705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 169013705f88SJack F Vogel 16919ca4041bSJack F Vogel hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); 169213705f88SJack F Vogel } 16939ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc = 0; 169413705f88SJack F Vogel 169513705f88SJack F Vogel hw->addr_ctrl.rar_used_count = 1; 169613705f88SJack F Vogel 169713705f88SJack F Vogel /* Zero out the other receive addresses. */ 16989ca4041bSJack F Vogel DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1); 169913705f88SJack F Vogel for (i = 1; i < rar_entries; i++) { 170013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); 170113705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); 170213705f88SJack F Vogel } 170313705f88SJack F Vogel 170413705f88SJack F Vogel /* Clear the MTA */ 170513705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 170613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 170713705f88SJack F Vogel 170813705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 17099ca4041bSJack F Vogel for (i = 0; i < hw->mac.mcft_size; i++) 171013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); 171113705f88SJack F Vogel 17125b7f4cedSJack F Vogel ixgbe_init_uta_tables(hw); 17135b7f4cedSJack F Vogel 171413705f88SJack F Vogel return IXGBE_SUCCESS; 171513705f88SJack F Vogel } 171613705f88SJack F Vogel 171713705f88SJack F Vogel /** 17189ca4041bSJack F Vogel * ixgbe_add_uc_addr - Adds a secondary unicast address. 17199ca4041bSJack F Vogel * @hw: pointer to hardware structure 17209ca4041bSJack F Vogel * @addr: new address 17219ca4041bSJack F Vogel * 17229ca4041bSJack F Vogel * Adds it to unused receive address register or goes into promiscuous mode. 17239ca4041bSJack F Vogel **/ 17249ca4041bSJack F Vogel void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) 17259ca4041bSJack F Vogel { 17269ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 17279ca4041bSJack F Vogel u32 rar; 17289ca4041bSJack F Vogel 17292969bf0eSJack F Vogel DEBUGFUNC("ixgbe_add_uc_addr"); 17302969bf0eSJack F Vogel 17319ca4041bSJack F Vogel DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", 17329ca4041bSJack F Vogel addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 17339ca4041bSJack F Vogel 17349ca4041bSJack F Vogel /* 17359ca4041bSJack F Vogel * Place this address in the RAR if there is room, 17369ca4041bSJack F Vogel * else put the controller into promiscuous mode 17379ca4041bSJack F Vogel */ 17389ca4041bSJack F Vogel if (hw->addr_ctrl.rar_used_count < rar_entries) { 17390ac6dfecSJack F Vogel rar = hw->addr_ctrl.rar_used_count; 17409ca4041bSJack F Vogel hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 17419ca4041bSJack F Vogel DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar); 17429ca4041bSJack F Vogel hw->addr_ctrl.rar_used_count++; 17439ca4041bSJack F Vogel } else { 17449ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc++; 17459ca4041bSJack F Vogel } 17469ca4041bSJack F Vogel 17479ca4041bSJack F Vogel DEBUGOUT("ixgbe_add_uc_addr Complete\n"); 17489ca4041bSJack F Vogel } 17499ca4041bSJack F Vogel 17509ca4041bSJack F Vogel /** 17519ca4041bSJack F Vogel * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses 17529ca4041bSJack F Vogel * @hw: pointer to hardware structure 17539ca4041bSJack F Vogel * @addr_list: the list of new addresses 17549ca4041bSJack F Vogel * @addr_count: number of addresses 17559ca4041bSJack F Vogel * @next: iterator function to walk the address list 17569ca4041bSJack F Vogel * 17579ca4041bSJack F Vogel * The given list replaces any existing list. Clears the secondary addrs from 17589ca4041bSJack F Vogel * receive address registers. Uses unused receive address registers for the 17599ca4041bSJack F Vogel * first secondary addresses, and falls back to promiscuous mode as needed. 17609ca4041bSJack F Vogel * 17619ca4041bSJack F Vogel * Drivers using secondary unicast addresses must set user_set_promisc when 17629ca4041bSJack F Vogel * manually putting the device into promiscuous mode. 17639ca4041bSJack F Vogel **/ 17649ca4041bSJack F Vogel s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, 17659ca4041bSJack F Vogel u32 addr_count, ixgbe_mc_addr_itr next) 17669ca4041bSJack F Vogel { 17679ca4041bSJack F Vogel u8 *addr; 17689ca4041bSJack F Vogel u32 i; 17699ca4041bSJack F Vogel u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; 17709ca4041bSJack F Vogel u32 uc_addr_in_use; 17719ca4041bSJack F Vogel u32 fctrl; 17729ca4041bSJack F Vogel u32 vmdq; 17739ca4041bSJack F Vogel 17742969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_uc_addr_list_generic"); 17752969bf0eSJack F Vogel 17769ca4041bSJack F Vogel /* 17779ca4041bSJack F Vogel * Clear accounting of old secondary address list, 17789ca4041bSJack F Vogel * don't count RAR[0] 17799ca4041bSJack F Vogel */ 17800ac6dfecSJack F Vogel uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1; 17819ca4041bSJack F Vogel hw->addr_ctrl.rar_used_count -= uc_addr_in_use; 17829ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc = 0; 17839ca4041bSJack F Vogel 17849ca4041bSJack F Vogel /* Zero out the other receive addresses */ 17852969bf0eSJack F Vogel DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use+1); 17862969bf0eSJack F Vogel for (i = 0; i < uc_addr_in_use; i++) { 17872969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0); 17882969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0); 17899ca4041bSJack F Vogel } 17909ca4041bSJack F Vogel 17919ca4041bSJack F Vogel /* Add the new addresses */ 17929ca4041bSJack F Vogel for (i = 0; i < addr_count; i++) { 17939ca4041bSJack F Vogel DEBUGOUT(" Adding the secondary addresses:\n"); 17949ca4041bSJack F Vogel addr = next(hw, &addr_list, &vmdq); 17959ca4041bSJack F Vogel ixgbe_add_uc_addr(hw, addr, vmdq); 17969ca4041bSJack F Vogel } 17979ca4041bSJack F Vogel 17989ca4041bSJack F Vogel if (hw->addr_ctrl.overflow_promisc) { 17999ca4041bSJack F Vogel /* enable promisc if not already in overflow or set by user */ 18009ca4041bSJack F Vogel if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { 18019ca4041bSJack F Vogel DEBUGOUT(" Entering address overflow promisc mode\n"); 18029ca4041bSJack F Vogel fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 18039ca4041bSJack F Vogel fctrl |= IXGBE_FCTRL_UPE; 18049ca4041bSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 18059ca4041bSJack F Vogel } 18069ca4041bSJack F Vogel } else { 18079ca4041bSJack F Vogel /* only disable if set by overflow, not by user */ 18089ca4041bSJack F Vogel if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { 18099ca4041bSJack F Vogel DEBUGOUT(" Leaving address overflow promisc mode\n"); 18109ca4041bSJack F Vogel fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 18119ca4041bSJack F Vogel fctrl &= ~IXGBE_FCTRL_UPE; 18129ca4041bSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 18139ca4041bSJack F Vogel } 18149ca4041bSJack F Vogel } 18159ca4041bSJack F Vogel 18169ca4041bSJack F Vogel DEBUGOUT("ixgbe_update_uc_addr_list_generic Complete\n"); 18179ca4041bSJack F Vogel return IXGBE_SUCCESS; 18189ca4041bSJack F Vogel } 18199ca4041bSJack F Vogel 18209ca4041bSJack F Vogel /** 182113705f88SJack F Vogel * ixgbe_mta_vector - Determines bit-vector in multicast table to set 182213705f88SJack F Vogel * @hw: pointer to hardware structure 182313705f88SJack F Vogel * @mc_addr: the multicast address 182413705f88SJack F Vogel * 182513705f88SJack F Vogel * Extracts the 12 bits, from a multicast address, to determine which 182613705f88SJack F Vogel * bit-vector to set in the multicast table. The hardware uses 12 bits, from 182713705f88SJack F Vogel * incoming rx multicast addresses, to determine the bit-vector to check in 182813705f88SJack F Vogel * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set 18299ca4041bSJack F Vogel * by the MO field of the MCSTCTRL. The MO field is set during initialization 183013705f88SJack F Vogel * to mc_filter_type. 183113705f88SJack F Vogel **/ 183213705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) 183313705f88SJack F Vogel { 183413705f88SJack F Vogel u32 vector = 0; 183513705f88SJack F Vogel 18362969bf0eSJack F Vogel DEBUGFUNC("ixgbe_mta_vector"); 18372969bf0eSJack F Vogel 183813705f88SJack F Vogel switch (hw->mac.mc_filter_type) { 183913705f88SJack F Vogel case 0: /* use bits [47:36] of the address */ 184013705f88SJack F Vogel vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); 184113705f88SJack F Vogel break; 184213705f88SJack F Vogel case 1: /* use bits [46:35] of the address */ 184313705f88SJack F Vogel vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); 184413705f88SJack F Vogel break; 184513705f88SJack F Vogel case 2: /* use bits [45:34] of the address */ 184613705f88SJack F Vogel vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); 184713705f88SJack F Vogel break; 184813705f88SJack F Vogel case 3: /* use bits [43:32] of the address */ 184913705f88SJack F Vogel vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); 185013705f88SJack F Vogel break; 185113705f88SJack F Vogel default: /* Invalid mc_filter_type */ 185213705f88SJack F Vogel DEBUGOUT("MC filter type param set incorrectly\n"); 185313705f88SJack F Vogel ASSERT(0); 185413705f88SJack F Vogel break; 185513705f88SJack F Vogel } 185613705f88SJack F Vogel 185713705f88SJack F Vogel /* vector can only be 12-bits or boundary will be exceeded */ 185813705f88SJack F Vogel vector &= 0xFFF; 185913705f88SJack F Vogel return vector; 186013705f88SJack F Vogel } 186113705f88SJack F Vogel 186213705f88SJack F Vogel /** 186313705f88SJack F Vogel * ixgbe_set_mta - Set bit-vector in multicast table 186413705f88SJack F Vogel * @hw: pointer to hardware structure 186513705f88SJack F Vogel * @hash_value: Multicast address hash value 186613705f88SJack F Vogel * 186713705f88SJack F Vogel * Sets the bit-vector in the multicast table. 186813705f88SJack F Vogel **/ 186913705f88SJack F Vogel void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) 187013705f88SJack F Vogel { 187113705f88SJack F Vogel u32 vector; 187213705f88SJack F Vogel u32 vector_bit; 187313705f88SJack F Vogel u32 vector_reg; 187413705f88SJack F Vogel 18752969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_mta"); 18762969bf0eSJack F Vogel 187713705f88SJack F Vogel hw->addr_ctrl.mta_in_use++; 187813705f88SJack F Vogel 187913705f88SJack F Vogel vector = ixgbe_mta_vector(hw, mc_addr); 188013705f88SJack F Vogel DEBUGOUT1(" bit-vector = 0x%03X\n", vector); 188113705f88SJack F Vogel 188213705f88SJack F Vogel /* 188313705f88SJack F Vogel * The MTA is a register array of 128 32-bit registers. It is treated 188413705f88SJack F Vogel * like an array of 4096 bits. We want to set bit 188513705f88SJack F Vogel * BitArray[vector_value]. So we figure out what register the bit is 188613705f88SJack F Vogel * in, read it, OR in the new bit, then write back the new value. The 188713705f88SJack F Vogel * register is determined by the upper 7 bits of the vector value and 188813705f88SJack F Vogel * the bit within that register are determined by the lower 5 bits of 188913705f88SJack F Vogel * the value. 189013705f88SJack F Vogel */ 189113705f88SJack F Vogel vector_reg = (vector >> 5) & 0x7F; 189213705f88SJack F Vogel vector_bit = vector & 0x1F; 1893*1a4e3449SJack F Vogel hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); 189413705f88SJack F Vogel } 189513705f88SJack F Vogel 189613705f88SJack F Vogel /** 189713705f88SJack F Vogel * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses 189813705f88SJack F Vogel * @hw: pointer to hardware structure 189913705f88SJack F Vogel * @mc_addr_list: the list of new multicast addresses 190013705f88SJack F Vogel * @mc_addr_count: number of addresses 19019ca4041bSJack F Vogel * @next: iterator function to walk the multicast address list 190213705f88SJack F Vogel * 190313705f88SJack F Vogel * The given list replaces any existing list. Clears the MC addrs from receive 19049ca4041bSJack F Vogel * address registers and the multicast table. Uses unused receive address 190513705f88SJack F Vogel * registers for the first multicast addresses, and hashes the rest into the 190613705f88SJack F Vogel * multicast table. 190713705f88SJack F Vogel **/ 190813705f88SJack F Vogel s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, 19099ca4041bSJack F Vogel u32 mc_addr_count, ixgbe_mc_addr_itr next) 191013705f88SJack F Vogel { 191113705f88SJack F Vogel u32 i; 19129ca4041bSJack F Vogel u32 vmdq; 191313705f88SJack F Vogel 19142969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_mc_addr_list_generic"); 19152969bf0eSJack F Vogel 191613705f88SJack F Vogel /* 191713705f88SJack F Vogel * Set the new number of MC addresses that we are being requested to 191813705f88SJack F Vogel * use. 191913705f88SJack F Vogel */ 192013705f88SJack F Vogel hw->addr_ctrl.num_mc_addrs = mc_addr_count; 192113705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 192213705f88SJack F Vogel 1923*1a4e3449SJack F Vogel /* Clear mta_shadow */ 192413705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 1925*1a4e3449SJack F Vogel memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); 192613705f88SJack F Vogel 1927*1a4e3449SJack F Vogel /* Update mta_shadow */ 192813705f88SJack F Vogel for (i = 0; i < mc_addr_count; i++) { 192913705f88SJack F Vogel DEBUGOUT(" Adding the multicast addresses:\n"); 19300ac6dfecSJack F Vogel ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); 193113705f88SJack F Vogel } 193213705f88SJack F Vogel 193313705f88SJack F Vogel /* Enable mta */ 1934*1a4e3449SJack F Vogel for (i = 0; i < hw->mac.mcft_size; i++) 1935*1a4e3449SJack F Vogel IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i, 1936*1a4e3449SJack F Vogel hw->mac.mta_shadow[i]); 1937*1a4e3449SJack F Vogel 193813705f88SJack F Vogel if (hw->addr_ctrl.mta_in_use > 0) 193913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, 194013705f88SJack F Vogel IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); 194113705f88SJack F Vogel 194213705f88SJack F Vogel DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n"); 194313705f88SJack F Vogel return IXGBE_SUCCESS; 194413705f88SJack F Vogel } 194513705f88SJack F Vogel 194613705f88SJack F Vogel /** 194713705f88SJack F Vogel * ixgbe_enable_mc_generic - Enable multicast address in RAR 194813705f88SJack F Vogel * @hw: pointer to hardware structure 194913705f88SJack F Vogel * 195013705f88SJack F Vogel * Enables multicast address in RAR and the use of the multicast hash table. 195113705f88SJack F Vogel **/ 195213705f88SJack F Vogel s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) 195313705f88SJack F Vogel { 195413705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 195513705f88SJack F Vogel 19562969bf0eSJack F Vogel DEBUGFUNC("ixgbe_enable_mc_generic"); 19572969bf0eSJack F Vogel 195813705f88SJack F Vogel if (a->mta_in_use > 0) 195913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | 196013705f88SJack F Vogel hw->mac.mc_filter_type); 196113705f88SJack F Vogel 196213705f88SJack F Vogel return IXGBE_SUCCESS; 196313705f88SJack F Vogel } 196413705f88SJack F Vogel 196513705f88SJack F Vogel /** 19669ca4041bSJack F Vogel * ixgbe_disable_mc_generic - Disable multicast address in RAR 196713705f88SJack F Vogel * @hw: pointer to hardware structure 196813705f88SJack F Vogel * 196913705f88SJack F Vogel * Disables multicast address in RAR and the use of the multicast hash table. 197013705f88SJack F Vogel **/ 197113705f88SJack F Vogel s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) 197213705f88SJack F Vogel { 197313705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 197413705f88SJack F Vogel 19752969bf0eSJack F Vogel DEBUGFUNC("ixgbe_disable_mc_generic"); 19762969bf0eSJack F Vogel 197713705f88SJack F Vogel if (a->mta_in_use > 0) 197813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 197913705f88SJack F Vogel 198013705f88SJack F Vogel return IXGBE_SUCCESS; 198113705f88SJack F Vogel } 198213705f88SJack F Vogel 19831b6e0dbaSJack F Vogel /** 19840ac6dfecSJack F Vogel * ixgbe_fc_enable_generic - Enable flow control 19851b6e0dbaSJack F Vogel * @hw: pointer to hardware structure 19860ac6dfecSJack F Vogel * @packetbuf_num: packet buffer number (0-7) 19871b6e0dbaSJack F Vogel * 19880ac6dfecSJack F Vogel * Enable flow control according to the current settings. 19891b6e0dbaSJack F Vogel **/ 19900ac6dfecSJack F Vogel s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) 19911b6e0dbaSJack F Vogel { 19921b6e0dbaSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 19930ac6dfecSJack F Vogel u32 mflcn_reg, fccfg_reg; 19940ac6dfecSJack F Vogel u32 reg; 1995d8602bb9SJack F Vogel u32 rx_pba_size; 1996*1a4e3449SJack F Vogel u32 fcrtl, fcrth; 19971b6e0dbaSJack F Vogel 19980ac6dfecSJack F Vogel DEBUGFUNC("ixgbe_fc_enable_generic"); 19991b6e0dbaSJack F Vogel 20000ac6dfecSJack F Vogel /* Negotiate the fc mode to use */ 20010ac6dfecSJack F Vogel ret_val = ixgbe_fc_autoneg(hw); 2002*1a4e3449SJack F Vogel if (ret_val == IXGBE_ERR_FLOW_CONTROL) 20030ac6dfecSJack F Vogel goto out; 20040ac6dfecSJack F Vogel 20050ac6dfecSJack F Vogel /* Disable any previous flow control settings */ 20060ac6dfecSJack F Vogel mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); 20070ac6dfecSJack F Vogel mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE); 20080ac6dfecSJack F Vogel 20090ac6dfecSJack F Vogel fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); 20100ac6dfecSJack F Vogel fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); 20111b6e0dbaSJack F Vogel 20121b6e0dbaSJack F Vogel /* 20131b6e0dbaSJack F Vogel * The possible values of fc.current_mode are: 20141b6e0dbaSJack F Vogel * 0: Flow control is completely disabled 20151b6e0dbaSJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames, 20161b6e0dbaSJack F Vogel * but not send pause frames). 20171b6e0dbaSJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but 20181b6e0dbaSJack F Vogel * we do not support receiving pause frames). 20191b6e0dbaSJack F Vogel * 3: Both Rx and Tx flow control (symmetric) are enabled. 20201b6e0dbaSJack F Vogel * other: Invalid. 20211b6e0dbaSJack F Vogel */ 20221b6e0dbaSJack F Vogel switch (hw->fc.current_mode) { 20231b6e0dbaSJack F Vogel case ixgbe_fc_none: 2024*1a4e3449SJack F Vogel /* 2025*1a4e3449SJack F Vogel * Flow control is disabled by software override or autoneg. 20260ac6dfecSJack F Vogel * The code below will actually disable it in the HW. 20270ac6dfecSJack F Vogel */ 20281b6e0dbaSJack F Vogel break; 20291b6e0dbaSJack F Vogel case ixgbe_fc_rx_pause: 20301b6e0dbaSJack F Vogel /* 20311b6e0dbaSJack F Vogel * Rx Flow control is enabled and Tx Flow control is 20321b6e0dbaSJack F Vogel * disabled by software override. Since there really 20331b6e0dbaSJack F Vogel * isn't a way to advertise that we are capable of RX 20341b6e0dbaSJack F Vogel * Pause ONLY, we will advertise that we support both 20351b6e0dbaSJack F Vogel * symmetric and asymmetric Rx PAUSE. Later, we will 20361b6e0dbaSJack F Vogel * disable the adapter's ability to send PAUSE frames. 20371b6e0dbaSJack F Vogel */ 20380ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_RFCE; 20391b6e0dbaSJack F Vogel break; 20401b6e0dbaSJack F Vogel case ixgbe_fc_tx_pause: 20411b6e0dbaSJack F Vogel /* 20421b6e0dbaSJack F Vogel * Tx Flow control is enabled, and Rx Flow control is 20431b6e0dbaSJack F Vogel * disabled by software override. 20441b6e0dbaSJack F Vogel */ 20450ac6dfecSJack F Vogel fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; 20461b6e0dbaSJack F Vogel break; 20471b6e0dbaSJack F Vogel case ixgbe_fc_full: 20481b6e0dbaSJack F Vogel /* Flow control (both Rx and Tx) is enabled by SW override. */ 20490ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_RFCE; 20500ac6dfecSJack F Vogel fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; 20511b6e0dbaSJack F Vogel break; 20521b6e0dbaSJack F Vogel default: 20531b6e0dbaSJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 20542969bf0eSJack F Vogel ret_val = IXGBE_ERR_CONFIG; 20551b6e0dbaSJack F Vogel goto out; 20561b6e0dbaSJack F Vogel break; 20571b6e0dbaSJack F Vogel } 20581b6e0dbaSJack F Vogel 20590ac6dfecSJack F Vogel /* Set 802.3x based flow control settings. */ 20600ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_DPF; 20610ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); 20620ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); 20631b6e0dbaSJack F Vogel 2064d8602bb9SJack F Vogel rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); 2065*1a4e3449SJack F Vogel rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; 2066d8602bb9SJack F Vogel 2067*1a4e3449SJack F Vogel fcrth = (rx_pba_size - hw->fc.high_water) << 10; 2068*1a4e3449SJack F Vogel fcrtl = (rx_pba_size - hw->fc.low_water) << 10; 2069d8602bb9SJack F Vogel 20700ac6dfecSJack F Vogel if (hw->fc.current_mode & ixgbe_fc_tx_pause) { 2071*1a4e3449SJack F Vogel fcrth |= IXGBE_FCRTH_FCEN; 2072*1a4e3449SJack F Vogel if (hw->fc.send_xon) 2073*1a4e3449SJack F Vogel fcrtl |= IXGBE_FCRTL_XONE; 20741b6e0dbaSJack F Vogel } 20751b6e0dbaSJack F Vogel 2076*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth); 2077*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl); 20780ac6dfecSJack F Vogel 20790ac6dfecSJack F Vogel /* Configure pause time (2 TCs per register) */ 2080d8602bb9SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); 20810ac6dfecSJack F Vogel if ((packetbuf_num & 1) == 0) 20820ac6dfecSJack F Vogel reg = (reg & 0xFFFF0000) | hw->fc.pause_time; 20830ac6dfecSJack F Vogel else 20840ac6dfecSJack F Vogel reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16); 20850ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg); 20860ac6dfecSJack F Vogel 20870ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); 20880ac6dfecSJack F Vogel 20890ac6dfecSJack F Vogel out: 20900ac6dfecSJack F Vogel return ret_val; 20910ac6dfecSJack F Vogel } 20920ac6dfecSJack F Vogel 20930ac6dfecSJack F Vogel /** 20940ac6dfecSJack F Vogel * ixgbe_fc_autoneg - Configure flow control 20950ac6dfecSJack F Vogel * @hw: pointer to hardware structure 20960ac6dfecSJack F Vogel * 20970ac6dfecSJack F Vogel * Compares our advertised flow control capabilities to those advertised by 20980ac6dfecSJack F Vogel * our link partner, and determines the proper flow control mode to use. 20990ac6dfecSJack F Vogel **/ 21000ac6dfecSJack F Vogel s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) 21010ac6dfecSJack F Vogel { 2102*1a4e3449SJack F Vogel s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 21030ac6dfecSJack F Vogel ixgbe_link_speed speed; 21040ac6dfecSJack F Vogel bool link_up; 21050ac6dfecSJack F Vogel 21060ac6dfecSJack F Vogel DEBUGFUNC("ixgbe_fc_autoneg"); 21070ac6dfecSJack F Vogel 2108*1a4e3449SJack F Vogel if (hw->fc.disable_fc_autoneg) 2109*1a4e3449SJack F Vogel goto out; 2110*1a4e3449SJack F Vogel 21110ac6dfecSJack F Vogel /* 21120ac6dfecSJack F Vogel * AN should have completed when the cable was plugged in. 21130ac6dfecSJack F Vogel * Look for reasons to bail out. Bail out if: 21140ac6dfecSJack F Vogel * - FC autoneg is disabled, or if 21152969bf0eSJack F Vogel * - link is not up. 21160ac6dfecSJack F Vogel * 21172969bf0eSJack F Vogel * Since we're being called from an LSC, link is already known to be up. 21180ac6dfecSJack F Vogel * So use link_up_wait_to_complete=FALSE. 21190ac6dfecSJack F Vogel */ 21200ac6dfecSJack F Vogel hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 2121*1a4e3449SJack F Vogel if (!link_up) { 2122*1a4e3449SJack F Vogel ret_val = IXGBE_ERR_FLOW_CONTROL; 21232969bf0eSJack F Vogel goto out; 21242969bf0eSJack F Vogel } 21252969bf0eSJack F Vogel 2126*1a4e3449SJack F Vogel switch (hw->phy.media_type) { 2127*1a4e3449SJack F Vogel /* Autoneg flow control on fiber adapters */ 2128*1a4e3449SJack F Vogel case ixgbe_media_type_fiber: 2129*1a4e3449SJack F Vogel if (speed == IXGBE_LINK_SPEED_1GB_FULL) 2130*1a4e3449SJack F Vogel ret_val = ixgbe_fc_autoneg_fiber(hw); 2131*1a4e3449SJack F Vogel break; 2132*1a4e3449SJack F Vogel 2133*1a4e3449SJack F Vogel /* Autoneg flow control on backplane adapters */ 2134*1a4e3449SJack F Vogel case ixgbe_media_type_backplane: 2135*1a4e3449SJack F Vogel ret_val = ixgbe_fc_autoneg_backplane(hw); 2136*1a4e3449SJack F Vogel break; 2137*1a4e3449SJack F Vogel 2138*1a4e3449SJack F Vogel /* Autoneg flow control on copper adapters */ 2139*1a4e3449SJack F Vogel case ixgbe_media_type_copper: 2140*1a4e3449SJack F Vogel if (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS) 2141*1a4e3449SJack F Vogel ret_val = ixgbe_fc_autoneg_copper(hw); 2142*1a4e3449SJack F Vogel break; 2143*1a4e3449SJack F Vogel 2144*1a4e3449SJack F Vogel default: 2145*1a4e3449SJack F Vogel break; 2146*1a4e3449SJack F Vogel } 2147*1a4e3449SJack F Vogel 2148*1a4e3449SJack F Vogel out: 2149*1a4e3449SJack F Vogel if (ret_val == IXGBE_SUCCESS) { 2150*1a4e3449SJack F Vogel hw->fc.fc_was_autonegged = TRUE; 2151*1a4e3449SJack F Vogel } else { 2152*1a4e3449SJack F Vogel hw->fc.fc_was_autonegged = FALSE; 2153*1a4e3449SJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 2154*1a4e3449SJack F Vogel } 2155*1a4e3449SJack F Vogel return ret_val; 2156*1a4e3449SJack F Vogel } 2157*1a4e3449SJack F Vogel 2158*1a4e3449SJack F Vogel /** 2159*1a4e3449SJack F Vogel * ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber 2160*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 2161*1a4e3449SJack F Vogel * @speed: 2162*1a4e3449SJack F Vogel * @link_up 2163*1a4e3449SJack F Vogel * 2164*1a4e3449SJack F Vogel * Enable flow control according on 1 gig fiber. 2165*1a4e3449SJack F Vogel **/ 2166*1a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw) 2167*1a4e3449SJack F Vogel { 2168*1a4e3449SJack F Vogel u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; 2169*1a4e3449SJack F Vogel s32 ret_val; 2170*1a4e3449SJack F Vogel 2171*1a4e3449SJack F Vogel /* 2172*1a4e3449SJack F Vogel * On multispeed fiber at 1g, bail out if 2173*1a4e3449SJack F Vogel * - link is up but AN did not complete, or if 2174*1a4e3449SJack F Vogel * - link is up and AN completed but timed out 2175*1a4e3449SJack F Vogel */ 2176*1a4e3449SJack F Vogel 2177*1a4e3449SJack F Vogel linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); 2178*1a4e3449SJack F Vogel if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || 2179*1a4e3449SJack F Vogel ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { 2180*1a4e3449SJack F Vogel ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 2181*1a4e3449SJack F Vogel goto out; 2182*1a4e3449SJack F Vogel } 2183*1a4e3449SJack F Vogel 2184*1a4e3449SJack F Vogel pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); 2185*1a4e3449SJack F Vogel pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); 2186*1a4e3449SJack F Vogel 2187*1a4e3449SJack F Vogel ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg, 2188*1a4e3449SJack F Vogel pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE, 2189*1a4e3449SJack F Vogel IXGBE_PCS1GANA_ASM_PAUSE, 2190*1a4e3449SJack F Vogel IXGBE_PCS1GANA_SYM_PAUSE, 2191*1a4e3449SJack F Vogel IXGBE_PCS1GANA_ASM_PAUSE); 2192*1a4e3449SJack F Vogel 2193*1a4e3449SJack F Vogel out: 2194*1a4e3449SJack F Vogel return ret_val; 2195*1a4e3449SJack F Vogel } 2196*1a4e3449SJack F Vogel 2197*1a4e3449SJack F Vogel /** 2198*1a4e3449SJack F Vogel * ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37 2199*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 2200*1a4e3449SJack F Vogel * 2201*1a4e3449SJack F Vogel * Enable flow control according to IEEE clause 37. 2202*1a4e3449SJack F Vogel **/ 2203*1a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw) 2204*1a4e3449SJack F Vogel { 2205*1a4e3449SJack F Vogel u32 links2, anlp1_reg, autoc_reg, links; 2206*1a4e3449SJack F Vogel s32 ret_val; 2207*1a4e3449SJack F Vogel 22082969bf0eSJack F Vogel /* 22092969bf0eSJack F Vogel * On backplane, bail out if 22102969bf0eSJack F Vogel * - backplane autoneg was not completed, or if 22112969bf0eSJack F Vogel * - we are 82599 and link partner is not AN enabled 22122969bf0eSJack F Vogel */ 22132969bf0eSJack F Vogel links = IXGBE_READ_REG(hw, IXGBE_LINKS); 22142969bf0eSJack F Vogel if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { 22152969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 22162969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 2217*1a4e3449SJack F Vogel ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 22182969bf0eSJack F Vogel goto out; 22192969bf0eSJack F Vogel } 22202969bf0eSJack F Vogel 22212969bf0eSJack F Vogel if (hw->mac.type == ixgbe_mac_82599EB) { 22222969bf0eSJack F Vogel links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); 22232969bf0eSJack F Vogel if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { 22242969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 22252969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 2226*1a4e3449SJack F Vogel ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 22272969bf0eSJack F Vogel goto out; 22282969bf0eSJack F Vogel } 22292969bf0eSJack F Vogel } 22302969bf0eSJack F Vogel /* 22312969bf0eSJack F Vogel * Read the 10g AN autoc and LP ability registers and resolve 22322969bf0eSJack F Vogel * local flow control settings accordingly 22332969bf0eSJack F Vogel */ 22342969bf0eSJack F Vogel autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 22352969bf0eSJack F Vogel anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); 22362969bf0eSJack F Vogel 2237*1a4e3449SJack F Vogel ret_val = ixgbe_negotiate_fc(hw, autoc_reg, 2238*1a4e3449SJack F Vogel anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE, 2239*1a4e3449SJack F Vogel IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE); 2240*1a4e3449SJack F Vogel 2241*1a4e3449SJack F Vogel out: 2242*1a4e3449SJack F Vogel return ret_val; 2243*1a4e3449SJack F Vogel } 2244*1a4e3449SJack F Vogel 2245*1a4e3449SJack F Vogel /** 2246*1a4e3449SJack F Vogel * ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37 2247*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 2248*1a4e3449SJack F Vogel * 2249*1a4e3449SJack F Vogel * Enable flow control according to IEEE clause 37. 2250*1a4e3449SJack F Vogel **/ 2251*1a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw) 2252*1a4e3449SJack F Vogel { 2253*1a4e3449SJack F Vogel u16 technology_ability_reg = 0; 2254*1a4e3449SJack F Vogel u16 lp_technology_ability_reg = 0; 2255*1a4e3449SJack F Vogel 2256*1a4e3449SJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, 2257*1a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 2258*1a4e3449SJack F Vogel &technology_ability_reg); 2259*1a4e3449SJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_LP, 2260*1a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 2261*1a4e3449SJack F Vogel &lp_technology_ability_reg); 2262*1a4e3449SJack F Vogel 2263*1a4e3449SJack F Vogel return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg, 2264*1a4e3449SJack F Vogel (u32)lp_technology_ability_reg, 2265*1a4e3449SJack F Vogel IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE, 2266*1a4e3449SJack F Vogel IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE); 2267*1a4e3449SJack F Vogel } 2268*1a4e3449SJack F Vogel 2269*1a4e3449SJack F Vogel /** 2270*1a4e3449SJack F Vogel * ixgbe_negotiate_fc - Negotiate flow control 2271*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 2272*1a4e3449SJack F Vogel * @adv_reg: flow control advertised settings 2273*1a4e3449SJack F Vogel * @lp_reg: link partner's flow control settings 2274*1a4e3449SJack F Vogel * @adv_sym: symmetric pause bit in advertisement 2275*1a4e3449SJack F Vogel * @adv_asm: asymmetric pause bit in advertisement 2276*1a4e3449SJack F Vogel * @lp_sym: symmetric pause bit in link partner advertisement 2277*1a4e3449SJack F Vogel * @lp_asm: asymmetric pause bit in link partner advertisement 2278*1a4e3449SJack F Vogel * 2279*1a4e3449SJack F Vogel * Find the intersection between advertised settings and link partner's 2280*1a4e3449SJack F Vogel * advertised settings 2281*1a4e3449SJack F Vogel **/ 2282*1a4e3449SJack F Vogel static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, 2283*1a4e3449SJack F Vogel u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) 2284*1a4e3449SJack F Vogel { 2285*1a4e3449SJack F Vogel if ((!(adv_reg)) || (!(lp_reg))) 2286*1a4e3449SJack F Vogel return IXGBE_ERR_FC_NOT_NEGOTIATED; 2287*1a4e3449SJack F Vogel 2288*1a4e3449SJack F Vogel if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { 22892969bf0eSJack F Vogel /* 22902969bf0eSJack F Vogel * Now we need to check if the user selected Rx ONLY 22912969bf0eSJack F Vogel * of pause frames. In this case, we had to advertise 22922969bf0eSJack F Vogel * FULL flow control because we could not advertise RX 22932969bf0eSJack F Vogel * ONLY. Hence, we must now check to see if we need to 22942969bf0eSJack F Vogel * turn OFF the TRANSMISSION of PAUSE frames. 22952969bf0eSJack F Vogel */ 22962969bf0eSJack F Vogel if (hw->fc.requested_mode == ixgbe_fc_full) { 22972969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_full; 22982969bf0eSJack F Vogel DEBUGOUT("Flow Control = FULL.\n"); 22992969bf0eSJack F Vogel } else { 23002969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 23012969bf0eSJack F Vogel DEBUGOUT("Flow Control=RX PAUSE frames only\n"); 23022969bf0eSJack F Vogel } 2303*1a4e3449SJack F Vogel } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) && 2304*1a4e3449SJack F Vogel (lp_reg & lp_sym) && (lp_reg & lp_asm)) { 23052969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_tx_pause; 23062969bf0eSJack F Vogel DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); 2307*1a4e3449SJack F Vogel } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) && 2308*1a4e3449SJack F Vogel !(lp_reg & lp_sym) && (lp_reg & lp_asm)) { 23092969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 23102969bf0eSJack F Vogel DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); 23112969bf0eSJack F Vogel } else { 23122969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_none; 23132969bf0eSJack F Vogel DEBUGOUT("Flow Control = NONE.\n"); 23142969bf0eSJack F Vogel } 2315*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 23161b6e0dbaSJack F Vogel } 23171b6e0dbaSJack F Vogel 23180ac6dfecSJack F Vogel /** 23190ac6dfecSJack F Vogel * ixgbe_setup_fc - Set up flow control 23200ac6dfecSJack F Vogel * @hw: pointer to hardware structure 23210ac6dfecSJack F Vogel * 23220ac6dfecSJack F Vogel * Called at init time to set up flow control. 23230ac6dfecSJack F Vogel **/ 23240ac6dfecSJack F Vogel s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) 23250ac6dfecSJack F Vogel { 23260ac6dfecSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 2327*1a4e3449SJack F Vogel u32 reg = 0, reg_bp = 0; 2328*1a4e3449SJack F Vogel u16 reg_cu = 0; 23290ac6dfecSJack F Vogel 23302969bf0eSJack F Vogel DEBUGFUNC("ixgbe_setup_fc"); 23312969bf0eSJack F Vogel 23320ac6dfecSJack F Vogel /* Validate the packetbuf configuration */ 23330ac6dfecSJack F Vogel if (packetbuf_num < 0 || packetbuf_num > 7) { 23340ac6dfecSJack F Vogel DEBUGOUT1("Invalid packet buffer number [%d], expected range is" 23350ac6dfecSJack F Vogel " 0-7\n", packetbuf_num); 23360ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 23370ac6dfecSJack F Vogel goto out; 23380ac6dfecSJack F Vogel } 23390ac6dfecSJack F Vogel 23400ac6dfecSJack F Vogel /* 23410ac6dfecSJack F Vogel * Validate the water mark configuration. Zero water marks are invalid 23420ac6dfecSJack F Vogel * because it causes the controller to just blast out fc packets. 23430ac6dfecSJack F Vogel */ 23440ac6dfecSJack F Vogel if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { 23450ac6dfecSJack F Vogel DEBUGOUT("Invalid water mark configuration\n"); 23460ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 23470ac6dfecSJack F Vogel goto out; 23480ac6dfecSJack F Vogel } 23490ac6dfecSJack F Vogel 23500ac6dfecSJack F Vogel /* 23510ac6dfecSJack F Vogel * Validate the requested mode. Strict IEEE mode does not allow 23520ac6dfecSJack F Vogel * ixgbe_fc_rx_pause because it will cause us to fail at UNH. 23530ac6dfecSJack F Vogel */ 23540ac6dfecSJack F Vogel if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { 23550ac6dfecSJack F Vogel DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); 23560ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 23570ac6dfecSJack F Vogel goto out; 23580ac6dfecSJack F Vogel } 23590ac6dfecSJack F Vogel 23600ac6dfecSJack F Vogel /* 23610ac6dfecSJack F Vogel * 10gig parts do not have a word in the EEPROM to determine the 23620ac6dfecSJack F Vogel * default flow control setting, so we explicitly set it to full. 23630ac6dfecSJack F Vogel */ 23640ac6dfecSJack F Vogel if (hw->fc.requested_mode == ixgbe_fc_default) 23650ac6dfecSJack F Vogel hw->fc.requested_mode = ixgbe_fc_full; 23660ac6dfecSJack F Vogel 23670ac6dfecSJack F Vogel /* 2368*1a4e3449SJack F Vogel * Set up the 1G and 10G flow control advertisement registers so the 2369*1a4e3449SJack F Vogel * HW will be able to do fc autoneg once the cable is plugged in. If 2370*1a4e3449SJack F Vogel * we link at 10G, the 1G advertisement is harmless and vice versa. 23710ac6dfecSJack F Vogel */ 2372*1a4e3449SJack F Vogel 2373*1a4e3449SJack F Vogel switch (hw->phy.media_type) { 2374*1a4e3449SJack F Vogel case ixgbe_media_type_fiber: 2375*1a4e3449SJack F Vogel case ixgbe_media_type_backplane: 23760ac6dfecSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); 2377*1a4e3449SJack F Vogel reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC); 2378*1a4e3449SJack F Vogel break; 2379*1a4e3449SJack F Vogel 2380*1a4e3449SJack F Vogel case ixgbe_media_type_copper: 2381*1a4e3449SJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, 2382*1a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®_cu); 2383*1a4e3449SJack F Vogel break; 2384*1a4e3449SJack F Vogel 2385*1a4e3449SJack F Vogel default: 2386*1a4e3449SJack F Vogel ; 2387*1a4e3449SJack F Vogel } 23880ac6dfecSJack F Vogel 23890ac6dfecSJack F Vogel /* 23900ac6dfecSJack F Vogel * The possible values of fc.requested_mode are: 23910ac6dfecSJack F Vogel * 0: Flow control is completely disabled 23920ac6dfecSJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames, 23930ac6dfecSJack F Vogel * but not send pause frames). 23940ac6dfecSJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but 23950ac6dfecSJack F Vogel * we do not support receiving pause frames). 23960ac6dfecSJack F Vogel * 3: Both Rx and Tx flow control (symmetric) are enabled. 23970ac6dfecSJack F Vogel * other: Invalid. 23980ac6dfecSJack F Vogel */ 23990ac6dfecSJack F Vogel switch (hw->fc.requested_mode) { 24000ac6dfecSJack F Vogel case ixgbe_fc_none: 24010ac6dfecSJack F Vogel /* Flow control completely disabled by software override. */ 24020ac6dfecSJack F Vogel reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 2403*1a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) 2404*1a4e3449SJack F Vogel reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE | 2405*1a4e3449SJack F Vogel IXGBE_AUTOC_ASM_PAUSE); 2406*1a4e3449SJack F Vogel else if (hw->phy.media_type == ixgbe_media_type_copper) 2407*1a4e3449SJack F Vogel reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); 24080ac6dfecSJack F Vogel break; 24090ac6dfecSJack F Vogel case ixgbe_fc_rx_pause: 24100ac6dfecSJack F Vogel /* 24110ac6dfecSJack F Vogel * Rx Flow control is enabled and Tx Flow control is 24120ac6dfecSJack F Vogel * disabled by software override. Since there really 24130ac6dfecSJack F Vogel * isn't a way to advertise that we are capable of RX 24140ac6dfecSJack F Vogel * Pause ONLY, we will advertise that we support both 24150ac6dfecSJack F Vogel * symmetric and asymmetric Rx PAUSE. Later, we will 24160ac6dfecSJack F Vogel * disable the adapter's ability to send PAUSE frames. 24170ac6dfecSJack F Vogel */ 24180ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 2419*1a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) 2420*1a4e3449SJack F Vogel reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | 2421*1a4e3449SJack F Vogel IXGBE_AUTOC_ASM_PAUSE); 2422*1a4e3449SJack F Vogel else if (hw->phy.media_type == ixgbe_media_type_copper) 2423*1a4e3449SJack F Vogel reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); 24240ac6dfecSJack F Vogel break; 24250ac6dfecSJack F Vogel case ixgbe_fc_tx_pause: 24260ac6dfecSJack F Vogel /* 24270ac6dfecSJack F Vogel * Tx Flow control is enabled, and Rx Flow control is 24280ac6dfecSJack F Vogel * disabled by software override. 24290ac6dfecSJack F Vogel */ 24300ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_ASM_PAUSE); 24310ac6dfecSJack F Vogel reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); 2432*1a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) { 2433*1a4e3449SJack F Vogel reg_bp |= (IXGBE_AUTOC_ASM_PAUSE); 2434*1a4e3449SJack F Vogel reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE); 2435*1a4e3449SJack F Vogel } else if (hw->phy.media_type == ixgbe_media_type_copper) { 2436*1a4e3449SJack F Vogel reg_cu |= (IXGBE_TAF_ASM_PAUSE); 2437*1a4e3449SJack F Vogel reg_cu &= ~(IXGBE_TAF_SYM_PAUSE); 2438*1a4e3449SJack F Vogel } 24390ac6dfecSJack F Vogel break; 24400ac6dfecSJack F Vogel case ixgbe_fc_full: 24410ac6dfecSJack F Vogel /* Flow control (both Rx and Tx) is enabled by SW override. */ 24420ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 2443*1a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) 2444*1a4e3449SJack F Vogel reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | 2445*1a4e3449SJack F Vogel IXGBE_AUTOC_ASM_PAUSE); 2446*1a4e3449SJack F Vogel else if (hw->phy.media_type == ixgbe_media_type_copper) 2447*1a4e3449SJack F Vogel reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); 24480ac6dfecSJack F Vogel break; 24490ac6dfecSJack F Vogel default: 24500ac6dfecSJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 24512969bf0eSJack F Vogel ret_val = IXGBE_ERR_CONFIG; 24520ac6dfecSJack F Vogel goto out; 24530ac6dfecSJack F Vogel break; 24540ac6dfecSJack F Vogel } 24550ac6dfecSJack F Vogel 2456*1a4e3449SJack F Vogel /* 2457*1a4e3449SJack F Vogel * Enable auto-negotiation between the MAC & PHY; 2458*1a4e3449SJack F Vogel * the MAC will advertise clause 37 flow control. 2459*1a4e3449SJack F Vogel */ 24600ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); 24610ac6dfecSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); 24620ac6dfecSJack F Vogel 24630ac6dfecSJack F Vogel /* Disable AN timeout */ 24640ac6dfecSJack F Vogel if (hw->fc.strict_ieee) 24650ac6dfecSJack F Vogel reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; 24660ac6dfecSJack F Vogel 24670ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); 24680ac6dfecSJack F Vogel DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg); 24690ac6dfecSJack F Vogel 24702969bf0eSJack F Vogel /* 2471*1a4e3449SJack F Vogel * AUTOC restart handles negotiation of 1G and 10G on backplane 2472*1a4e3449SJack F Vogel * and copper. There is no need to set the PCS1GCTL register. 2473*1a4e3449SJack F Vogel * 24742969bf0eSJack F Vogel */ 2475*1a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) { 2476*1a4e3449SJack F Vogel reg_bp |= IXGBE_AUTOC_AN_RESTART; 2477*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); 2478*1a4e3449SJack F Vogel } else if ((hw->phy.media_type == ixgbe_media_type_copper) && 2479*1a4e3449SJack F Vogel (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) { 2480*1a4e3449SJack F Vogel hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, 2481*1a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu); 24822969bf0eSJack F Vogel } 24832969bf0eSJack F Vogel 2484*1a4e3449SJack F Vogel DEBUGOUT1("Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); 24850ac6dfecSJack F Vogel out: 24860ac6dfecSJack F Vogel return ret_val; 24870ac6dfecSJack F Vogel } 24881b6e0dbaSJack F Vogel 248913705f88SJack F Vogel /** 249013705f88SJack F Vogel * ixgbe_disable_pcie_master - Disable PCI-express master access 249113705f88SJack F Vogel * @hw: pointer to hardware structure 249213705f88SJack F Vogel * 249313705f88SJack F Vogel * Disables PCI-Express master access and verifies there are no pending 249413705f88SJack F Vogel * requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable 249513705f88SJack F Vogel * bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS 249613705f88SJack F Vogel * is returned signifying master requests disabled. 249713705f88SJack F Vogel **/ 249813705f88SJack F Vogel s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) 249913705f88SJack F Vogel { 25005b7f4cedSJack F Vogel u32 i; 25015b7f4cedSJack F Vogel u32 reg_val; 25025b7f4cedSJack F Vogel u32 number_of_queues; 2503c0014855SJack F Vogel s32 status = IXGBE_SUCCESS; 250413705f88SJack F Vogel 25052969bf0eSJack F Vogel DEBUGFUNC("ixgbe_disable_pcie_master"); 25062969bf0eSJack F Vogel 2507c0014855SJack F Vogel /* Just jump out if bus mastering is already disabled */ 2508c0014855SJack F Vogel if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) 2509c0014855SJack F Vogel goto out; 2510c0014855SJack F Vogel 25115b7f4cedSJack F Vogel /* Disable the receive unit by stopping each queue */ 25125b7f4cedSJack F Vogel number_of_queues = hw->mac.max_rx_queues; 25135b7f4cedSJack F Vogel for (i = 0; i < number_of_queues; i++) { 25145b7f4cedSJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); 25155b7f4cedSJack F Vogel if (reg_val & IXGBE_RXDCTL_ENABLE) { 25165b7f4cedSJack F Vogel reg_val &= ~IXGBE_RXDCTL_ENABLE; 25175b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val); 25185b7f4cedSJack F Vogel } 25195b7f4cedSJack F Vogel } 25205b7f4cedSJack F Vogel 25215b7f4cedSJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL); 25225b7f4cedSJack F Vogel reg_val |= IXGBE_CTRL_GIO_DIS; 25235b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val); 252413705f88SJack F Vogel 252513705f88SJack F Vogel for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 2526c0014855SJack F Vogel if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) 2527c0014855SJack F Vogel goto out; 252813705f88SJack F Vogel usec_delay(100); 252913705f88SJack F Vogel } 253013705f88SJack F Vogel 2531c0014855SJack F Vogel DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n"); 2532c0014855SJack F Vogel status = IXGBE_ERR_MASTER_REQUESTS_PENDING; 2533c0014855SJack F Vogel 2534c0014855SJack F Vogel /* 2535c0014855SJack F Vogel * The GIO Master Disable bit didn't clear. There are multiple reasons 2536c0014855SJack F Vogel * for this listed in the datasheet 5.2.5.3.2 Master Disable, and they 2537c0014855SJack F Vogel * all require a double reset to recover from. Before proceeding, we 2538c0014855SJack F Vogel * first wait a little more to try to ensure that, at a minimum, the 2539c0014855SJack F Vogel * PCIe block has no transactions pending. 2540c0014855SJack F Vogel */ 2541c0014855SJack F Vogel for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 2542c0014855SJack F Vogel if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) & 2543c0014855SJack F Vogel IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) 2544c0014855SJack F Vogel break; 2545c0014855SJack F Vogel usec_delay(100); 2546c0014855SJack F Vogel } 2547c0014855SJack F Vogel 2548c0014855SJack F Vogel if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT) 2549c0014855SJack F Vogel DEBUGOUT("PCIe transaction pending bit also did not clear.\n"); 2550c0014855SJack F Vogel 2551c0014855SJack F Vogel /* 2552c0014855SJack F Vogel * Two consecutive resets are required via CTRL.RST per datasheet 2553c0014855SJack F Vogel * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine 2554c0014855SJack F Vogel * of this need. The first reset prevents new master requests from 2555c0014855SJack F Vogel * being issued by our device. We then must wait 1usec for any 2556c0014855SJack F Vogel * remaining completions from the PCIe bus to trickle in, and then reset 2557c0014855SJack F Vogel * again to clear out any effects they may have had on our device. 2558c0014855SJack F Vogel */ 2559c0014855SJack F Vogel hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 2560c0014855SJack F Vogel 2561c0014855SJack F Vogel out: 256213705f88SJack F Vogel return status; 256313705f88SJack F Vogel } 256413705f88SJack F Vogel 256513705f88SJack F Vogel 256613705f88SJack F Vogel /** 25679ca4041bSJack F Vogel * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore 256813705f88SJack F Vogel * @hw: pointer to hardware structure 25699ca4041bSJack F Vogel * @mask: Mask to specify which semaphore to acquire 257013705f88SJack F Vogel * 25719ca4041bSJack F Vogel * Acquires the SWFW semaphore thought the GSSR register for the specified 257213705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 257313705f88SJack F Vogel **/ 257413705f88SJack F Vogel s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) 257513705f88SJack F Vogel { 257613705f88SJack F Vogel u32 gssr; 257713705f88SJack F Vogel u32 swmask = mask; 257813705f88SJack F Vogel u32 fwmask = mask << 5; 257913705f88SJack F Vogel s32 timeout = 200; 258013705f88SJack F Vogel 25812969bf0eSJack F Vogel DEBUGFUNC("ixgbe_acquire_swfw_sync"); 25822969bf0eSJack F Vogel 258313705f88SJack F Vogel while (timeout) { 25840ac6dfecSJack F Vogel /* 25850ac6dfecSJack F Vogel * SW EEPROM semaphore bit is used for access to all 25860ac6dfecSJack F Vogel * SW_FW_SYNC/GSSR bits (not just EEPROM) 25870ac6dfecSJack F Vogel */ 258813705f88SJack F Vogel if (ixgbe_get_eeprom_semaphore(hw)) 25892969bf0eSJack F Vogel return IXGBE_ERR_SWFW_SYNC; 259013705f88SJack F Vogel 259113705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 259213705f88SJack F Vogel if (!(gssr & (fwmask | swmask))) 259313705f88SJack F Vogel break; 259413705f88SJack F Vogel 259513705f88SJack F Vogel /* 259613705f88SJack F Vogel * Firmware currently using resource (fwmask) or other software 259713705f88SJack F Vogel * thread currently using resource (swmask) 259813705f88SJack F Vogel */ 259913705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 260013705f88SJack F Vogel msec_delay(5); 260113705f88SJack F Vogel timeout--; 260213705f88SJack F Vogel } 260313705f88SJack F Vogel 260413705f88SJack F Vogel if (!timeout) { 26050ac6dfecSJack F Vogel DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); 26062969bf0eSJack F Vogel return IXGBE_ERR_SWFW_SYNC; 260713705f88SJack F Vogel } 260813705f88SJack F Vogel 260913705f88SJack F Vogel gssr |= swmask; 261013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 261113705f88SJack F Vogel 261213705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 261313705f88SJack F Vogel return IXGBE_SUCCESS; 261413705f88SJack F Vogel } 261513705f88SJack F Vogel 261613705f88SJack F Vogel /** 261713705f88SJack F Vogel * ixgbe_release_swfw_sync - Release SWFW semaphore 261813705f88SJack F Vogel * @hw: pointer to hardware structure 26199ca4041bSJack F Vogel * @mask: Mask to specify which semaphore to release 262013705f88SJack F Vogel * 26219ca4041bSJack F Vogel * Releases the SWFW semaphore thought the GSSR register for the specified 262213705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 262313705f88SJack F Vogel **/ 262413705f88SJack F Vogel void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) 262513705f88SJack F Vogel { 262613705f88SJack F Vogel u32 gssr; 262713705f88SJack F Vogel u32 swmask = mask; 262813705f88SJack F Vogel 26292969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_swfw_sync"); 26302969bf0eSJack F Vogel 263113705f88SJack F Vogel ixgbe_get_eeprom_semaphore(hw); 263213705f88SJack F Vogel 263313705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 263413705f88SJack F Vogel gssr &= ~swmask; 263513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 263613705f88SJack F Vogel 263713705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 26380ac6dfecSJack F Vogel } 26390ac6dfecSJack F Vogel 26400ac6dfecSJack F Vogel /** 26410ac6dfecSJack F Vogel * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit 26420ac6dfecSJack F Vogel * @hw: pointer to hardware structure 26430ac6dfecSJack F Vogel * @regval: register value to write to RXCTRL 26440ac6dfecSJack F Vogel * 26450ac6dfecSJack F Vogel * Enables the Rx DMA unit 26460ac6dfecSJack F Vogel **/ 26470ac6dfecSJack F Vogel s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) 26480ac6dfecSJack F Vogel { 26492969bf0eSJack F Vogel DEBUGFUNC("ixgbe_enable_rx_dma_generic"); 26502969bf0eSJack F Vogel 26510ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); 26520ac6dfecSJack F Vogel 26530ac6dfecSJack F Vogel return IXGBE_SUCCESS; 26540ac6dfecSJack F Vogel } 26550ac6dfecSJack F Vogel 26560ac6dfecSJack F Vogel /** 26570ac6dfecSJack F Vogel * ixgbe_blink_led_start_generic - Blink LED based on index. 26580ac6dfecSJack F Vogel * @hw: pointer to hardware structure 26590ac6dfecSJack F Vogel * @index: led number to blink 26600ac6dfecSJack F Vogel **/ 26610ac6dfecSJack F Vogel s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) 26620ac6dfecSJack F Vogel { 26630ac6dfecSJack F Vogel ixgbe_link_speed speed = 0; 26640ac6dfecSJack F Vogel bool link_up = 0; 26650ac6dfecSJack F Vogel u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 26660ac6dfecSJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 26670ac6dfecSJack F Vogel 26682969bf0eSJack F Vogel DEBUGFUNC("ixgbe_blink_led_start_generic"); 26692969bf0eSJack F Vogel 26700ac6dfecSJack F Vogel /* 26710ac6dfecSJack F Vogel * Link must be up to auto-blink the LEDs; 26720ac6dfecSJack F Vogel * Force it if link is down. 26730ac6dfecSJack F Vogel */ 26740ac6dfecSJack F Vogel hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 26750ac6dfecSJack F Vogel 26760ac6dfecSJack F Vogel if (!link_up) { 2677d8602bb9SJack F Vogel autoc_reg |= IXGBE_AUTOC_AN_RESTART; 26780ac6dfecSJack F Vogel autoc_reg |= IXGBE_AUTOC_FLU; 26790ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 26800ac6dfecSJack F Vogel msec_delay(10); 26810ac6dfecSJack F Vogel } 26820ac6dfecSJack F Vogel 26830ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 26840ac6dfecSJack F Vogel led_reg |= IXGBE_LED_BLINK(index); 26850ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 26860ac6dfecSJack F Vogel IXGBE_WRITE_FLUSH(hw); 26870ac6dfecSJack F Vogel 26880ac6dfecSJack F Vogel return IXGBE_SUCCESS; 26890ac6dfecSJack F Vogel } 26900ac6dfecSJack F Vogel 26910ac6dfecSJack F Vogel /** 26920ac6dfecSJack F Vogel * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. 26930ac6dfecSJack F Vogel * @hw: pointer to hardware structure 26940ac6dfecSJack F Vogel * @index: led number to stop blinking 26950ac6dfecSJack F Vogel **/ 26960ac6dfecSJack F Vogel s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) 26970ac6dfecSJack F Vogel { 26980ac6dfecSJack F Vogel u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 26990ac6dfecSJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 27000ac6dfecSJack F Vogel 27012969bf0eSJack F Vogel DEBUGFUNC("ixgbe_blink_led_stop_generic"); 27022969bf0eSJack F Vogel 2703d8602bb9SJack F Vogel 27040ac6dfecSJack F Vogel autoc_reg &= ~IXGBE_AUTOC_FLU; 27050ac6dfecSJack F Vogel autoc_reg |= IXGBE_AUTOC_AN_RESTART; 27060ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 27070ac6dfecSJack F Vogel 27080ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 27090ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_BLINK(index); 27100ac6dfecSJack F Vogel led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 27110ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 27120ac6dfecSJack F Vogel IXGBE_WRITE_FLUSH(hw); 27130ac6dfecSJack F Vogel 27140ac6dfecSJack F Vogel return IXGBE_SUCCESS; 271513705f88SJack F Vogel } 271613705f88SJack F Vogel 27172969bf0eSJack F Vogel /** 27182969bf0eSJack F Vogel * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM 27192969bf0eSJack F Vogel * @hw: pointer to hardware structure 27202969bf0eSJack F Vogel * @san_mac_offset: SAN MAC address offset 27212969bf0eSJack F Vogel * 27222969bf0eSJack F Vogel * This function will read the EEPROM location for the SAN MAC address 27232969bf0eSJack F Vogel * pointer, and returns the value at that location. This is used in both 27242969bf0eSJack F Vogel * get and set mac_addr routines. 27252969bf0eSJack F Vogel **/ 27262969bf0eSJack F Vogel static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, 27272969bf0eSJack F Vogel u16 *san_mac_offset) 27282969bf0eSJack F Vogel { 27292969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_san_mac_addr_offset"); 27302969bf0eSJack F Vogel 27312969bf0eSJack F Vogel /* 27322969bf0eSJack F Vogel * First read the EEPROM pointer to see if the MAC addresses are 27332969bf0eSJack F Vogel * available. 27342969bf0eSJack F Vogel */ 27352969bf0eSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset); 27362969bf0eSJack F Vogel 27372969bf0eSJack F Vogel return IXGBE_SUCCESS; 27382969bf0eSJack F Vogel } 27392969bf0eSJack F Vogel 27402969bf0eSJack F Vogel /** 27412969bf0eSJack F Vogel * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM 27422969bf0eSJack F Vogel * @hw: pointer to hardware structure 27432969bf0eSJack F Vogel * @san_mac_addr: SAN MAC address 27442969bf0eSJack F Vogel * 27452969bf0eSJack F Vogel * Reads the SAN MAC address from the EEPROM, if it's available. This is 27462969bf0eSJack F Vogel * per-port, so set_lan_id() must be called before reading the addresses. 27472969bf0eSJack F Vogel * set_lan_id() is called by identify_sfp(), but this cannot be relied 27482969bf0eSJack F Vogel * upon for non-SFP connections, so we must call it here. 27492969bf0eSJack F Vogel **/ 27502969bf0eSJack F Vogel s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) 27512969bf0eSJack F Vogel { 27522969bf0eSJack F Vogel u16 san_mac_data, san_mac_offset; 27532969bf0eSJack F Vogel u8 i; 27542969bf0eSJack F Vogel 27552969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_san_mac_addr_generic"); 27562969bf0eSJack F Vogel 27572969bf0eSJack F Vogel /* 27582969bf0eSJack F Vogel * First read the EEPROM pointer to see if the MAC addresses are 27592969bf0eSJack F Vogel * available. If they're not, no point in calling set_lan_id() here. 27602969bf0eSJack F Vogel */ 27612969bf0eSJack F Vogel ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); 27622969bf0eSJack F Vogel 27632969bf0eSJack F Vogel if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { 27642969bf0eSJack F Vogel /* 27652969bf0eSJack F Vogel * No addresses available in this EEPROM. It's not an 27662969bf0eSJack F Vogel * error though, so just wipe the local address and return. 27672969bf0eSJack F Vogel */ 27682969bf0eSJack F Vogel for (i = 0; i < 6; i++) 27692969bf0eSJack F Vogel san_mac_addr[i] = 0xFF; 27702969bf0eSJack F Vogel 27712969bf0eSJack F Vogel goto san_mac_addr_out; 27722969bf0eSJack F Vogel } 27732969bf0eSJack F Vogel 27742969bf0eSJack F Vogel /* make sure we know which port we need to program */ 27752969bf0eSJack F Vogel hw->mac.ops.set_lan_id(hw); 27762969bf0eSJack F Vogel /* apply the port offset to the address offset */ 27772969bf0eSJack F Vogel (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : 27782969bf0eSJack F Vogel (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); 27792969bf0eSJack F Vogel for (i = 0; i < 3; i++) { 27802969bf0eSJack F Vogel hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data); 27812969bf0eSJack F Vogel san_mac_addr[i * 2] = (u8)(san_mac_data); 27822969bf0eSJack F Vogel san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); 27832969bf0eSJack F Vogel san_mac_offset++; 27842969bf0eSJack F Vogel } 27852969bf0eSJack F Vogel 27862969bf0eSJack F Vogel san_mac_addr_out: 27872969bf0eSJack F Vogel return IXGBE_SUCCESS; 27882969bf0eSJack F Vogel } 27892969bf0eSJack F Vogel 27902969bf0eSJack F Vogel /** 27912969bf0eSJack F Vogel * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM 27922969bf0eSJack F Vogel * @hw: pointer to hardware structure 27932969bf0eSJack F Vogel * @san_mac_addr: SAN MAC address 27942969bf0eSJack F Vogel * 27952969bf0eSJack F Vogel * Write a SAN MAC address to the EEPROM. 27962969bf0eSJack F Vogel **/ 27972969bf0eSJack F Vogel s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) 27982969bf0eSJack F Vogel { 27992969bf0eSJack F Vogel s32 status = IXGBE_SUCCESS; 28002969bf0eSJack F Vogel u16 san_mac_data, san_mac_offset; 28012969bf0eSJack F Vogel u8 i; 28022969bf0eSJack F Vogel 28032969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_san_mac_addr_generic"); 28042969bf0eSJack F Vogel 28052969bf0eSJack F Vogel /* Look for SAN mac address pointer. If not defined, return */ 28062969bf0eSJack F Vogel ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); 28072969bf0eSJack F Vogel 28082969bf0eSJack F Vogel if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { 28092969bf0eSJack F Vogel status = IXGBE_ERR_NO_SAN_ADDR_PTR; 28102969bf0eSJack F Vogel goto san_mac_addr_out; 28112969bf0eSJack F Vogel } 28122969bf0eSJack F Vogel 28132969bf0eSJack F Vogel /* Make sure we know which port we need to write */ 28142969bf0eSJack F Vogel hw->mac.ops.set_lan_id(hw); 28152969bf0eSJack F Vogel /* Apply the port offset to the address offset */ 28162969bf0eSJack F Vogel (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : 28172969bf0eSJack F Vogel (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); 28182969bf0eSJack F Vogel 28192969bf0eSJack F Vogel for (i = 0; i < 3; i++) { 28202969bf0eSJack F Vogel san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8); 28212969bf0eSJack F Vogel san_mac_data |= (u16)(san_mac_addr[i * 2]); 28222969bf0eSJack F Vogel hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); 28232969bf0eSJack F Vogel san_mac_offset++; 28242969bf0eSJack F Vogel } 28252969bf0eSJack F Vogel 28262969bf0eSJack F Vogel san_mac_addr_out: 28272969bf0eSJack F Vogel return status; 28282969bf0eSJack F Vogel } 28292969bf0eSJack F Vogel 28302969bf0eSJack F Vogel /** 28312969bf0eSJack F Vogel * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count 28322969bf0eSJack F Vogel * @hw: pointer to hardware structure 28332969bf0eSJack F Vogel * 28342969bf0eSJack F Vogel * Read PCIe configuration space, and get the MSI-X vector count from 28352969bf0eSJack F Vogel * the capabilities table. 28362969bf0eSJack F Vogel **/ 28372969bf0eSJack F Vogel u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) 28382969bf0eSJack F Vogel { 28392969bf0eSJack F Vogel u32 msix_count = 64; 28402969bf0eSJack F Vogel 28412969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); 28422969bf0eSJack F Vogel if (hw->mac.msix_vectors_from_pcie) { 28432969bf0eSJack F Vogel msix_count = IXGBE_READ_PCIE_WORD(hw, 28442969bf0eSJack F Vogel IXGBE_PCIE_MSIX_82599_CAPS); 28452969bf0eSJack F Vogel msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; 28462969bf0eSJack F Vogel 28472969bf0eSJack F Vogel /* MSI-X count is zero-based in HW, so increment to give 28482969bf0eSJack F Vogel * proper value */ 28492969bf0eSJack F Vogel msix_count++; 28502969bf0eSJack F Vogel } 28512969bf0eSJack F Vogel 28522969bf0eSJack F Vogel return msix_count; 28532969bf0eSJack F Vogel } 28542969bf0eSJack F Vogel 28552969bf0eSJack F Vogel /** 28562969bf0eSJack F Vogel * ixgbe_insert_mac_addr_generic - Find a RAR for this mac address 28572969bf0eSJack F Vogel * @hw: pointer to hardware structure 28582969bf0eSJack F Vogel * @addr: Address to put into receive address register 28592969bf0eSJack F Vogel * @vmdq: VMDq pool to assign 28602969bf0eSJack F Vogel * 28612969bf0eSJack F Vogel * Puts an ethernet address into a receive address register, or 28622969bf0eSJack F Vogel * finds the rar that it is aleady in; adds to the pool list 28632969bf0eSJack F Vogel **/ 28642969bf0eSJack F Vogel s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) 28652969bf0eSJack F Vogel { 28662969bf0eSJack F Vogel static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF; 28672969bf0eSJack F Vogel u32 first_empty_rar = NO_EMPTY_RAR_FOUND; 28682969bf0eSJack F Vogel u32 rar; 28692969bf0eSJack F Vogel u32 rar_low, rar_high; 28702969bf0eSJack F Vogel u32 addr_low, addr_high; 28712969bf0eSJack F Vogel 28722969bf0eSJack F Vogel DEBUGFUNC("ixgbe_insert_mac_addr_generic"); 28732969bf0eSJack F Vogel 28742969bf0eSJack F Vogel /* swap bytes for HW little endian */ 28752969bf0eSJack F Vogel addr_low = addr[0] | (addr[1] << 8) 28762969bf0eSJack F Vogel | (addr[2] << 16) 28772969bf0eSJack F Vogel | (addr[3] << 24); 28782969bf0eSJack F Vogel addr_high = addr[4] | (addr[5] << 8); 28792969bf0eSJack F Vogel 28802969bf0eSJack F Vogel /* 28812969bf0eSJack F Vogel * Either find the mac_id in rar or find the first empty space. 28822969bf0eSJack F Vogel * rar_highwater points to just after the highest currently used 28832969bf0eSJack F Vogel * rar in order to shorten the search. It grows when we add a new 28842969bf0eSJack F Vogel * rar to the top. 28852969bf0eSJack F Vogel */ 28862969bf0eSJack F Vogel for (rar = 0; rar < hw->mac.rar_highwater; rar++) { 28872969bf0eSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); 28882969bf0eSJack F Vogel 28892969bf0eSJack F Vogel if (((IXGBE_RAH_AV & rar_high) == 0) 28902969bf0eSJack F Vogel && first_empty_rar == NO_EMPTY_RAR_FOUND) { 28912969bf0eSJack F Vogel first_empty_rar = rar; 28922969bf0eSJack F Vogel } else if ((rar_high & 0xFFFF) == addr_high) { 28932969bf0eSJack F Vogel rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar)); 28942969bf0eSJack F Vogel if (rar_low == addr_low) 28952969bf0eSJack F Vogel break; /* found it already in the rars */ 28962969bf0eSJack F Vogel } 28972969bf0eSJack F Vogel } 28982969bf0eSJack F Vogel 28992969bf0eSJack F Vogel if (rar < hw->mac.rar_highwater) { 29002969bf0eSJack F Vogel /* already there so just add to the pool bits */ 29012969bf0eSJack F Vogel ixgbe_set_vmdq(hw, rar, vmdq); 29022969bf0eSJack F Vogel } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { 29032969bf0eSJack F Vogel /* stick it into first empty RAR slot we found */ 29042969bf0eSJack F Vogel rar = first_empty_rar; 29052969bf0eSJack F Vogel ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 29062969bf0eSJack F Vogel } else if (rar == hw->mac.rar_highwater) { 29072969bf0eSJack F Vogel /* add it to the top of the list and inc the highwater mark */ 29082969bf0eSJack F Vogel ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 29092969bf0eSJack F Vogel hw->mac.rar_highwater++; 29102969bf0eSJack F Vogel } else if (rar >= hw->mac.num_rar_entries) { 29112969bf0eSJack F Vogel return IXGBE_ERR_INVALID_MAC_ADDR; 29122969bf0eSJack F Vogel } 29132969bf0eSJack F Vogel 29142969bf0eSJack F Vogel /* 29152969bf0eSJack F Vogel * If we found rar[0], make sure the default pool bit (we use pool 0) 29162969bf0eSJack F Vogel * remains cleared to be sure default pool packets will get delivered 29172969bf0eSJack F Vogel */ 29182969bf0eSJack F Vogel if (rar == 0) 29192969bf0eSJack F Vogel ixgbe_clear_vmdq(hw, rar, 0); 29202969bf0eSJack F Vogel 29212969bf0eSJack F Vogel return rar; 29222969bf0eSJack F Vogel } 29232969bf0eSJack F Vogel 29242969bf0eSJack F Vogel /** 29252969bf0eSJack F Vogel * ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address 29262969bf0eSJack F Vogel * @hw: pointer to hardware struct 29272969bf0eSJack F Vogel * @rar: receive address register index to disassociate 29282969bf0eSJack F Vogel * @vmdq: VMDq pool index to remove from the rar 29292969bf0eSJack F Vogel **/ 29302969bf0eSJack F Vogel s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) 29312969bf0eSJack F Vogel { 29322969bf0eSJack F Vogel u32 mpsar_lo, mpsar_hi; 29332969bf0eSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 29342969bf0eSJack F Vogel 29352969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_vmdq_generic"); 29362969bf0eSJack F Vogel 2937*1a4e3449SJack F Vogel /* Make sure we are using a valid rar index range */ 2938*1a4e3449SJack F Vogel if (rar >= rar_entries) { 2939*1a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", rar); 2940*1a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 2941*1a4e3449SJack F Vogel } 2942*1a4e3449SJack F Vogel 29432969bf0eSJack F Vogel mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); 29442969bf0eSJack F Vogel mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); 29452969bf0eSJack F Vogel 29462969bf0eSJack F Vogel if (!mpsar_lo && !mpsar_hi) 29472969bf0eSJack F Vogel goto done; 29482969bf0eSJack F Vogel 29492969bf0eSJack F Vogel if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { 29502969bf0eSJack F Vogel if (mpsar_lo) { 29512969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); 29522969bf0eSJack F Vogel mpsar_lo = 0; 29532969bf0eSJack F Vogel } 29542969bf0eSJack F Vogel if (mpsar_hi) { 29552969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); 29562969bf0eSJack F Vogel mpsar_hi = 0; 29572969bf0eSJack F Vogel } 29582969bf0eSJack F Vogel } else if (vmdq < 32) { 29592969bf0eSJack F Vogel mpsar_lo &= ~(1 << vmdq); 29602969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); 29612969bf0eSJack F Vogel } else { 29622969bf0eSJack F Vogel mpsar_hi &= ~(1 << (vmdq - 32)); 29632969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); 29642969bf0eSJack F Vogel } 29652969bf0eSJack F Vogel 29662969bf0eSJack F Vogel /* was that the last pool using this rar? */ 29672969bf0eSJack F Vogel if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) 29682969bf0eSJack F Vogel hw->mac.ops.clear_rar(hw, rar); 29692969bf0eSJack F Vogel done: 29702969bf0eSJack F Vogel return IXGBE_SUCCESS; 29712969bf0eSJack F Vogel } 29722969bf0eSJack F Vogel 29732969bf0eSJack F Vogel /** 29742969bf0eSJack F Vogel * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address 29752969bf0eSJack F Vogel * @hw: pointer to hardware struct 29762969bf0eSJack F Vogel * @rar: receive address register index to associate with a VMDq index 29772969bf0eSJack F Vogel * @vmdq: VMDq pool index 29782969bf0eSJack F Vogel **/ 29792969bf0eSJack F Vogel s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) 29802969bf0eSJack F Vogel { 29812969bf0eSJack F Vogel u32 mpsar; 29822969bf0eSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 29832969bf0eSJack F Vogel 29842969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_vmdq_generic"); 29852969bf0eSJack F Vogel 2986*1a4e3449SJack F Vogel /* Make sure we are using a valid rar index range */ 2987*1a4e3449SJack F Vogel if (rar >= rar_entries) { 2988*1a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", rar); 2989*1a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 2990*1a4e3449SJack F Vogel } 2991*1a4e3449SJack F Vogel 29922969bf0eSJack F Vogel if (vmdq < 32) { 29932969bf0eSJack F Vogel mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); 29942969bf0eSJack F Vogel mpsar |= 1 << vmdq; 29952969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); 29962969bf0eSJack F Vogel } else { 29972969bf0eSJack F Vogel mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); 29982969bf0eSJack F Vogel mpsar |= 1 << (vmdq - 32); 29992969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); 30002969bf0eSJack F Vogel } 30012969bf0eSJack F Vogel return IXGBE_SUCCESS; 30022969bf0eSJack F Vogel } 30032969bf0eSJack F Vogel 30042969bf0eSJack F Vogel /** 30052969bf0eSJack F Vogel * ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array 30062969bf0eSJack F Vogel * @hw: pointer to hardware structure 30072969bf0eSJack F Vogel **/ 30082969bf0eSJack F Vogel s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) 30092969bf0eSJack F Vogel { 30102969bf0eSJack F Vogel int i; 30112969bf0eSJack F Vogel 30122969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_uta_tables_generic"); 30132969bf0eSJack F Vogel DEBUGOUT(" Clearing UTA\n"); 30142969bf0eSJack F Vogel 30152969bf0eSJack F Vogel for (i = 0; i < 128; i++) 30162969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); 30172969bf0eSJack F Vogel 30182969bf0eSJack F Vogel return IXGBE_SUCCESS; 30192969bf0eSJack F Vogel } 30202969bf0eSJack F Vogel 30212969bf0eSJack F Vogel /** 30222969bf0eSJack F Vogel * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot 30232969bf0eSJack F Vogel * @hw: pointer to hardware structure 30242969bf0eSJack F Vogel * @vlan: VLAN id to write to VLAN filter 30252969bf0eSJack F Vogel * 30262969bf0eSJack F Vogel * return the VLVF index where this VLAN id should be placed 30272969bf0eSJack F Vogel * 30282969bf0eSJack F Vogel **/ 30292969bf0eSJack F Vogel s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) 30302969bf0eSJack F Vogel { 30312969bf0eSJack F Vogel u32 bits = 0; 30322969bf0eSJack F Vogel u32 first_empty_slot = 0; 30332969bf0eSJack F Vogel s32 regindex; 30342969bf0eSJack F Vogel 3035c0014855SJack F Vogel /* short cut the special case */ 3036c0014855SJack F Vogel if (vlan == 0) 3037c0014855SJack F Vogel return 0; 3038c0014855SJack F Vogel 30392969bf0eSJack F Vogel /* 30402969bf0eSJack F Vogel * Search for the vlan id in the VLVF entries. Save off the first empty 30412969bf0eSJack F Vogel * slot found along the way 30422969bf0eSJack F Vogel */ 30432969bf0eSJack F Vogel for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { 30442969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); 30452969bf0eSJack F Vogel if (!bits && !(first_empty_slot)) 30462969bf0eSJack F Vogel first_empty_slot = regindex; 30472969bf0eSJack F Vogel else if ((bits & 0x0FFF) == vlan) 30482969bf0eSJack F Vogel break; 30492969bf0eSJack F Vogel } 30502969bf0eSJack F Vogel 30512969bf0eSJack F Vogel /* 30522969bf0eSJack F Vogel * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan 30532969bf0eSJack F Vogel * in the VLVF. Else use the first empty VLVF register for this 30542969bf0eSJack F Vogel * vlan id. 30552969bf0eSJack F Vogel */ 30562969bf0eSJack F Vogel if (regindex >= IXGBE_VLVF_ENTRIES) { 30572969bf0eSJack F Vogel if (first_empty_slot) 30582969bf0eSJack F Vogel regindex = first_empty_slot; 30592969bf0eSJack F Vogel else { 30602969bf0eSJack F Vogel DEBUGOUT("No space in VLVF.\n"); 3061c0014855SJack F Vogel regindex = IXGBE_ERR_NO_SPACE; 30622969bf0eSJack F Vogel } 30632969bf0eSJack F Vogel } 30642969bf0eSJack F Vogel 30652969bf0eSJack F Vogel return regindex; 30662969bf0eSJack F Vogel } 30672969bf0eSJack F Vogel 30682969bf0eSJack F Vogel /** 30692969bf0eSJack F Vogel * ixgbe_set_vfta_generic - Set VLAN filter table 30702969bf0eSJack F Vogel * @hw: pointer to hardware structure 30712969bf0eSJack F Vogel * @vlan: VLAN id to write to VLAN filter 30722969bf0eSJack F Vogel * @vind: VMDq output index that maps queue to VLAN id in VFVFB 30732969bf0eSJack F Vogel * @vlan_on: boolean flag to turn on/off VLAN in VFVF 30742969bf0eSJack F Vogel * 30752969bf0eSJack F Vogel * Turn on/off specified VLAN in the VLAN filter table. 30762969bf0eSJack F Vogel **/ 30772969bf0eSJack F Vogel s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, 30782969bf0eSJack F Vogel bool vlan_on) 30792969bf0eSJack F Vogel { 30802969bf0eSJack F Vogel s32 regindex; 30812969bf0eSJack F Vogel u32 bitindex; 3082c0014855SJack F Vogel u32 vfta; 30832969bf0eSJack F Vogel u32 bits; 30842969bf0eSJack F Vogel u32 vt; 3085c0014855SJack F Vogel u32 targetbit; 3086c0014855SJack F Vogel bool vfta_changed = FALSE; 30872969bf0eSJack F Vogel 30882969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_vfta_generic"); 30892969bf0eSJack F Vogel 30902969bf0eSJack F Vogel if (vlan > 4095) 30912969bf0eSJack F Vogel return IXGBE_ERR_PARAM; 30922969bf0eSJack F Vogel 30932969bf0eSJack F Vogel /* 30942969bf0eSJack F Vogel * this is a 2 part operation - first the VFTA, then the 30952969bf0eSJack F Vogel * VLVF and VLVFB if VT Mode is set 3096c0014855SJack F Vogel * We don't write the VFTA until we know the VLVF part succeeded. 30972969bf0eSJack F Vogel */ 30982969bf0eSJack F Vogel 30992969bf0eSJack F Vogel /* Part 1 31002969bf0eSJack F Vogel * The VFTA is a bitstring made up of 128 32-bit registers 31012969bf0eSJack F Vogel * that enable the particular VLAN id, much like the MTA: 31022969bf0eSJack F Vogel * bits[11-5]: which register 31032969bf0eSJack F Vogel * bits[4-0]: which bit in the register 31042969bf0eSJack F Vogel */ 31052969bf0eSJack F Vogel regindex = (vlan >> 5) & 0x7F; 31062969bf0eSJack F Vogel bitindex = vlan & 0x1F; 3107c0014855SJack F Vogel targetbit = (1 << bitindex); 3108c0014855SJack F Vogel vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); 31092969bf0eSJack F Vogel 3110c0014855SJack F Vogel if (vlan_on) { 3111c0014855SJack F Vogel if (!(vfta & targetbit)) { 3112c0014855SJack F Vogel vfta |= targetbit; 3113c0014855SJack F Vogel vfta_changed = TRUE; 3114c0014855SJack F Vogel } 3115c0014855SJack F Vogel } else { 3116c0014855SJack F Vogel if ((vfta & targetbit)) { 3117c0014855SJack F Vogel vfta &= ~targetbit; 3118c0014855SJack F Vogel vfta_changed = TRUE; 3119c0014855SJack F Vogel } 3120c0014855SJack F Vogel } 31212969bf0eSJack F Vogel 31222969bf0eSJack F Vogel /* Part 2 31232969bf0eSJack F Vogel * If VT Mode is set 31242969bf0eSJack F Vogel * Either vlan_on 31252969bf0eSJack F Vogel * make sure the vlan is in VLVF 31262969bf0eSJack F Vogel * set the vind bit in the matching VLVFB 31272969bf0eSJack F Vogel * Or !vlan_on 31282969bf0eSJack F Vogel * clear the pool bit and possibly the vind 31292969bf0eSJack F Vogel */ 31302969bf0eSJack F Vogel vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); 31312969bf0eSJack F Vogel if (vt & IXGBE_VT_CTL_VT_ENABLE) { 3132c0014855SJack F Vogel s32 vlvf_index; 3133c0014855SJack F Vogel 3134c0014855SJack F Vogel vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); 3135c0014855SJack F Vogel if (vlvf_index < 0) 3136c0014855SJack F Vogel return vlvf_index; 31372969bf0eSJack F Vogel 31382969bf0eSJack F Vogel if (vlan_on) { 31392969bf0eSJack F Vogel /* set the pool bit */ 31402969bf0eSJack F Vogel if (vind < 32) { 31412969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3142c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2)); 31432969bf0eSJack F Vogel bits |= (1 << vind); 31442969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3145c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2), 31462969bf0eSJack F Vogel bits); 31472969bf0eSJack F Vogel } else { 31482969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3149c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1)); 3150c0014855SJack F Vogel bits |= (1 << (vind-32)); 31512969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3152c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1), 31532969bf0eSJack F Vogel bits); 31542969bf0eSJack F Vogel } 31552969bf0eSJack F Vogel } else { 31562969bf0eSJack F Vogel /* clear the pool bit */ 31572969bf0eSJack F Vogel if (vind < 32) { 31582969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3159c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2)); 31602969bf0eSJack F Vogel bits &= ~(1 << vind); 31612969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3162c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2), 31632969bf0eSJack F Vogel bits); 31642969bf0eSJack F Vogel bits |= IXGBE_READ_REG(hw, 3165c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1)); 31662969bf0eSJack F Vogel } else { 31672969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3168c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1)); 3169c0014855SJack F Vogel bits &= ~(1 << (vind-32)); 31702969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3171c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1), 31722969bf0eSJack F Vogel bits); 31732969bf0eSJack F Vogel bits |= IXGBE_READ_REG(hw, 3174c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2)); 31752969bf0eSJack F Vogel } 31762969bf0eSJack F Vogel } 31772969bf0eSJack F Vogel 3178c0014855SJack F Vogel /* 3179c0014855SJack F Vogel * If there are still bits set in the VLVFB registers 3180c0014855SJack F Vogel * for the VLAN ID indicated we need to see if the 3181c0014855SJack F Vogel * caller is requesting that we clear the VFTA entry bit. 3182c0014855SJack F Vogel * If the caller has requested that we clear the VFTA 3183c0014855SJack F Vogel * entry bit but there are still pools/VFs using this VLAN 3184c0014855SJack F Vogel * ID entry then ignore the request. We're not worried 3185c0014855SJack F Vogel * about the case where we're turning the VFTA VLAN ID 3186c0014855SJack F Vogel * entry bit on, only when requested to turn it off as 3187c0014855SJack F Vogel * there may be multiple pools and/or VFs using the 3188c0014855SJack F Vogel * VLAN ID entry. In that case we cannot clear the 3189c0014855SJack F Vogel * VFTA bit until all pools/VFs using that VLAN ID have also 3190c0014855SJack F Vogel * been cleared. This will be indicated by "bits" being 3191c0014855SJack F Vogel * zero. 3192c0014855SJack F Vogel */ 3193c0014855SJack F Vogel if (bits) { 3194c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 31952969bf0eSJack F Vogel (IXGBE_VLVF_VIEN | vlan)); 3196c0014855SJack F Vogel if (!vlan_on) { 3197c0014855SJack F Vogel /* someone wants to clear the vfta entry 3198c0014855SJack F Vogel * but some pools/VFs are still using it. 3199c0014855SJack F Vogel * Ignore it. */ 3200c0014855SJack F Vogel vfta_changed = FALSE; 32012969bf0eSJack F Vogel } 3202c0014855SJack F Vogel } 3203c0014855SJack F Vogel else 3204c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); 3205c0014855SJack F Vogel } 3206c0014855SJack F Vogel 3207c0014855SJack F Vogel if (vfta_changed) 3208c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); 3209c0014855SJack F Vogel 32102969bf0eSJack F Vogel return IXGBE_SUCCESS; 32112969bf0eSJack F Vogel } 32122969bf0eSJack F Vogel 32132969bf0eSJack F Vogel /** 32142969bf0eSJack F Vogel * ixgbe_clear_vfta_generic - Clear VLAN filter table 32152969bf0eSJack F Vogel * @hw: pointer to hardware structure 32162969bf0eSJack F Vogel * 32172969bf0eSJack F Vogel * Clears the VLAN filer table, and the VMDq index associated with the filter 32182969bf0eSJack F Vogel **/ 32192969bf0eSJack F Vogel s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) 32202969bf0eSJack F Vogel { 32212969bf0eSJack F Vogel u32 offset; 32222969bf0eSJack F Vogel 32232969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_vfta_generic"); 32242969bf0eSJack F Vogel 32252969bf0eSJack F Vogel for (offset = 0; offset < hw->mac.vft_size; offset++) 32262969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); 32272969bf0eSJack F Vogel 32282969bf0eSJack F Vogel for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { 32292969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); 32302969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0); 32312969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0); 32322969bf0eSJack F Vogel } 32332969bf0eSJack F Vogel 32342969bf0eSJack F Vogel return IXGBE_SUCCESS; 32352969bf0eSJack F Vogel } 32362969bf0eSJack F Vogel 32372969bf0eSJack F Vogel /** 32382969bf0eSJack F Vogel * ixgbe_check_mac_link_generic - Determine link and speed status 32392969bf0eSJack F Vogel * @hw: pointer to hardware structure 32402969bf0eSJack F Vogel * @speed: pointer to link speed 32412969bf0eSJack F Vogel * @link_up: TRUE when link is up 32422969bf0eSJack F Vogel * @link_up_wait_to_complete: bool used to wait for link up or not 32432969bf0eSJack F Vogel * 32442969bf0eSJack F Vogel * Reads the links register to determine if link is up and the current speed 32452969bf0eSJack F Vogel **/ 32462969bf0eSJack F Vogel s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, 32472969bf0eSJack F Vogel bool *link_up, bool link_up_wait_to_complete) 32482969bf0eSJack F Vogel { 3249c0014855SJack F Vogel u32 links_reg, links_orig; 32502969bf0eSJack F Vogel u32 i; 32512969bf0eSJack F Vogel 32522969bf0eSJack F Vogel DEBUGFUNC("ixgbe_check_mac_link_generic"); 32532969bf0eSJack F Vogel 3254c0014855SJack F Vogel /* clear the old state */ 3255c0014855SJack F Vogel links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); 3256c0014855SJack F Vogel 32572969bf0eSJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); 3258c0014855SJack F Vogel 3259c0014855SJack F Vogel if (links_orig != links_reg) { 3260c0014855SJack F Vogel DEBUGOUT2("LINKS changed from %08X to %08X\n", 3261c0014855SJack F Vogel links_orig, links_reg); 3262c0014855SJack F Vogel } 3263c0014855SJack F Vogel 32642969bf0eSJack F Vogel if (link_up_wait_to_complete) { 32652969bf0eSJack F Vogel for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { 32662969bf0eSJack F Vogel if (links_reg & IXGBE_LINKS_UP) { 32672969bf0eSJack F Vogel *link_up = TRUE; 32682969bf0eSJack F Vogel break; 32692969bf0eSJack F Vogel } else { 32702969bf0eSJack F Vogel *link_up = FALSE; 32712969bf0eSJack F Vogel } 32722969bf0eSJack F Vogel msec_delay(100); 32732969bf0eSJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); 32742969bf0eSJack F Vogel } 32752969bf0eSJack F Vogel } else { 32762969bf0eSJack F Vogel if (links_reg & IXGBE_LINKS_UP) 32772969bf0eSJack F Vogel *link_up = TRUE; 32782969bf0eSJack F Vogel else 32792969bf0eSJack F Vogel *link_up = FALSE; 32802969bf0eSJack F Vogel } 32812969bf0eSJack F Vogel 32822969bf0eSJack F Vogel if ((links_reg & IXGBE_LINKS_SPEED_82599) == 32832969bf0eSJack F Vogel IXGBE_LINKS_SPEED_10G_82599) 32842969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_10GB_FULL; 32852969bf0eSJack F Vogel else if ((links_reg & IXGBE_LINKS_SPEED_82599) == 32862969bf0eSJack F Vogel IXGBE_LINKS_SPEED_1G_82599) 32872969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_1GB_FULL; 3288*1a4e3449SJack F Vogel else if ((links_reg & IXGBE_LINKS_SPEED_82599) == 3289*1a4e3449SJack F Vogel IXGBE_LINKS_SPEED_100_82599) 32902969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_100_FULL; 3291*1a4e3449SJack F Vogel else 3292*1a4e3449SJack F Vogel *speed = IXGBE_LINK_SPEED_UNKNOWN; 32932969bf0eSJack F Vogel 32942969bf0eSJack F Vogel /* if link is down, zero out the current_mode */ 32952969bf0eSJack F Vogel if (*link_up == FALSE) { 32962969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_none; 32972969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 32982969bf0eSJack F Vogel } 32992969bf0eSJack F Vogel 33002969bf0eSJack F Vogel return IXGBE_SUCCESS; 33012969bf0eSJack F Vogel } 33022969bf0eSJack F Vogel 33032969bf0eSJack F Vogel /** 33042969bf0eSJack F Vogel * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from 33052969bf0eSJack F Vogel * the EEPROM 33062969bf0eSJack F Vogel * @hw: pointer to hardware structure 33072969bf0eSJack F Vogel * @wwnn_prefix: the alternative WWNN prefix 33082969bf0eSJack F Vogel * @wwpn_prefix: the alternative WWPN prefix 33092969bf0eSJack F Vogel * 33102969bf0eSJack F Vogel * This function will read the EEPROM from the alternative SAN MAC address 33112969bf0eSJack F Vogel * block to check the support for the alternative WWNN/WWPN prefix support. 33122969bf0eSJack F Vogel **/ 33132969bf0eSJack F Vogel s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, 33142969bf0eSJack F Vogel u16 *wwpn_prefix) 33152969bf0eSJack F Vogel { 33162969bf0eSJack F Vogel u16 offset, caps; 33172969bf0eSJack F Vogel u16 alt_san_mac_blk_offset; 33182969bf0eSJack F Vogel 33192969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_wwn_prefix_generic"); 33202969bf0eSJack F Vogel 33212969bf0eSJack F Vogel /* clear output first */ 33222969bf0eSJack F Vogel *wwnn_prefix = 0xFFFF; 33232969bf0eSJack F Vogel *wwpn_prefix = 0xFFFF; 33242969bf0eSJack F Vogel 33252969bf0eSJack F Vogel /* check if alternative SAN MAC is supported */ 33262969bf0eSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, 33272969bf0eSJack F Vogel &alt_san_mac_blk_offset); 33282969bf0eSJack F Vogel 33292969bf0eSJack F Vogel if ((alt_san_mac_blk_offset == 0) || 33302969bf0eSJack F Vogel (alt_san_mac_blk_offset == 0xFFFF)) 33312969bf0eSJack F Vogel goto wwn_prefix_out; 33322969bf0eSJack F Vogel 33332969bf0eSJack F Vogel /* check capability in alternative san mac address block */ 33342969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; 33352969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, &caps); 33362969bf0eSJack F Vogel if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) 33372969bf0eSJack F Vogel goto wwn_prefix_out; 33382969bf0eSJack F Vogel 33392969bf0eSJack F Vogel /* get the corresponding prefix for WWNN/WWPN */ 33402969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; 33412969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, wwnn_prefix); 33422969bf0eSJack F Vogel 33432969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; 33442969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, wwpn_prefix); 33452969bf0eSJack F Vogel 33462969bf0eSJack F Vogel wwn_prefix_out: 33472969bf0eSJack F Vogel return IXGBE_SUCCESS; 33482969bf0eSJack F Vogel } 3349*1a4e3449SJack F Vogel 3350*1a4e3449SJack F Vogel /** 3351*1a4e3449SJack F Vogel * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM 3352*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 3353*1a4e3449SJack F Vogel * @bs: the fcoe boot status 3354*1a4e3449SJack F Vogel * 3355*1a4e3449SJack F Vogel * This function will read the FCOE boot status from the iSCSI FCOE block 3356*1a4e3449SJack F Vogel **/ 3357*1a4e3449SJack F Vogel s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs) 3358*1a4e3449SJack F Vogel { 3359*1a4e3449SJack F Vogel u16 offset, caps, flags; 3360*1a4e3449SJack F Vogel s32 status; 3361*1a4e3449SJack F Vogel 3362*1a4e3449SJack F Vogel DEBUGFUNC("ixgbe_get_fcoe_boot_status_generic"); 3363*1a4e3449SJack F Vogel 3364*1a4e3449SJack F Vogel /* clear output first */ 3365*1a4e3449SJack F Vogel *bs = ixgbe_fcoe_bootstatus_unavailable; 3366*1a4e3449SJack F Vogel 3367*1a4e3449SJack F Vogel /* check if FCOE IBA block is present */ 3368*1a4e3449SJack F Vogel offset = IXGBE_FCOE_IBA_CAPS_BLK_PTR; 3369*1a4e3449SJack F Vogel status = hw->eeprom.ops.read(hw, offset, &caps); 3370*1a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) 3371*1a4e3449SJack F Vogel goto out; 3372*1a4e3449SJack F Vogel 3373*1a4e3449SJack F Vogel if (!(caps & IXGBE_FCOE_IBA_CAPS_FCOE)) 3374*1a4e3449SJack F Vogel goto out; 3375*1a4e3449SJack F Vogel 3376*1a4e3449SJack F Vogel /* check if iSCSI FCOE block is populated */ 3377*1a4e3449SJack F Vogel status = hw->eeprom.ops.read(hw, IXGBE_ISCSI_FCOE_BLK_PTR, &offset); 3378*1a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) 3379*1a4e3449SJack F Vogel goto out; 3380*1a4e3449SJack F Vogel 3381*1a4e3449SJack F Vogel if ((offset == 0) || (offset == 0xFFFF)) 3382*1a4e3449SJack F Vogel goto out; 3383*1a4e3449SJack F Vogel 3384*1a4e3449SJack F Vogel /* read fcoe flags in iSCSI FCOE block */ 3385*1a4e3449SJack F Vogel offset = offset + IXGBE_ISCSI_FCOE_FLAGS_OFFSET; 3386*1a4e3449SJack F Vogel status = hw->eeprom.ops.read(hw, offset, &flags); 3387*1a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) 3388*1a4e3449SJack F Vogel goto out; 3389*1a4e3449SJack F Vogel 3390*1a4e3449SJack F Vogel if (flags & IXGBE_ISCSI_FCOE_FLAGS_ENABLE) 3391*1a4e3449SJack F Vogel *bs = ixgbe_fcoe_bootstatus_enabled; 3392*1a4e3449SJack F Vogel else 3393*1a4e3449SJack F Vogel *bs = ixgbe_fcoe_bootstatus_disabled; 3394*1a4e3449SJack F Vogel 3395*1a4e3449SJack F Vogel out: 3396*1a4e3449SJack F Vogel return status; 3397*1a4e3449SJack F Vogel } 3398*1a4e3449SJack F Vogel 3399*1a4e3449SJack F Vogel /** 3400*1a4e3449SJack F Vogel * ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow 3401*1a4e3449SJack F Vogel * control 3402*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 3403*1a4e3449SJack F Vogel * 3404*1a4e3449SJack F Vogel * There are several phys that do not support autoneg flow control. This 3405*1a4e3449SJack F Vogel * function check the device id to see if the associated phy supports 3406*1a4e3449SJack F Vogel * autoneg flow control. 3407*1a4e3449SJack F Vogel **/ 3408*1a4e3449SJack F Vogel static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) 3409*1a4e3449SJack F Vogel { 3410*1a4e3449SJack F Vogel 3411*1a4e3449SJack F Vogel DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); 3412*1a4e3449SJack F Vogel 3413*1a4e3449SJack F Vogel switch (hw->device_id) { 3414*1a4e3449SJack F Vogel case IXGBE_DEV_ID_82599_T3_LOM: 3415*1a4e3449SJack F Vogel return IXGBE_SUCCESS; 3416*1a4e3449SJack F Vogel default: 3417*1a4e3449SJack F Vogel return IXGBE_ERR_FC_NOT_SUPPORTED; 3418*1a4e3449SJack F Vogel } 3419*1a4e3449SJack F Vogel } 3420*1a4e3449SJack F Vogel 3421*1a4e3449SJack F Vogel /** 3422*1a4e3449SJack F Vogel * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing 3423*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 3424*1a4e3449SJack F Vogel * @enable: enable or disable switch for anti-spoofing 3425*1a4e3449SJack F Vogel * @pf: Physical Function pool - do not enable anti-spoofing for the PF 3426*1a4e3449SJack F Vogel * 3427*1a4e3449SJack F Vogel **/ 3428*1a4e3449SJack F Vogel void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf) 3429*1a4e3449SJack F Vogel { 3430*1a4e3449SJack F Vogel int j; 3431*1a4e3449SJack F Vogel int pf_target_reg = pf >> 3; 3432*1a4e3449SJack F Vogel int pf_target_shift = pf % 8; 3433*1a4e3449SJack F Vogel u32 pfvfspoof = 0; 3434*1a4e3449SJack F Vogel 3435*1a4e3449SJack F Vogel if (hw->mac.type == ixgbe_mac_82598EB) 3436*1a4e3449SJack F Vogel return; 3437*1a4e3449SJack F Vogel 3438*1a4e3449SJack F Vogel if (enable) 3439*1a4e3449SJack F Vogel pfvfspoof = IXGBE_SPOOF_MACAS_MASK; 3440*1a4e3449SJack F Vogel 3441*1a4e3449SJack F Vogel /* 3442*1a4e3449SJack F Vogel * PFVFSPOOF register array is size 8 with 8 bits assigned to 3443*1a4e3449SJack F Vogel * MAC anti-spoof enables in each register array element. 3444*1a4e3449SJack F Vogel */ 3445*1a4e3449SJack F Vogel for (j = 0; j < IXGBE_PFVFSPOOF_REG_COUNT; j++) 3446*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); 3447*1a4e3449SJack F Vogel 3448*1a4e3449SJack F Vogel /* If not enabling anti-spoofing then done */ 3449*1a4e3449SJack F Vogel if (!enable) 3450*1a4e3449SJack F Vogel return; 3451*1a4e3449SJack F Vogel 3452*1a4e3449SJack F Vogel /* 3453*1a4e3449SJack F Vogel * The PF should be allowed to spoof so that it can support 3454*1a4e3449SJack F Vogel * emulation mode NICs. Reset the bit assigned to the PF 3455*1a4e3449SJack F Vogel */ 3456*1a4e3449SJack F Vogel pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg)); 3457*1a4e3449SJack F Vogel pfvfspoof ^= (1 << pf_target_shift); 3458*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg), pfvfspoof); 3459*1a4e3449SJack F Vogel } 3460*1a4e3449SJack F Vogel 3461*1a4e3449SJack F Vogel /** 3462*1a4e3449SJack F Vogel * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing 3463*1a4e3449SJack F Vogel * @hw: pointer to hardware structure 3464*1a4e3449SJack F Vogel * @enable: enable or disable switch for VLAN anti-spoofing 3465*1a4e3449SJack F Vogel * @pf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing 3466*1a4e3449SJack F Vogel * 3467*1a4e3449SJack F Vogel **/ 3468*1a4e3449SJack F Vogel void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) 3469*1a4e3449SJack F Vogel { 3470*1a4e3449SJack F Vogel int vf_target_reg = vf >> 3; 3471*1a4e3449SJack F Vogel int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT; 3472*1a4e3449SJack F Vogel u32 pfvfspoof; 3473*1a4e3449SJack F Vogel 3474*1a4e3449SJack F Vogel if (hw->mac.type == ixgbe_mac_82598EB) 3475*1a4e3449SJack F Vogel return; 3476*1a4e3449SJack F Vogel 3477*1a4e3449SJack F Vogel pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); 3478*1a4e3449SJack F Vogel if (enable) 3479*1a4e3449SJack F Vogel pfvfspoof |= (1 << vf_target_shift); 3480*1a4e3449SJack F Vogel else 3481*1a4e3449SJack F Vogel pfvfspoof &= ~(1 << vf_target_shift); 3482*1a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); 3483*1a4e3449SJack F Vogel } 3484