19ca4041bSJack F Vogel /****************************************************************************** 213705f88SJack F Vogel 3*85d0a26eSJack F Vogel Copyright (c) 2001-2012, 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" 361a4e3449SJack 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); 541a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw); 551a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw); 561a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw); 571a4e3449SJack F Vogel static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); 581a4e3449SJack F Vogel static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, 591a4e3449SJack F Vogel u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); 60*85d0a26eSJack F Vogel static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); 61*85d0a26eSJack F Vogel static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, 62*85d0a26eSJack F Vogel u16 words, u16 *data); 63*85d0a26eSJack F Vogel static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, 64*85d0a26eSJack F Vogel u16 words, u16 *data); 65*85d0a26eSJack F Vogel static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw, 66*85d0a26eSJack F Vogel u16 offset); 6713705f88SJack F Vogel 6813705f88SJack F Vogel /** 699ca4041bSJack F Vogel * ixgbe_init_ops_generic - Inits function ptrs 709ca4041bSJack F Vogel * @hw: pointer to the hardware structure 7113705f88SJack F Vogel * 729ca4041bSJack F Vogel * Initialize the function pointers. 7313705f88SJack F Vogel **/ 749ca4041bSJack F Vogel s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) 7513705f88SJack F Vogel { 769ca4041bSJack F Vogel struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 779ca4041bSJack F Vogel struct ixgbe_mac_info *mac = &hw->mac; 789ca4041bSJack F Vogel u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC); 7913705f88SJack F Vogel 802969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_ops_generic"); 812969bf0eSJack F Vogel 8213705f88SJack F Vogel /* EEPROM */ 839ca4041bSJack F Vogel eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic; 849ca4041bSJack F Vogel /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */ 85*85d0a26eSJack F Vogel if (eec & IXGBE_EEC_PRES) { 862969bf0eSJack F Vogel eeprom->ops.read = &ixgbe_read_eerd_generic; 87*85d0a26eSJack F Vogel eeprom->ops.read_buffer = &ixgbe_read_eerd_buffer_generic; 88*85d0a26eSJack F Vogel } else { 899ca4041bSJack F Vogel eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic; 90*85d0a26eSJack F Vogel eeprom->ops.read_buffer = 91*85d0a26eSJack F Vogel &ixgbe_read_eeprom_buffer_bit_bang_generic; 92*85d0a26eSJack F Vogel } 939ca4041bSJack F Vogel eeprom->ops.write = &ixgbe_write_eeprom_generic; 94*85d0a26eSJack F Vogel eeprom->ops.write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic; 959ca4041bSJack F Vogel eeprom->ops.validate_checksum = 9613705f88SJack F Vogel &ixgbe_validate_eeprom_checksum_generic; 979ca4041bSJack F Vogel eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic; 982969bf0eSJack F Vogel eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_generic; 999ca4041bSJack F Vogel 1009ca4041bSJack F Vogel /* MAC */ 1019ca4041bSJack F Vogel mac->ops.init_hw = &ixgbe_init_hw_generic; 1029ca4041bSJack F Vogel mac->ops.reset_hw = NULL; 1039ca4041bSJack F Vogel mac->ops.start_hw = &ixgbe_start_hw_generic; 1049ca4041bSJack F Vogel mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic; 1059ca4041bSJack F Vogel mac->ops.get_media_type = NULL; 1061b6e0dbaSJack F Vogel mac->ops.get_supported_physical_layer = NULL; 1070ac6dfecSJack F Vogel mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic; 1089ca4041bSJack F Vogel mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic; 1099ca4041bSJack F Vogel mac->ops.stop_adapter = &ixgbe_stop_adapter_generic; 1109ca4041bSJack F Vogel mac->ops.get_bus_info = &ixgbe_get_bus_info_generic; 1111b6e0dbaSJack F Vogel mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie; 112d8602bb9SJack F Vogel mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync; 113d8602bb9SJack F Vogel mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync; 1149ca4041bSJack F Vogel 1159ca4041bSJack F Vogel /* LEDs */ 1169ca4041bSJack F Vogel mac->ops.led_on = &ixgbe_led_on_generic; 1179ca4041bSJack F Vogel mac->ops.led_off = &ixgbe_led_off_generic; 1180ac6dfecSJack F Vogel mac->ops.blink_led_start = &ixgbe_blink_led_start_generic; 1190ac6dfecSJack F Vogel mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic; 1209ca4041bSJack F Vogel 12113705f88SJack F Vogel /* RAR, Multicast, VLAN */ 1229ca4041bSJack F Vogel mac->ops.set_rar = &ixgbe_set_rar_generic; 1235b7f4cedSJack F Vogel mac->ops.clear_rar = &ixgbe_clear_rar_generic; 1240ac6dfecSJack F Vogel mac->ops.insert_mac_addr = NULL; 1259ca4041bSJack F Vogel mac->ops.set_vmdq = NULL; 1265b7f4cedSJack F Vogel mac->ops.clear_vmdq = NULL; 1279ca4041bSJack F Vogel mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic; 1289ca4041bSJack F Vogel mac->ops.update_uc_addr_list = &ixgbe_update_uc_addr_list_generic; 1299ca4041bSJack F Vogel mac->ops.update_mc_addr_list = &ixgbe_update_mc_addr_list_generic; 1309ca4041bSJack F Vogel mac->ops.enable_mc = &ixgbe_enable_mc_generic; 1319ca4041bSJack F Vogel mac->ops.disable_mc = &ixgbe_disable_mc_generic; 1325b7f4cedSJack F Vogel mac->ops.clear_vfta = NULL; 1335b7f4cedSJack F Vogel mac->ops.set_vfta = NULL; 134*85d0a26eSJack F Vogel mac->ops.set_vlvf = NULL; 1355b7f4cedSJack F Vogel mac->ops.init_uta_tables = NULL; 1369ca4041bSJack F Vogel 1370ac6dfecSJack F Vogel /* Flow Control */ 1380ac6dfecSJack F Vogel mac->ops.fc_enable = &ixgbe_fc_enable_generic; 1399ca4041bSJack F Vogel 1409ca4041bSJack F Vogel /* Link */ 1419ca4041bSJack F Vogel mac->ops.get_link_capabilities = NULL; 1429ca4041bSJack F Vogel mac->ops.setup_link = NULL; 1439ca4041bSJack F Vogel mac->ops.check_link = NULL; 14413705f88SJack F Vogel 14513705f88SJack F Vogel return IXGBE_SUCCESS; 14613705f88SJack F Vogel } 14713705f88SJack F Vogel 14813705f88SJack F Vogel /** 1499ca4041bSJack F Vogel * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx 15013705f88SJack F Vogel * @hw: pointer to hardware structure 15113705f88SJack F Vogel * 15213705f88SJack F Vogel * Starts the hardware by filling the bus info structure and media type, clears 15313705f88SJack F Vogel * all on chip counters, initializes receive address registers, multicast 15413705f88SJack F Vogel * table, VLAN filter table, calls routine to set up link and flow control 15513705f88SJack F Vogel * settings, and leaves transmit and receive units disabled and uninitialized 15613705f88SJack F Vogel **/ 15713705f88SJack F Vogel s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) 15813705f88SJack F Vogel { 15913705f88SJack F Vogel u32 ctrl_ext; 16013705f88SJack F Vogel 1612969bf0eSJack F Vogel DEBUGFUNC("ixgbe_start_hw_generic"); 1622969bf0eSJack F Vogel 16313705f88SJack F Vogel /* Set the media type */ 1649ca4041bSJack F Vogel hw->phy.media_type = hw->mac.ops.get_media_type(hw); 16513705f88SJack F Vogel 1660ac6dfecSJack F Vogel /* PHY ops initialization must be done in reset_hw() */ 16713705f88SJack F Vogel 16813705f88SJack F Vogel /* Clear the VLAN filter table */ 1699ca4041bSJack F Vogel hw->mac.ops.clear_vfta(hw); 17013705f88SJack F Vogel 17113705f88SJack F Vogel /* Clear statistics registers */ 1729ca4041bSJack F Vogel hw->mac.ops.clear_hw_cntrs(hw); 17313705f88SJack F Vogel 17413705f88SJack F Vogel /* Set No Snoop Disable */ 17513705f88SJack F Vogel ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); 17613705f88SJack F Vogel ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; 17713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); 1789ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 17913705f88SJack F Vogel 1800ac6dfecSJack F Vogel /* Setup flow control */ 1810ac6dfecSJack F Vogel ixgbe_setup_fc(hw, 0); 1820ac6dfecSJack F Vogel 18313705f88SJack F Vogel /* Clear adapter stopped flag */ 18413705f88SJack F Vogel hw->adapter_stopped = FALSE; 18513705f88SJack F Vogel 1861a4e3449SJack F Vogel return IXGBE_SUCCESS; 1871a4e3449SJack F Vogel } 1881a4e3449SJack F Vogel 1891a4e3449SJack F Vogel /** 1901a4e3449SJack F Vogel * ixgbe_start_hw_gen2 - Init sequence for common device family 1911a4e3449SJack F Vogel * @hw: pointer to hw structure 1921a4e3449SJack F Vogel * 1931a4e3449SJack F Vogel * Performs the init sequence common to the second generation 1941a4e3449SJack F Vogel * of 10 GbE devices. 1951a4e3449SJack F Vogel * Devices in the second generation: 1961a4e3449SJack F Vogel * 82599 197182b3808SJack F Vogel * X540 1981a4e3449SJack F Vogel **/ 1991a4e3449SJack F Vogel s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) 2001a4e3449SJack F Vogel { 2011a4e3449SJack F Vogel u32 i; 2021a4e3449SJack F Vogel u32 regval; 2031a4e3449SJack F Vogel 2041a4e3449SJack F Vogel /* Clear the rate limiters */ 2051a4e3449SJack F Vogel for (i = 0; i < hw->mac.max_tx_queues; i++) { 2061a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i); 2071a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0); 2081a4e3449SJack F Vogel } 2091a4e3449SJack F Vogel IXGBE_WRITE_FLUSH(hw); 2101a4e3449SJack F Vogel 2111a4e3449SJack F Vogel /* Disable relaxed ordering */ 2121a4e3449SJack F Vogel for (i = 0; i < hw->mac.max_tx_queues; i++) { 2131a4e3449SJack F Vogel regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); 2141a4e3449SJack F Vogel regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; 2151a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); 2161a4e3449SJack F Vogel } 2171a4e3449SJack F Vogel 2181a4e3449SJack F Vogel for (i = 0; i < hw->mac.max_rx_queues; i++) { 2191a4e3449SJack F Vogel regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); 2201a4e3449SJack F Vogel regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | 2211a4e3449SJack F Vogel IXGBE_DCA_RXCTRL_DESC_HSRO_EN); 2221a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); 2231a4e3449SJack F Vogel } 2241a4e3449SJack F Vogel 2251a4e3449SJack F Vogel return IXGBE_SUCCESS; 22613705f88SJack F Vogel } 22713705f88SJack F Vogel 22813705f88SJack F Vogel /** 22913705f88SJack F Vogel * ixgbe_init_hw_generic - Generic hardware initialization 23013705f88SJack F Vogel * @hw: pointer to hardware structure 23113705f88SJack F Vogel * 2329ca4041bSJack F Vogel * Initialize the hardware by resetting the hardware, filling the bus info 23313705f88SJack F Vogel * structure and media type, clears all on chip counters, initializes receive 23413705f88SJack F Vogel * address registers, multicast table, VLAN filter table, calls routine to set 23513705f88SJack F Vogel * up link and flow control settings, and leaves transmit and receive units 23613705f88SJack F Vogel * disabled and uninitialized 23713705f88SJack F Vogel **/ 23813705f88SJack F Vogel s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) 23913705f88SJack F Vogel { 2401a4e3449SJack F Vogel s32 status; 2410ac6dfecSJack F Vogel 2422969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_hw_generic"); 2432969bf0eSJack F Vogel 24413705f88SJack F Vogel /* Reset the hardware */ 2450ac6dfecSJack F Vogel status = hw->mac.ops.reset_hw(hw); 24613705f88SJack F Vogel 2470ac6dfecSJack F Vogel if (status == IXGBE_SUCCESS) { 24813705f88SJack F Vogel /* Start the HW */ 2490ac6dfecSJack F Vogel status = hw->mac.ops.start_hw(hw); 2500ac6dfecSJack F Vogel } 25113705f88SJack F Vogel 2520ac6dfecSJack F Vogel return status; 25313705f88SJack F Vogel } 25413705f88SJack F Vogel 25513705f88SJack F Vogel /** 25613705f88SJack F Vogel * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters 25713705f88SJack F Vogel * @hw: pointer to hardware structure 25813705f88SJack F Vogel * 25913705f88SJack F Vogel * Clears all hardware statistics counters by reading them from the hardware 26013705f88SJack F Vogel * Statistics counters are clear on read. 26113705f88SJack F Vogel **/ 26213705f88SJack F Vogel s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) 26313705f88SJack F Vogel { 26413705f88SJack F Vogel u16 i = 0; 26513705f88SJack F Vogel 2662969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_hw_cntrs_generic"); 2672969bf0eSJack F Vogel 26813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_CRCERRS); 26913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ILLERRC); 27013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ERRBC); 27113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MSPDC); 27213705f88SJack F Vogel for (i = 0; i < 8; i++) 27313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPC(i)); 27413705f88SJack F Vogel 27513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MLFC); 27613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MRFC); 27713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RLEC); 27813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONTXC); 27913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); 2800ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 2810ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); 2820ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); 2830ac6dfecSJack F Vogel } else { 2841b6e0dbaSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONRXC); 28513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); 2860ac6dfecSJack F Vogel } 28713705f88SJack F Vogel 28813705f88SJack F Vogel for (i = 0; i < 8; i++) { 28913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); 29013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); 2910ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 2920ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); 2930ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); 2940ac6dfecSJack F Vogel } else { 2951b6e0dbaSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); 29613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); 29713705f88SJack F Vogel } 2980ac6dfecSJack F Vogel } 2990ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) 3000ac6dfecSJack F Vogel for (i = 0; i < 8; i++) 3010ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); 30213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC64); 30313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC127); 30413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC255); 30513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC511); 30613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1023); 30713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1522); 30813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPRC); 30913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPRC); 31013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPRC); 31113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPTC); 31213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCL); 31313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCH); 31413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCL); 31513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCH); 316*85d0a26eSJack F Vogel if (hw->mac.type == ixgbe_mac_82598EB) 31713705f88SJack F Vogel for (i = 0; i < 8; i++) 31813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RNBC(i)); 31913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RUC); 32013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RFC); 32113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ROC); 32213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RJC); 32313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPRC); 32413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPDC); 32513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPTC); 32613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORL); 32713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORH); 32813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPR); 32913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPT); 33013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC64); 33113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC127); 33213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC255); 33313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC511); 33413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1023); 33513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1522); 33613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPTC); 33713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPTC); 33813705f88SJack F Vogel for (i = 0; i < 16; i++) { 33913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPRC(i)); 34013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPTC(i)); 3411a4e3449SJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 3421a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); 3431a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); 3441a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); 3451a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); 3461a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); 3471a4e3449SJack F Vogel } else { 3481a4e3449SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC(i)); 34913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC(i)); 35013705f88SJack F Vogel } 3511a4e3449SJack F Vogel } 3521a4e3449SJack F Vogel 353*85d0a26eSJack F Vogel if (hw->mac.type == ixgbe_mac_X540) { 354*85d0a26eSJack F Vogel if (hw->phy.id == 0) 355*85d0a26eSJack F Vogel ixgbe_identify_phy(hw); 356*85d0a26eSJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL, 357*85d0a26eSJack F Vogel IXGBE_MDIO_PCS_DEV_TYPE, &i); 358*85d0a26eSJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECH, 359*85d0a26eSJack F Vogel IXGBE_MDIO_PCS_DEV_TYPE, &i); 360*85d0a26eSJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_LDPCECL, 361*85d0a26eSJack F Vogel IXGBE_MDIO_PCS_DEV_TYPE, &i); 362*85d0a26eSJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_LDPCECH, 363*85d0a26eSJack F Vogel IXGBE_MDIO_PCS_DEV_TYPE, &i); 364*85d0a26eSJack F Vogel } 365*85d0a26eSJack F Vogel 3661a4e3449SJack F Vogel return IXGBE_SUCCESS; 3671a4e3449SJack F Vogel } 3681a4e3449SJack F Vogel 3691a4e3449SJack F Vogel /** 3701a4e3449SJack F Vogel * ixgbe_read_pba_string_generic - Reads part number string from EEPROM 3711a4e3449SJack F Vogel * @hw: pointer to hardware structure 3721a4e3449SJack F Vogel * @pba_num: stores the part number string from the EEPROM 3731a4e3449SJack F Vogel * @pba_num_size: part number string buffer length 3741a4e3449SJack F Vogel * 3751a4e3449SJack F Vogel * Reads the part number string from the EEPROM. 3761a4e3449SJack F Vogel **/ 3771a4e3449SJack F Vogel s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, 3781a4e3449SJack F Vogel u32 pba_num_size) 3791a4e3449SJack F Vogel { 3801a4e3449SJack F Vogel s32 ret_val; 3811a4e3449SJack F Vogel u16 data; 3821a4e3449SJack F Vogel u16 pba_ptr; 3831a4e3449SJack F Vogel u16 offset; 3841a4e3449SJack F Vogel u16 length; 3851a4e3449SJack F Vogel 3861a4e3449SJack F Vogel DEBUGFUNC("ixgbe_read_pba_string_generic"); 3871a4e3449SJack F Vogel 3881a4e3449SJack F Vogel if (pba_num == NULL) { 3891a4e3449SJack F Vogel DEBUGOUT("PBA string buffer was null\n"); 3901a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 3911a4e3449SJack F Vogel } 3921a4e3449SJack F Vogel 3931a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); 3941a4e3449SJack F Vogel if (ret_val) { 3951a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 3961a4e3449SJack F Vogel return ret_val; 3971a4e3449SJack F Vogel } 3981a4e3449SJack F Vogel 3991a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &pba_ptr); 4001a4e3449SJack F Vogel if (ret_val) { 4011a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 4021a4e3449SJack F Vogel return ret_val; 4031a4e3449SJack F Vogel } 4041a4e3449SJack F Vogel 4051a4e3449SJack F Vogel /* 4061a4e3449SJack F Vogel * if data is not ptr guard the PBA must be in legacy format which 4071a4e3449SJack F Vogel * means pba_ptr is actually our second data word for the PBA number 4081a4e3449SJack F Vogel * and we can decode it into an ascii string 4091a4e3449SJack F Vogel */ 4101a4e3449SJack F Vogel if (data != IXGBE_PBANUM_PTR_GUARD) { 4111a4e3449SJack F Vogel DEBUGOUT("NVM PBA number is not stored as string\n"); 4121a4e3449SJack F Vogel 4131a4e3449SJack F Vogel /* we will need 11 characters to store the PBA */ 4141a4e3449SJack F Vogel if (pba_num_size < 11) { 4151a4e3449SJack F Vogel DEBUGOUT("PBA string buffer too small\n"); 4161a4e3449SJack F Vogel return IXGBE_ERR_NO_SPACE; 4171a4e3449SJack F Vogel } 4181a4e3449SJack F Vogel 4191a4e3449SJack F Vogel /* extract hex string from data and pba_ptr */ 4201a4e3449SJack F Vogel pba_num[0] = (data >> 12) & 0xF; 4211a4e3449SJack F Vogel pba_num[1] = (data >> 8) & 0xF; 4221a4e3449SJack F Vogel pba_num[2] = (data >> 4) & 0xF; 4231a4e3449SJack F Vogel pba_num[3] = data & 0xF; 4241a4e3449SJack F Vogel pba_num[4] = (pba_ptr >> 12) & 0xF; 4251a4e3449SJack F Vogel pba_num[5] = (pba_ptr >> 8) & 0xF; 4261a4e3449SJack F Vogel pba_num[6] = '-'; 4271a4e3449SJack F Vogel pba_num[7] = 0; 4281a4e3449SJack F Vogel pba_num[8] = (pba_ptr >> 4) & 0xF; 4291a4e3449SJack F Vogel pba_num[9] = pba_ptr & 0xF; 4301a4e3449SJack F Vogel 4311a4e3449SJack F Vogel /* put a null character on the end of our string */ 4321a4e3449SJack F Vogel pba_num[10] = '\0'; 4331a4e3449SJack F Vogel 4341a4e3449SJack F Vogel /* switch all the data but the '-' to hex char */ 4351a4e3449SJack F Vogel for (offset = 0; offset < 10; offset++) { 4361a4e3449SJack F Vogel if (pba_num[offset] < 0xA) 4371a4e3449SJack F Vogel pba_num[offset] += '0'; 4381a4e3449SJack F Vogel else if (pba_num[offset] < 0x10) 4391a4e3449SJack F Vogel pba_num[offset] += 'A' - 0xA; 4401a4e3449SJack F Vogel } 4411a4e3449SJack F Vogel 4421a4e3449SJack F Vogel return IXGBE_SUCCESS; 4431a4e3449SJack F Vogel } 4441a4e3449SJack F Vogel 4451a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, pba_ptr, &length); 4461a4e3449SJack F Vogel if (ret_val) { 4471a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 4481a4e3449SJack F Vogel return ret_val; 4491a4e3449SJack F Vogel } 4501a4e3449SJack F Vogel 4511a4e3449SJack F Vogel if (length == 0xFFFF || length == 0) { 4521a4e3449SJack F Vogel DEBUGOUT("NVM PBA number section invalid length\n"); 4531a4e3449SJack F Vogel return IXGBE_ERR_PBA_SECTION; 4541a4e3449SJack F Vogel } 4551a4e3449SJack F Vogel 4561a4e3449SJack F Vogel /* check if pba_num buffer is big enough */ 4571a4e3449SJack F Vogel if (pba_num_size < (((u32)length * 2) - 1)) { 4581a4e3449SJack F Vogel DEBUGOUT("PBA string buffer too small\n"); 4591a4e3449SJack F Vogel return IXGBE_ERR_NO_SPACE; 4601a4e3449SJack F Vogel } 4611a4e3449SJack F Vogel 4621a4e3449SJack F Vogel /* trim pba length from start of string */ 4631a4e3449SJack F Vogel pba_ptr++; 4641a4e3449SJack F Vogel length--; 4651a4e3449SJack F Vogel 4661a4e3449SJack F Vogel for (offset = 0; offset < length; offset++) { 4671a4e3449SJack F Vogel ret_val = hw->eeprom.ops.read(hw, pba_ptr + offset, &data); 4681a4e3449SJack F Vogel if (ret_val) { 4691a4e3449SJack F Vogel DEBUGOUT("NVM Read Error\n"); 4701a4e3449SJack F Vogel return ret_val; 4711a4e3449SJack F Vogel } 4721a4e3449SJack F Vogel pba_num[offset * 2] = (u8)(data >> 8); 4731a4e3449SJack F Vogel pba_num[(offset * 2) + 1] = (u8)(data & 0xFF); 4741a4e3449SJack F Vogel } 4751a4e3449SJack F Vogel pba_num[offset * 2] = '\0'; 4761a4e3449SJack F Vogel 4771a4e3449SJack F Vogel return IXGBE_SUCCESS; 4781a4e3449SJack F Vogel } 4791a4e3449SJack F Vogel 4801a4e3449SJack F Vogel /** 4811b6e0dbaSJack F Vogel * ixgbe_read_pba_num_generic - Reads part number from EEPROM 4829ca4041bSJack F Vogel * @hw: pointer to hardware structure 4839ca4041bSJack F Vogel * @pba_num: stores the part number from the EEPROM 4849ca4041bSJack F Vogel * 4859ca4041bSJack F Vogel * Reads the part number from the EEPROM. 4869ca4041bSJack F Vogel **/ 4879ca4041bSJack F Vogel s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) 4889ca4041bSJack F Vogel { 4899ca4041bSJack F Vogel s32 ret_val; 4909ca4041bSJack F Vogel u16 data; 4919ca4041bSJack F Vogel 4929ca4041bSJack F Vogel DEBUGFUNC("ixgbe_read_pba_num_generic"); 4939ca4041bSJack F Vogel 4949ca4041bSJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); 4959ca4041bSJack F Vogel if (ret_val) { 4969ca4041bSJack F Vogel DEBUGOUT("NVM Read Error\n"); 4979ca4041bSJack F Vogel return ret_val; 4981a4e3449SJack F Vogel } else if (data == IXGBE_PBANUM_PTR_GUARD) { 4991a4e3449SJack F Vogel DEBUGOUT("NVM Not supported\n"); 5001a4e3449SJack F Vogel return IXGBE_NOT_IMPLEMENTED; 5019ca4041bSJack F Vogel } 5029ca4041bSJack F Vogel *pba_num = (u32)(data << 16); 5039ca4041bSJack F Vogel 5049ca4041bSJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data); 5059ca4041bSJack F Vogel if (ret_val) { 5069ca4041bSJack F Vogel DEBUGOUT("NVM Read Error\n"); 5079ca4041bSJack F Vogel return ret_val; 5089ca4041bSJack F Vogel } 5099ca4041bSJack F Vogel *pba_num |= data; 5109ca4041bSJack F Vogel 5119ca4041bSJack F Vogel return IXGBE_SUCCESS; 5129ca4041bSJack F Vogel } 5139ca4041bSJack F Vogel 5149ca4041bSJack F Vogel /** 51513705f88SJack F Vogel * ixgbe_get_mac_addr_generic - Generic get MAC address 51613705f88SJack F Vogel * @hw: pointer to hardware structure 51713705f88SJack F Vogel * @mac_addr: Adapter MAC address 51813705f88SJack F Vogel * 51913705f88SJack F Vogel * Reads the adapter's MAC address from first Receive Address Register (RAR0) 52013705f88SJack F Vogel * A reset of the adapter must be performed prior to calling this function 52113705f88SJack F Vogel * in order for the MAC address to have been loaded from the EEPROM into RAR0 52213705f88SJack F Vogel **/ 52313705f88SJack F Vogel s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) 52413705f88SJack F Vogel { 52513705f88SJack F Vogel u32 rar_high; 52613705f88SJack F Vogel u32 rar_low; 52713705f88SJack F Vogel u16 i; 52813705f88SJack F Vogel 5292969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_mac_addr_generic"); 5302969bf0eSJack F Vogel 53113705f88SJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0)); 53213705f88SJack F Vogel rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0)); 53313705f88SJack F Vogel 53413705f88SJack F Vogel for (i = 0; i < 4; i++) 53513705f88SJack F Vogel mac_addr[i] = (u8)(rar_low >> (i*8)); 53613705f88SJack F Vogel 53713705f88SJack F Vogel for (i = 0; i < 2; i++) 53813705f88SJack F Vogel mac_addr[i+4] = (u8)(rar_high >> (i*8)); 53913705f88SJack F Vogel 54013705f88SJack F Vogel return IXGBE_SUCCESS; 54113705f88SJack F Vogel } 54213705f88SJack F Vogel 54313705f88SJack F Vogel /** 54413705f88SJack F Vogel * ixgbe_get_bus_info_generic - Generic set PCI bus info 54513705f88SJack F Vogel * @hw: pointer to hardware structure 54613705f88SJack F Vogel * 54713705f88SJack F Vogel * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure 54813705f88SJack F Vogel **/ 54913705f88SJack F Vogel s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) 55013705f88SJack F Vogel { 5511b6e0dbaSJack F Vogel struct ixgbe_mac_info *mac = &hw->mac; 55213705f88SJack F Vogel u16 link_status; 55313705f88SJack F Vogel 5542969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_bus_info_generic"); 5552969bf0eSJack F Vogel 55613705f88SJack F Vogel hw->bus.type = ixgbe_bus_type_pci_express; 55713705f88SJack F Vogel 55813705f88SJack F Vogel /* Get the negotiated link width and speed from PCI config space */ 55913705f88SJack F Vogel link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); 56013705f88SJack F Vogel 56113705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_WIDTH) { 56213705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_1: 56313705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x1; 56413705f88SJack F Vogel break; 56513705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_2: 56613705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x2; 56713705f88SJack F Vogel break; 56813705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_4: 56913705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x4; 57013705f88SJack F Vogel break; 57113705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_8: 57213705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x8; 57313705f88SJack F Vogel break; 57413705f88SJack F Vogel default: 57513705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_unknown; 57613705f88SJack F Vogel break; 57713705f88SJack F Vogel } 57813705f88SJack F Vogel 57913705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_SPEED) { 58013705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_2500: 58113705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_2500; 58213705f88SJack F Vogel break; 58313705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_5000: 58413705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_5000; 58513705f88SJack F Vogel break; 58613705f88SJack F Vogel default: 58713705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_unknown; 58813705f88SJack F Vogel break; 58913705f88SJack F Vogel } 59013705f88SJack F Vogel 5911b6e0dbaSJack F Vogel mac->ops.set_lan_id(hw); 5921b6e0dbaSJack F Vogel 59313705f88SJack F Vogel return IXGBE_SUCCESS; 59413705f88SJack F Vogel } 59513705f88SJack F Vogel 59613705f88SJack F Vogel /** 5971b6e0dbaSJack F Vogel * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices 5981b6e0dbaSJack F Vogel * @hw: pointer to the HW structure 5991b6e0dbaSJack F Vogel * 6001b6e0dbaSJack F Vogel * Determines the LAN function id by reading memory-mapped registers 6011b6e0dbaSJack F Vogel * and swaps the port value if requested. 6021b6e0dbaSJack F Vogel **/ 6031b6e0dbaSJack F Vogel void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) 6041b6e0dbaSJack F Vogel { 6051b6e0dbaSJack F Vogel struct ixgbe_bus_info *bus = &hw->bus; 6061b6e0dbaSJack F Vogel u32 reg; 6071b6e0dbaSJack F Vogel 6082969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); 6092969bf0eSJack F Vogel 6101b6e0dbaSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_STATUS); 6111b6e0dbaSJack F Vogel bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; 6120ac6dfecSJack F Vogel bus->lan_id = bus->func; 6131b6e0dbaSJack F Vogel 6141b6e0dbaSJack F Vogel /* check for a port swap */ 6151b6e0dbaSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_FACTPS); 6161b6e0dbaSJack F Vogel if (reg & IXGBE_FACTPS_LFS) 6171b6e0dbaSJack F Vogel bus->func ^= 0x1; 6181b6e0dbaSJack F Vogel } 6191b6e0dbaSJack F Vogel 6201b6e0dbaSJack F Vogel /** 6219ca4041bSJack F Vogel * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units 62213705f88SJack F Vogel * @hw: pointer to hardware structure 62313705f88SJack F Vogel * 62413705f88SJack F Vogel * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, 62513705f88SJack F Vogel * disables transmit and receive units. The adapter_stopped flag is used by 62613705f88SJack F Vogel * the shared code and drivers to determine if the adapter is in a stopped 62713705f88SJack F Vogel * state and should not touch the hardware. 62813705f88SJack F Vogel **/ 62913705f88SJack F Vogel s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) 63013705f88SJack F Vogel { 63113705f88SJack F Vogel u32 reg_val; 63213705f88SJack F Vogel u16 i; 63313705f88SJack F Vogel 6342969bf0eSJack F Vogel DEBUGFUNC("ixgbe_stop_adapter_generic"); 6352969bf0eSJack F Vogel 63613705f88SJack F Vogel /* 63713705f88SJack F Vogel * Set the adapter_stopped flag so other driver functions stop touching 63813705f88SJack F Vogel * the hardware 63913705f88SJack F Vogel */ 64013705f88SJack F Vogel hw->adapter_stopped = TRUE; 64113705f88SJack F Vogel 64213705f88SJack F Vogel /* Disable the receive unit */ 643*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, 0); 64413705f88SJack F Vogel 645*85d0a26eSJack F Vogel /* Clear interrupt mask to stop interrupts from being generated */ 64613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); 64713705f88SJack F Vogel 648*85d0a26eSJack F Vogel /* Clear any pending interrupts, flush previous writes */ 64913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_EICR); 65013705f88SJack F Vogel 65113705f88SJack F Vogel /* Disable the transmit unit. Each queue must be disabled. */ 652*85d0a26eSJack F Vogel for (i = 0; i < hw->mac.max_tx_queues; i++) 653*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), IXGBE_TXDCTL_SWFLSH); 654*85d0a26eSJack F Vogel 655*85d0a26eSJack F Vogel /* Disable the receive unit by stopping each queue */ 656*85d0a26eSJack F Vogel for (i = 0; i < hw->mac.max_rx_queues; i++) { 657*85d0a26eSJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); 658*85d0a26eSJack F Vogel reg_val &= ~IXGBE_RXDCTL_ENABLE; 659*85d0a26eSJack F Vogel reg_val |= IXGBE_RXDCTL_SWFLSH; 660*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val); 66113705f88SJack F Vogel } 662*85d0a26eSJack F Vogel 663*85d0a26eSJack F Vogel /* flush all queues disables */ 664*85d0a26eSJack F Vogel IXGBE_WRITE_FLUSH(hw); 665*85d0a26eSJack F Vogel msec_delay(2); 66613705f88SJack F Vogel 6679ca4041bSJack F Vogel /* 6689ca4041bSJack F Vogel * Prevent the PCI-E bus from from hanging by disabling PCI-E master 6699ca4041bSJack F Vogel * access and verify no pending requests 6709ca4041bSJack F Vogel */ 671*85d0a26eSJack F Vogel return ixgbe_disable_pcie_master(hw); 67213705f88SJack F Vogel } 67313705f88SJack F Vogel 67413705f88SJack F Vogel /** 67513705f88SJack F Vogel * ixgbe_led_on_generic - Turns on the software controllable LEDs. 67613705f88SJack F Vogel * @hw: pointer to hardware structure 67713705f88SJack F Vogel * @index: led number to turn on 67813705f88SJack F Vogel **/ 67913705f88SJack F Vogel s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) 68013705f88SJack F Vogel { 68113705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 68213705f88SJack F Vogel 6832969bf0eSJack F Vogel DEBUGFUNC("ixgbe_led_on_generic"); 6842969bf0eSJack F Vogel 68513705f88SJack F Vogel /* To turn on the LED, set mode to ON. */ 68613705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 68713705f88SJack F Vogel led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); 68813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 6899ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 69013705f88SJack F Vogel 69113705f88SJack F Vogel return IXGBE_SUCCESS; 69213705f88SJack F Vogel } 69313705f88SJack F Vogel 69413705f88SJack F Vogel /** 69513705f88SJack F Vogel * ixgbe_led_off_generic - Turns off the software controllable LEDs. 69613705f88SJack F Vogel * @hw: pointer to hardware structure 69713705f88SJack F Vogel * @index: led number to turn off 69813705f88SJack F Vogel **/ 69913705f88SJack F Vogel s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) 70013705f88SJack F Vogel { 70113705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 70213705f88SJack F Vogel 7032969bf0eSJack F Vogel DEBUGFUNC("ixgbe_led_off_generic"); 7042969bf0eSJack F Vogel 70513705f88SJack F Vogel /* To turn off the LED, set mode to OFF. */ 70613705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 70713705f88SJack F Vogel led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); 70813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 7099ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 71013705f88SJack F Vogel 71113705f88SJack F Vogel return IXGBE_SUCCESS; 71213705f88SJack F Vogel } 71313705f88SJack F Vogel 71413705f88SJack F Vogel /** 71513705f88SJack F Vogel * ixgbe_init_eeprom_params_generic - Initialize EEPROM params 71613705f88SJack F Vogel * @hw: pointer to hardware structure 71713705f88SJack F Vogel * 71813705f88SJack F Vogel * Initializes the EEPROM parameters ixgbe_eeprom_info within the 71913705f88SJack F Vogel * ixgbe_hw struct in order to set up EEPROM access. 72013705f88SJack F Vogel **/ 72113705f88SJack F Vogel s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) 72213705f88SJack F Vogel { 72313705f88SJack F Vogel struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 72413705f88SJack F Vogel u32 eec; 72513705f88SJack F Vogel u16 eeprom_size; 72613705f88SJack F Vogel 7272969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_eeprom_params_generic"); 7282969bf0eSJack F Vogel 72913705f88SJack F Vogel if (eeprom->type == ixgbe_eeprom_uninitialized) { 73013705f88SJack F Vogel eeprom->type = ixgbe_eeprom_none; 7315b7f4cedSJack F Vogel /* Set default semaphore delay to 10ms which is a well 7325b7f4cedSJack F Vogel * tested value */ 7335b7f4cedSJack F Vogel eeprom->semaphore_delay = 10; 734*85d0a26eSJack F Vogel /* Clear EEPROM page size, it will be initialized as needed */ 735*85d0a26eSJack F Vogel eeprom->word_page_size = 0; 73613705f88SJack F Vogel 73713705f88SJack F Vogel /* 73813705f88SJack F Vogel * Check for EEPROM present first. 73913705f88SJack F Vogel * If not present leave as none 74013705f88SJack F Vogel */ 74113705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 74213705f88SJack F Vogel if (eec & IXGBE_EEC_PRES) { 74313705f88SJack F Vogel eeprom->type = ixgbe_eeprom_spi; 74413705f88SJack F Vogel 74513705f88SJack F Vogel /* 74613705f88SJack F Vogel * SPI EEPROM is assumed here. This code would need to 74713705f88SJack F Vogel * change if a future EEPROM is not SPI. 74813705f88SJack F Vogel */ 74913705f88SJack F Vogel eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 75013705f88SJack F Vogel IXGBE_EEC_SIZE_SHIFT); 75113705f88SJack F Vogel eeprom->word_size = 1 << (eeprom_size + 752*85d0a26eSJack F Vogel IXGBE_EEPROM_WORD_SIZE_SHIFT); 75313705f88SJack F Vogel } 75413705f88SJack F Vogel 75513705f88SJack F Vogel if (eec & IXGBE_EEC_ADDR_SIZE) 75613705f88SJack F Vogel eeprom->address_bits = 16; 75713705f88SJack F Vogel else 75813705f88SJack F Vogel eeprom->address_bits = 8; 75913705f88SJack F Vogel DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: " 76013705f88SJack F Vogel "%d\n", eeprom->type, eeprom->word_size, 76113705f88SJack F Vogel eeprom->address_bits); 76213705f88SJack F Vogel } 76313705f88SJack F Vogel 76413705f88SJack F Vogel return IXGBE_SUCCESS; 76513705f88SJack F Vogel } 76613705f88SJack F Vogel 76713705f88SJack F Vogel /** 768*85d0a26eSJack F Vogel * ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang 769*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 770*85d0a26eSJack F Vogel * @offset: offset within the EEPROM to write 771*85d0a26eSJack F Vogel * @words: number of word(s) 772*85d0a26eSJack F Vogel * @data: 16 bit word(s) to write to EEPROM 773*85d0a26eSJack F Vogel * 774*85d0a26eSJack F Vogel * Reads 16 bit word(s) from EEPROM through bit-bang method 775*85d0a26eSJack F Vogel **/ 776*85d0a26eSJack F Vogel s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, 777*85d0a26eSJack F Vogel u16 words, u16 *data) 778*85d0a26eSJack F Vogel { 779*85d0a26eSJack F Vogel s32 status = IXGBE_SUCCESS; 780*85d0a26eSJack F Vogel u16 i, count; 781*85d0a26eSJack F Vogel 782*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang_generic"); 783*85d0a26eSJack F Vogel 784*85d0a26eSJack F Vogel hw->eeprom.ops.init_params(hw); 785*85d0a26eSJack F Vogel 786*85d0a26eSJack F Vogel if (words == 0) { 787*85d0a26eSJack F Vogel status = IXGBE_ERR_INVALID_ARGUMENT; 788*85d0a26eSJack F Vogel goto out; 789*85d0a26eSJack F Vogel } 790*85d0a26eSJack F Vogel 791*85d0a26eSJack F Vogel if (offset + words > hw->eeprom.word_size) { 792*85d0a26eSJack F Vogel status = IXGBE_ERR_EEPROM; 793*85d0a26eSJack F Vogel goto out; 794*85d0a26eSJack F Vogel } 795*85d0a26eSJack F Vogel 796*85d0a26eSJack F Vogel /* 797*85d0a26eSJack F Vogel * The EEPROM page size cannot be queried from the chip. We do lazy 798*85d0a26eSJack F Vogel * initialization. It is worth to do that when we write large buffer. 799*85d0a26eSJack F Vogel */ 800*85d0a26eSJack F Vogel if ((hw->eeprom.word_page_size == 0) && 801*85d0a26eSJack F Vogel (words > IXGBE_EEPROM_PAGE_SIZE_MAX)) 802*85d0a26eSJack F Vogel ixgbe_detect_eeprom_page_size_generic(hw, offset); 803*85d0a26eSJack F Vogel 804*85d0a26eSJack F Vogel /* 805*85d0a26eSJack F Vogel * We cannot hold synchronization semaphores for too long 806*85d0a26eSJack F Vogel * to avoid other entity starvation. However it is more efficient 807*85d0a26eSJack F Vogel * to read in bursts than synchronizing access for each word. 808*85d0a26eSJack F Vogel */ 809*85d0a26eSJack F Vogel for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) { 810*85d0a26eSJack F Vogel count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ? 811*85d0a26eSJack F Vogel IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i); 812*85d0a26eSJack F Vogel status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i, 813*85d0a26eSJack F Vogel count, &data[i]); 814*85d0a26eSJack F Vogel 815*85d0a26eSJack F Vogel if (status != IXGBE_SUCCESS) 816*85d0a26eSJack F Vogel break; 817*85d0a26eSJack F Vogel } 818*85d0a26eSJack F Vogel 819*85d0a26eSJack F Vogel out: 820*85d0a26eSJack F Vogel return status; 821*85d0a26eSJack F Vogel } 822*85d0a26eSJack F Vogel 823*85d0a26eSJack F Vogel /** 824*85d0a26eSJack F Vogel * ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM 82513705f88SJack F Vogel * @hw: pointer to hardware structure 82613705f88SJack F Vogel * @offset: offset within the EEPROM to be written to 827*85d0a26eSJack F Vogel * @words: number of word(s) 828*85d0a26eSJack F Vogel * @data: 16 bit word(s) to be written to the EEPROM 82913705f88SJack F Vogel * 83013705f88SJack F Vogel * If ixgbe_eeprom_update_checksum is not called after this function, the 83113705f88SJack F Vogel * EEPROM will most likely contain an invalid checksum. 83213705f88SJack F Vogel **/ 833*85d0a26eSJack F Vogel static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, 834*85d0a26eSJack F Vogel u16 words, u16 *data) 83513705f88SJack F Vogel { 83613705f88SJack F Vogel s32 status; 837*85d0a26eSJack F Vogel u16 word; 838*85d0a26eSJack F Vogel u16 page_size; 839*85d0a26eSJack F Vogel u16 i; 84013705f88SJack F Vogel u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI; 84113705f88SJack F Vogel 842*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang"); 8439ca4041bSJack F Vogel 84413705f88SJack F Vogel /* Prepare the EEPROM for writing */ 84513705f88SJack F Vogel status = ixgbe_acquire_eeprom(hw); 84613705f88SJack F Vogel 84713705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 84813705f88SJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 84913705f88SJack F Vogel ixgbe_release_eeprom(hw); 85013705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 85113705f88SJack F Vogel } 85213705f88SJack F Vogel } 85313705f88SJack F Vogel 85413705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 855*85d0a26eSJack F Vogel for (i = 0; i < words; i++) { 85613705f88SJack F Vogel ixgbe_standby_eeprom(hw); 85713705f88SJack F Vogel 85813705f88SJack F Vogel /* Send the WRITE ENABLE command (8 bit opcode ) */ 859*85d0a26eSJack F Vogel ixgbe_shift_out_eeprom_bits(hw, 860*85d0a26eSJack F Vogel IXGBE_EEPROM_WREN_OPCODE_SPI, 86113705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 86213705f88SJack F Vogel 86313705f88SJack F Vogel ixgbe_standby_eeprom(hw); 86413705f88SJack F Vogel 86513705f88SJack F Vogel /* 866*85d0a26eSJack F Vogel * Some SPI eeproms use the 8th address bit embedded 867*85d0a26eSJack F Vogel * in the opcode 86813705f88SJack F Vogel */ 869*85d0a26eSJack F Vogel if ((hw->eeprom.address_bits == 8) && 870*85d0a26eSJack F Vogel ((offset + i) >= 128)) 87113705f88SJack F Vogel write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 87213705f88SJack F Vogel 87313705f88SJack F Vogel /* Send the Write command (8-bit opcode + addr) */ 87413705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, write_opcode, 87513705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 876*85d0a26eSJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2), 87713705f88SJack F Vogel hw->eeprom.address_bits); 87813705f88SJack F Vogel 879*85d0a26eSJack F Vogel page_size = hw->eeprom.word_page_size; 88013705f88SJack F Vogel 881*85d0a26eSJack F Vogel /* Send the data in burst via SPI*/ 882*85d0a26eSJack F Vogel do { 883*85d0a26eSJack F Vogel word = data[i]; 884*85d0a26eSJack F Vogel word = (word >> 8) | (word << 8); 885*85d0a26eSJack F Vogel ixgbe_shift_out_eeprom_bits(hw, word, 16); 886*85d0a26eSJack F Vogel 887*85d0a26eSJack F Vogel if (page_size == 0) 888*85d0a26eSJack F Vogel break; 889*85d0a26eSJack F Vogel 890*85d0a26eSJack F Vogel /* do not wrap around page */ 891*85d0a26eSJack F Vogel if (((offset + i) & (page_size - 1)) == 892*85d0a26eSJack F Vogel (page_size - 1)) 893*85d0a26eSJack F Vogel break; 894*85d0a26eSJack F Vogel } while (++i < words); 895*85d0a26eSJack F Vogel 896*85d0a26eSJack F Vogel ixgbe_standby_eeprom(hw); 897*85d0a26eSJack F Vogel msec_delay(10); 898*85d0a26eSJack F Vogel } 89913705f88SJack F Vogel /* Done with writing - release the EEPROM */ 90013705f88SJack F Vogel ixgbe_release_eeprom(hw); 90113705f88SJack F Vogel } 90213705f88SJack F Vogel 903*85d0a26eSJack F Vogel return status; 904*85d0a26eSJack F Vogel } 905*85d0a26eSJack F Vogel 906*85d0a26eSJack F Vogel /** 907*85d0a26eSJack F Vogel * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM 908*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 909*85d0a26eSJack F Vogel * @offset: offset within the EEPROM to be written to 910*85d0a26eSJack F Vogel * @data: 16 bit word to be written to the EEPROM 911*85d0a26eSJack F Vogel * 912*85d0a26eSJack F Vogel * If ixgbe_eeprom_update_checksum is not called after this function, the 913*85d0a26eSJack F Vogel * EEPROM will most likely contain an invalid checksum. 914*85d0a26eSJack F Vogel **/ 915*85d0a26eSJack F Vogel s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) 916*85d0a26eSJack F Vogel { 917*85d0a26eSJack F Vogel s32 status; 918*85d0a26eSJack F Vogel 919*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_write_eeprom_generic"); 920*85d0a26eSJack F Vogel 921*85d0a26eSJack F Vogel hw->eeprom.ops.init_params(hw); 922*85d0a26eSJack F Vogel 923*85d0a26eSJack F Vogel if (offset >= hw->eeprom.word_size) { 924*85d0a26eSJack F Vogel status = IXGBE_ERR_EEPROM; 925*85d0a26eSJack F Vogel goto out; 926*85d0a26eSJack F Vogel } 927*85d0a26eSJack F Vogel 928*85d0a26eSJack F Vogel status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data); 929*85d0a26eSJack F Vogel 9309ca4041bSJack F Vogel out: 93113705f88SJack F Vogel return status; 93213705f88SJack F Vogel } 93313705f88SJack F Vogel 93413705f88SJack F Vogel /** 935*85d0a26eSJack F Vogel * ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang 936*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 937*85d0a26eSJack F Vogel * @offset: offset within the EEPROM to be read 938*85d0a26eSJack F Vogel * @data: read 16 bit words(s) from EEPROM 939*85d0a26eSJack F Vogel * @words: number of word(s) 940*85d0a26eSJack F Vogel * 941*85d0a26eSJack F Vogel * Reads 16 bit word(s) from EEPROM through bit-bang method 942*85d0a26eSJack F Vogel **/ 943*85d0a26eSJack F Vogel s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, 944*85d0a26eSJack F Vogel u16 words, u16 *data) 945*85d0a26eSJack F Vogel { 946*85d0a26eSJack F Vogel s32 status = IXGBE_SUCCESS; 947*85d0a26eSJack F Vogel u16 i, count; 948*85d0a26eSJack F Vogel 949*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang_generic"); 950*85d0a26eSJack F Vogel 951*85d0a26eSJack F Vogel hw->eeprom.ops.init_params(hw); 952*85d0a26eSJack F Vogel 953*85d0a26eSJack F Vogel if (words == 0) { 954*85d0a26eSJack F Vogel status = IXGBE_ERR_INVALID_ARGUMENT; 955*85d0a26eSJack F Vogel goto out; 956*85d0a26eSJack F Vogel } 957*85d0a26eSJack F Vogel 958*85d0a26eSJack F Vogel if (offset + words > hw->eeprom.word_size) { 959*85d0a26eSJack F Vogel status = IXGBE_ERR_EEPROM; 960*85d0a26eSJack F Vogel goto out; 961*85d0a26eSJack F Vogel } 962*85d0a26eSJack F Vogel 963*85d0a26eSJack F Vogel /* 964*85d0a26eSJack F Vogel * We cannot hold synchronization semaphores for too long 965*85d0a26eSJack F Vogel * to avoid other entity starvation. However it is more efficient 966*85d0a26eSJack F Vogel * to read in bursts than synchronizing access for each word. 967*85d0a26eSJack F Vogel */ 968*85d0a26eSJack F Vogel for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) { 969*85d0a26eSJack F Vogel count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ? 970*85d0a26eSJack F Vogel IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i); 971*85d0a26eSJack F Vogel 972*85d0a26eSJack F Vogel status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i, 973*85d0a26eSJack F Vogel count, &data[i]); 974*85d0a26eSJack F Vogel 975*85d0a26eSJack F Vogel if (status != IXGBE_SUCCESS) 976*85d0a26eSJack F Vogel break; 977*85d0a26eSJack F Vogel } 978*85d0a26eSJack F Vogel 979*85d0a26eSJack F Vogel out: 980*85d0a26eSJack F Vogel return status; 981*85d0a26eSJack F Vogel } 982*85d0a26eSJack F Vogel 983*85d0a26eSJack F Vogel /** 984*85d0a26eSJack F Vogel * ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang 985*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 986*85d0a26eSJack F Vogel * @offset: offset within the EEPROM to be read 987*85d0a26eSJack F Vogel * @words: number of word(s) 988*85d0a26eSJack F Vogel * @data: read 16 bit word(s) from EEPROM 989*85d0a26eSJack F Vogel * 990*85d0a26eSJack F Vogel * Reads 16 bit word(s) from EEPROM through bit-bang method 991*85d0a26eSJack F Vogel **/ 992*85d0a26eSJack F Vogel static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset, 993*85d0a26eSJack F Vogel u16 words, u16 *data) 994*85d0a26eSJack F Vogel { 995*85d0a26eSJack F Vogel s32 status; 996*85d0a26eSJack F Vogel u16 word_in; 997*85d0a26eSJack F Vogel u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; 998*85d0a26eSJack F Vogel u16 i; 999*85d0a26eSJack F Vogel 1000*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang"); 1001*85d0a26eSJack F Vogel 1002*85d0a26eSJack F Vogel /* Prepare the EEPROM for reading */ 1003*85d0a26eSJack F Vogel status = ixgbe_acquire_eeprom(hw); 1004*85d0a26eSJack F Vogel 1005*85d0a26eSJack F Vogel if (status == IXGBE_SUCCESS) { 1006*85d0a26eSJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 1007*85d0a26eSJack F Vogel ixgbe_release_eeprom(hw); 1008*85d0a26eSJack F Vogel status = IXGBE_ERR_EEPROM; 1009*85d0a26eSJack F Vogel } 1010*85d0a26eSJack F Vogel } 1011*85d0a26eSJack F Vogel 1012*85d0a26eSJack F Vogel if (status == IXGBE_SUCCESS) { 1013*85d0a26eSJack F Vogel for (i = 0; i < words; i++) { 1014*85d0a26eSJack F Vogel ixgbe_standby_eeprom(hw); 1015*85d0a26eSJack F Vogel /* 1016*85d0a26eSJack F Vogel * Some SPI eeproms use the 8th address bit embedded 1017*85d0a26eSJack F Vogel * in the opcode 1018*85d0a26eSJack F Vogel */ 1019*85d0a26eSJack F Vogel if ((hw->eeprom.address_bits == 8) && 1020*85d0a26eSJack F Vogel ((offset + i) >= 128)) 1021*85d0a26eSJack F Vogel read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 1022*85d0a26eSJack F Vogel 1023*85d0a26eSJack F Vogel /* Send the READ command (opcode + addr) */ 1024*85d0a26eSJack F Vogel ixgbe_shift_out_eeprom_bits(hw, read_opcode, 1025*85d0a26eSJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 1026*85d0a26eSJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2), 1027*85d0a26eSJack F Vogel hw->eeprom.address_bits); 1028*85d0a26eSJack F Vogel 1029*85d0a26eSJack F Vogel /* Read the data. */ 1030*85d0a26eSJack F Vogel word_in = ixgbe_shift_in_eeprom_bits(hw, 16); 1031*85d0a26eSJack F Vogel data[i] = (word_in >> 8) | (word_in << 8); 1032*85d0a26eSJack F Vogel } 1033*85d0a26eSJack F Vogel 1034*85d0a26eSJack F Vogel /* End this read operation */ 1035*85d0a26eSJack F Vogel ixgbe_release_eeprom(hw); 1036*85d0a26eSJack F Vogel } 1037*85d0a26eSJack F Vogel 1038*85d0a26eSJack F Vogel return status; 1039*85d0a26eSJack F Vogel } 1040*85d0a26eSJack F Vogel 1041*85d0a26eSJack F Vogel /** 104213705f88SJack F Vogel * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang 104313705f88SJack F Vogel * @hw: pointer to hardware structure 104413705f88SJack F Vogel * @offset: offset within the EEPROM to be read 104513705f88SJack F Vogel * @data: read 16 bit value from EEPROM 104613705f88SJack F Vogel * 104713705f88SJack F Vogel * Reads 16 bit value from EEPROM through bit-bang method 104813705f88SJack F Vogel **/ 104913705f88SJack F Vogel s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, 105013705f88SJack F Vogel u16 *data) 105113705f88SJack F Vogel { 105213705f88SJack F Vogel s32 status; 105313705f88SJack F Vogel 10542969bf0eSJack F Vogel DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic"); 10552969bf0eSJack F Vogel 10569ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 10579ca4041bSJack F Vogel 10589ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 10599ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 10609ca4041bSJack F Vogel goto out; 10619ca4041bSJack F Vogel } 10629ca4041bSJack F Vogel 1063*85d0a26eSJack F Vogel status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data); 106413705f88SJack F Vogel 1065*85d0a26eSJack F Vogel out: 1066*85d0a26eSJack F Vogel return status; 1067*85d0a26eSJack F Vogel } 1068*85d0a26eSJack F Vogel 1069*85d0a26eSJack F Vogel /** 1070*85d0a26eSJack F Vogel * ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD 1071*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 1072*85d0a26eSJack F Vogel * @offset: offset of word in the EEPROM to read 1073*85d0a26eSJack F Vogel * @words: number of word(s) 1074*85d0a26eSJack F Vogel * @data: 16 bit word(s) from the EEPROM 1075*85d0a26eSJack F Vogel * 1076*85d0a26eSJack F Vogel * Reads a 16 bit word(s) from the EEPROM using the EERD register. 1077*85d0a26eSJack F Vogel **/ 1078*85d0a26eSJack F Vogel s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset, 1079*85d0a26eSJack F Vogel u16 words, u16 *data) 1080*85d0a26eSJack F Vogel { 1081*85d0a26eSJack F Vogel u32 eerd; 1082*85d0a26eSJack F Vogel s32 status = IXGBE_SUCCESS; 1083*85d0a26eSJack F Vogel u32 i; 1084*85d0a26eSJack F Vogel 1085*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_read_eerd_buffer_generic"); 1086*85d0a26eSJack F Vogel 1087*85d0a26eSJack F Vogel hw->eeprom.ops.init_params(hw); 1088*85d0a26eSJack F Vogel 1089*85d0a26eSJack F Vogel if (words == 0) { 1090*85d0a26eSJack F Vogel status = IXGBE_ERR_INVALID_ARGUMENT; 1091*85d0a26eSJack F Vogel goto out; 1092*85d0a26eSJack F Vogel } 1093*85d0a26eSJack F Vogel 1094*85d0a26eSJack F Vogel if (offset >= hw->eeprom.word_size) { 109513705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 1096*85d0a26eSJack F Vogel goto out; 109713705f88SJack F Vogel } 109813705f88SJack F Vogel 1099*85d0a26eSJack F Vogel for (i = 0; i < words; i++) { 1100*85d0a26eSJack F Vogel eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) + 1101*85d0a26eSJack F Vogel IXGBE_EEPROM_RW_REG_START; 1102*85d0a26eSJack F Vogel 1103*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); 1104*85d0a26eSJack F Vogel status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ); 1105*85d0a26eSJack F Vogel 110613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 1107*85d0a26eSJack F Vogel data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >> 1108*85d0a26eSJack F Vogel IXGBE_EEPROM_RW_REG_DATA); 1109*85d0a26eSJack F Vogel } else { 1110*85d0a26eSJack F Vogel DEBUGOUT("Eeprom read timed out\n"); 1111*85d0a26eSJack F Vogel goto out; 1112*85d0a26eSJack F Vogel } 1113*85d0a26eSJack F Vogel } 1114*85d0a26eSJack F Vogel out: 1115*85d0a26eSJack F Vogel return status; 1116*85d0a26eSJack F Vogel } 1117*85d0a26eSJack F Vogel 1118*85d0a26eSJack F Vogel /** 1119*85d0a26eSJack F Vogel * ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size 1120*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 1121*85d0a26eSJack F Vogel * @offset: offset within the EEPROM to be used as a scratch pad 1122*85d0a26eSJack F Vogel * 1123*85d0a26eSJack F Vogel * Discover EEPROM page size by writing marching data at given offset. 1124*85d0a26eSJack F Vogel * This function is called only when we are writing a new large buffer 1125*85d0a26eSJack F Vogel * at given offset so the data would be overwritten anyway. 1126*85d0a26eSJack F Vogel **/ 1127*85d0a26eSJack F Vogel static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw, 1128*85d0a26eSJack F Vogel u16 offset) 1129*85d0a26eSJack F Vogel { 1130*85d0a26eSJack F Vogel u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX]; 1131*85d0a26eSJack F Vogel s32 status = IXGBE_SUCCESS; 1132*85d0a26eSJack F Vogel u16 i; 1133*85d0a26eSJack F Vogel 1134*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_detect_eeprom_page_size_generic"); 1135*85d0a26eSJack F Vogel 1136*85d0a26eSJack F Vogel for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++) 1137*85d0a26eSJack F Vogel data[i] = i; 1138*85d0a26eSJack F Vogel 1139*85d0a26eSJack F Vogel hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX; 1140*85d0a26eSJack F Vogel status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1141*85d0a26eSJack F Vogel IXGBE_EEPROM_PAGE_SIZE_MAX, data); 1142*85d0a26eSJack F Vogel hw->eeprom.word_page_size = 0; 1143*85d0a26eSJack F Vogel if (status != IXGBE_SUCCESS) 1144*85d0a26eSJack F Vogel goto out; 1145*85d0a26eSJack F Vogel 1146*85d0a26eSJack F Vogel status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data); 1147*85d0a26eSJack F Vogel if (status != IXGBE_SUCCESS) 1148*85d0a26eSJack F Vogel goto out; 114913705f88SJack F Vogel 115013705f88SJack F Vogel /* 1151*85d0a26eSJack F Vogel * When writing in burst more than the actual page size 1152*85d0a26eSJack F Vogel * EEPROM address wraps around current page. 115313705f88SJack F Vogel */ 1154*85d0a26eSJack F Vogel hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0]; 115513705f88SJack F Vogel 1156*85d0a26eSJack F Vogel DEBUGOUT1("Detected EEPROM page size = %d words.", 1157*85d0a26eSJack F Vogel hw->eeprom.word_page_size); 11589ca4041bSJack F Vogel out: 115913705f88SJack F Vogel return status; 116013705f88SJack F Vogel } 116113705f88SJack F Vogel 116213705f88SJack F Vogel /** 11632969bf0eSJack F Vogel * ixgbe_read_eerd_generic - Read EEPROM word using EERD 116413705f88SJack F Vogel * @hw: pointer to hardware structure 116513705f88SJack F Vogel * @offset: offset of word in the EEPROM to read 116613705f88SJack F Vogel * @data: word read from the EEPROM 116713705f88SJack F Vogel * 116813705f88SJack F Vogel * Reads a 16 bit word from the EEPROM using the EERD register. 116913705f88SJack F Vogel **/ 11702969bf0eSJack F Vogel s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) 117113705f88SJack F Vogel { 1172*85d0a26eSJack F Vogel return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data); 1173*85d0a26eSJack F Vogel } 117413705f88SJack F Vogel 1175*85d0a26eSJack F Vogel /** 1176*85d0a26eSJack F Vogel * ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR 1177*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 1178*85d0a26eSJack F Vogel * @offset: offset of word in the EEPROM to write 1179*85d0a26eSJack F Vogel * @words: number of word(s) 1180*85d0a26eSJack F Vogel * @data: word(s) write to the EEPROM 1181*85d0a26eSJack F Vogel * 1182*85d0a26eSJack F Vogel * Write a 16 bit word(s) to the EEPROM using the EEWR register. 1183*85d0a26eSJack F Vogel **/ 1184*85d0a26eSJack F Vogel s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset, 1185*85d0a26eSJack F Vogel u16 words, u16 *data) 1186*85d0a26eSJack F Vogel { 1187*85d0a26eSJack F Vogel u32 eewr; 1188*85d0a26eSJack F Vogel s32 status = IXGBE_SUCCESS; 1189*85d0a26eSJack F Vogel u16 i; 1190*85d0a26eSJack F Vogel 1191*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_write_eewr_generic"); 11922969bf0eSJack F Vogel 11939ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 11949ca4041bSJack F Vogel 1195*85d0a26eSJack F Vogel if (words == 0) { 1196*85d0a26eSJack F Vogel status = IXGBE_ERR_INVALID_ARGUMENT; 1197*85d0a26eSJack F Vogel goto out; 1198*85d0a26eSJack F Vogel } 1199*85d0a26eSJack F Vogel 12009ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 12019ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 12029ca4041bSJack F Vogel goto out; 12039ca4041bSJack F Vogel } 12049ca4041bSJack F Vogel 1205*85d0a26eSJack F Vogel for (i = 0; i < words; i++) { 1206*85d0a26eSJack F Vogel eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | 1207*85d0a26eSJack F Vogel (data[i] << IXGBE_EEPROM_RW_REG_DATA) | 12082969bf0eSJack F Vogel IXGBE_EEPROM_RW_REG_START; 120913705f88SJack F Vogel 1210*85d0a26eSJack F Vogel status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); 1211*85d0a26eSJack F Vogel if (status != IXGBE_SUCCESS) { 1212*85d0a26eSJack F Vogel DEBUGOUT("Eeprom write EEWR timed out\n"); 1213*85d0a26eSJack F Vogel goto out; 1214*85d0a26eSJack F Vogel } 121513705f88SJack F Vogel 1216*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr); 1217*85d0a26eSJack F Vogel 1218*85d0a26eSJack F Vogel status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); 1219*85d0a26eSJack F Vogel if (status != IXGBE_SUCCESS) { 1220*85d0a26eSJack F Vogel DEBUGOUT("Eeprom write EEWR timed out\n"); 1221*85d0a26eSJack F Vogel goto out; 1222*85d0a26eSJack F Vogel } 1223*85d0a26eSJack F Vogel } 122413705f88SJack F Vogel 12259ca4041bSJack F Vogel out: 122613705f88SJack F Vogel return status; 122713705f88SJack F Vogel } 122813705f88SJack F Vogel 122913705f88SJack F Vogel /** 12301a4e3449SJack F Vogel * ixgbe_write_eewr_generic - Write EEPROM word using EEWR 12311a4e3449SJack F Vogel * @hw: pointer to hardware structure 12321a4e3449SJack F Vogel * @offset: offset of word in the EEPROM to write 12331a4e3449SJack F Vogel * @data: word write to the EEPROM 12341a4e3449SJack F Vogel * 12351a4e3449SJack F Vogel * Write a 16 bit word to the EEPROM using the EEWR register. 12361a4e3449SJack F Vogel **/ 12371a4e3449SJack F Vogel s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data) 12381a4e3449SJack F Vogel { 1239*85d0a26eSJack F Vogel return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data); 12401a4e3449SJack F Vogel } 12411a4e3449SJack F Vogel 12421a4e3449SJack F Vogel /** 12432969bf0eSJack F Vogel * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status 124413705f88SJack F Vogel * @hw: pointer to hardware structure 12452969bf0eSJack F Vogel * @ee_reg: EEPROM flag for polling 124613705f88SJack F Vogel * 12472969bf0eSJack F Vogel * Polls the status bit (bit 1) of the EERD or EEWR to determine when the 12482969bf0eSJack F Vogel * read or write is done respectively. 124913705f88SJack F Vogel **/ 12502969bf0eSJack F Vogel s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) 125113705f88SJack F Vogel { 125213705f88SJack F Vogel u32 i; 125313705f88SJack F Vogel u32 reg; 125413705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 125513705f88SJack F Vogel 12562969bf0eSJack F Vogel DEBUGFUNC("ixgbe_poll_eerd_eewr_done"); 12572969bf0eSJack F Vogel 12582969bf0eSJack F Vogel for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) { 12592969bf0eSJack F Vogel if (ee_reg == IXGBE_NVM_POLL_READ) 126013705f88SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_EERD); 12612969bf0eSJack F Vogel else 12622969bf0eSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_EEWR); 12632969bf0eSJack F Vogel 12642969bf0eSJack F Vogel if (reg & IXGBE_EEPROM_RW_REG_DONE) { 126513705f88SJack F Vogel status = IXGBE_SUCCESS; 126613705f88SJack F Vogel break; 126713705f88SJack F Vogel } 126813705f88SJack F Vogel usec_delay(5); 126913705f88SJack F Vogel } 127013705f88SJack F Vogel return status; 127113705f88SJack F Vogel } 127213705f88SJack F Vogel 127313705f88SJack F Vogel /** 127413705f88SJack F Vogel * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang 127513705f88SJack F Vogel * @hw: pointer to hardware structure 127613705f88SJack F Vogel * 127713705f88SJack F Vogel * Prepares EEPROM for access using bit-bang method. This function should 127813705f88SJack F Vogel * be called before issuing a command to the EEPROM. 127913705f88SJack F Vogel **/ 128013705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) 128113705f88SJack F Vogel { 128213705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 128313705f88SJack F Vogel u32 eec; 128413705f88SJack F Vogel u32 i; 128513705f88SJack F Vogel 12862969bf0eSJack F Vogel DEBUGFUNC("ixgbe_acquire_eeprom"); 12872969bf0eSJack F Vogel 1288*85d0a26eSJack F Vogel if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) 1289*85d0a26eSJack F Vogel != IXGBE_SUCCESS) 129013705f88SJack F Vogel status = IXGBE_ERR_SWFW_SYNC; 129113705f88SJack F Vogel 129213705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 129313705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 129413705f88SJack F Vogel 129513705f88SJack F Vogel /* Request EEPROM Access */ 129613705f88SJack F Vogel eec |= IXGBE_EEC_REQ; 129713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 129813705f88SJack F Vogel 129913705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { 130013705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 130113705f88SJack F Vogel if (eec & IXGBE_EEC_GNT) 130213705f88SJack F Vogel break; 130313705f88SJack F Vogel usec_delay(5); 130413705f88SJack F Vogel } 130513705f88SJack F Vogel 13069ca4041bSJack F Vogel /* Release if grant not acquired */ 130713705f88SJack F Vogel if (!(eec & IXGBE_EEC_GNT)) { 130813705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 130913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 131013705f88SJack F Vogel DEBUGOUT("Could not acquire EEPROM grant\n"); 131113705f88SJack F Vogel 1312*85d0a26eSJack F Vogel hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 131313705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 131413705f88SJack F Vogel } 131513705f88SJack F Vogel 131613705f88SJack F Vogel /* Setup EEPROM for Read/Write */ 131713705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 131813705f88SJack F Vogel /* Clear CS and SK */ 131913705f88SJack F Vogel eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); 132013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 132113705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 132213705f88SJack F Vogel usec_delay(1); 132313705f88SJack F Vogel } 13241a4e3449SJack F Vogel } 132513705f88SJack F Vogel return status; 132613705f88SJack F Vogel } 132713705f88SJack F Vogel 132813705f88SJack F Vogel /** 132913705f88SJack F Vogel * ixgbe_get_eeprom_semaphore - Get hardware semaphore 133013705f88SJack F Vogel * @hw: pointer to hardware structure 133113705f88SJack F Vogel * 133213705f88SJack F Vogel * Sets the hardware semaphores so EEPROM access can occur for bit-bang method 133313705f88SJack F Vogel **/ 133413705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) 133513705f88SJack F Vogel { 133613705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 1337d8602bb9SJack F Vogel u32 timeout = 2000; 133813705f88SJack F Vogel u32 i; 133913705f88SJack F Vogel u32 swsm; 134013705f88SJack F Vogel 13412969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_eeprom_semaphore"); 13422969bf0eSJack F Vogel 13431a4e3449SJack F Vogel 134413705f88SJack F Vogel /* Get SMBI software semaphore between device drivers first */ 134513705f88SJack F Vogel for (i = 0; i < timeout; i++) { 134613705f88SJack F Vogel /* 134713705f88SJack F Vogel * If the SMBI bit is 0 when we read it, then the bit will be 134813705f88SJack F Vogel * set and we have the semaphore 134913705f88SJack F Vogel */ 135013705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 135113705f88SJack F Vogel if (!(swsm & IXGBE_SWSM_SMBI)) { 135213705f88SJack F Vogel status = IXGBE_SUCCESS; 135313705f88SJack F Vogel break; 135413705f88SJack F Vogel } 13550ac6dfecSJack F Vogel usec_delay(50); 135613705f88SJack F Vogel } 135713705f88SJack F Vogel 1358*85d0a26eSJack F Vogel if (i == timeout) { 1359*85d0a26eSJack F Vogel DEBUGOUT("Driver can't access the Eeprom - SMBI Semaphore " 1360*85d0a26eSJack F Vogel "not granted.\n"); 1361*85d0a26eSJack F Vogel /* 1362*85d0a26eSJack F Vogel * this release is particularly important because our attempts 1363*85d0a26eSJack F Vogel * above to get the semaphore may have succeeded, and if there 1364*85d0a26eSJack F Vogel * was a timeout, we should unconditionally clear the semaphore 1365*85d0a26eSJack F Vogel * bits to free the driver to make progress 1366*85d0a26eSJack F Vogel */ 1367*85d0a26eSJack F Vogel ixgbe_release_eeprom_semaphore(hw); 1368*85d0a26eSJack F Vogel 1369*85d0a26eSJack F Vogel usec_delay(50); 1370*85d0a26eSJack F Vogel /* 1371*85d0a26eSJack F Vogel * one last try 1372*85d0a26eSJack F Vogel * If the SMBI bit is 0 when we read it, then the bit will be 1373*85d0a26eSJack F Vogel * set and we have the semaphore 1374*85d0a26eSJack F Vogel */ 1375*85d0a26eSJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 1376*85d0a26eSJack F Vogel if (!(swsm & IXGBE_SWSM_SMBI)) 1377*85d0a26eSJack F Vogel status = IXGBE_SUCCESS; 1378*85d0a26eSJack F Vogel } 1379*85d0a26eSJack F Vogel 138013705f88SJack F Vogel /* Now get the semaphore between SW/FW through the SWESMBI bit */ 138113705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 138213705f88SJack F Vogel for (i = 0; i < timeout; i++) { 138313705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 138413705f88SJack F Vogel 138513705f88SJack F Vogel /* Set the SW EEPROM semaphore bit to request access */ 138613705f88SJack F Vogel swsm |= IXGBE_SWSM_SWESMBI; 138713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 138813705f88SJack F Vogel 138913705f88SJack F Vogel /* 139013705f88SJack F Vogel * If we set the bit successfully then we got the 139113705f88SJack F Vogel * semaphore. 139213705f88SJack F Vogel */ 139313705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 139413705f88SJack F Vogel if (swsm & IXGBE_SWSM_SWESMBI) 139513705f88SJack F Vogel break; 139613705f88SJack F Vogel 139713705f88SJack F Vogel usec_delay(50); 139813705f88SJack F Vogel } 139913705f88SJack F Vogel 140013705f88SJack F Vogel /* 140113705f88SJack F Vogel * Release semaphores and return error if SW EEPROM semaphore 140213705f88SJack F Vogel * was not granted because we don't have access to the EEPROM 140313705f88SJack F Vogel */ 140413705f88SJack F Vogel if (i >= timeout) { 14050ac6dfecSJack F Vogel DEBUGOUT("SWESMBI Software EEPROM semaphore " 140613705f88SJack F Vogel "not granted.\n"); 140713705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 140813705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 140913705f88SJack F Vogel } 14100ac6dfecSJack F Vogel } else { 14110ac6dfecSJack F Vogel DEBUGOUT("Software semaphore SMBI between device drivers " 14120ac6dfecSJack F Vogel "not granted.\n"); 141313705f88SJack F Vogel } 141413705f88SJack F Vogel 141513705f88SJack F Vogel return status; 141613705f88SJack F Vogel } 141713705f88SJack F Vogel 141813705f88SJack F Vogel /** 141913705f88SJack F Vogel * ixgbe_release_eeprom_semaphore - Release hardware semaphore 142013705f88SJack F Vogel * @hw: pointer to hardware structure 142113705f88SJack F Vogel * 142213705f88SJack F Vogel * This function clears hardware semaphore bits. 142313705f88SJack F Vogel **/ 142413705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) 142513705f88SJack F Vogel { 142613705f88SJack F Vogel u32 swsm; 142713705f88SJack F Vogel 14282969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_eeprom_semaphore"); 14292969bf0eSJack F Vogel 143013705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 143113705f88SJack F Vogel 143213705f88SJack F Vogel /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ 143313705f88SJack F Vogel swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI); 143413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 14359ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 143613705f88SJack F Vogel } 143713705f88SJack F Vogel 143813705f88SJack F Vogel /** 143913705f88SJack F Vogel * ixgbe_ready_eeprom - Polls for EEPROM ready 144013705f88SJack F Vogel * @hw: pointer to hardware structure 144113705f88SJack F Vogel **/ 144213705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) 144313705f88SJack F Vogel { 144413705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 144513705f88SJack F Vogel u16 i; 144613705f88SJack F Vogel u8 spi_stat_reg; 144713705f88SJack F Vogel 14482969bf0eSJack F Vogel DEBUGFUNC("ixgbe_ready_eeprom"); 14492969bf0eSJack F Vogel 145013705f88SJack F Vogel /* 145113705f88SJack F Vogel * Read "Status Register" repeatedly until the LSB is cleared. The 145213705f88SJack F Vogel * EEPROM will signal that the command has been completed by clearing 145313705f88SJack F Vogel * bit 0 of the internal status register. If it's not cleared within 145413705f88SJack F Vogel * 5 milliseconds, then error out. 145513705f88SJack F Vogel */ 145613705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) { 145713705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI, 145813705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 145913705f88SJack F Vogel spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8); 146013705f88SJack F Vogel if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI)) 146113705f88SJack F Vogel break; 146213705f88SJack F Vogel 146313705f88SJack F Vogel usec_delay(5); 146413705f88SJack F Vogel ixgbe_standby_eeprom(hw); 146513705f88SJack F Vogel }; 146613705f88SJack F Vogel 146713705f88SJack F Vogel /* 146813705f88SJack F Vogel * On some parts, SPI write time could vary from 0-20mSec on 3.3V 146913705f88SJack F Vogel * devices (and only 0-5mSec on 5V devices) 147013705f88SJack F Vogel */ 147113705f88SJack F Vogel if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { 147213705f88SJack F Vogel DEBUGOUT("SPI EEPROM Status error\n"); 147313705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 147413705f88SJack F Vogel } 147513705f88SJack F Vogel 147613705f88SJack F Vogel return status; 147713705f88SJack F Vogel } 147813705f88SJack F Vogel 147913705f88SJack F Vogel /** 148013705f88SJack F Vogel * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state 148113705f88SJack F Vogel * @hw: pointer to hardware structure 148213705f88SJack F Vogel **/ 148313705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw) 148413705f88SJack F Vogel { 148513705f88SJack F Vogel u32 eec; 148613705f88SJack F Vogel 14872969bf0eSJack F Vogel DEBUGFUNC("ixgbe_standby_eeprom"); 14882969bf0eSJack F Vogel 148913705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 149013705f88SJack F Vogel 149113705f88SJack F Vogel /* Toggle CS to flush commands */ 149213705f88SJack F Vogel eec |= IXGBE_EEC_CS; 149313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 149413705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 149513705f88SJack F Vogel usec_delay(1); 149613705f88SJack F Vogel eec &= ~IXGBE_EEC_CS; 149713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 149813705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 149913705f88SJack F Vogel usec_delay(1); 150013705f88SJack F Vogel } 150113705f88SJack F Vogel 150213705f88SJack F Vogel /** 150313705f88SJack F Vogel * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM. 150413705f88SJack F Vogel * @hw: pointer to hardware structure 150513705f88SJack F Vogel * @data: data to send to the EEPROM 150613705f88SJack F Vogel * @count: number of bits to shift out 150713705f88SJack F Vogel **/ 150813705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, 150913705f88SJack F Vogel u16 count) 151013705f88SJack F Vogel { 151113705f88SJack F Vogel u32 eec; 151213705f88SJack F Vogel u32 mask; 151313705f88SJack F Vogel u32 i; 151413705f88SJack F Vogel 15152969bf0eSJack F Vogel DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); 15162969bf0eSJack F Vogel 151713705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 151813705f88SJack F Vogel 151913705f88SJack F Vogel /* 152013705f88SJack F Vogel * Mask is used to shift "count" bits of "data" out to the EEPROM 152113705f88SJack F Vogel * one bit at a time. Determine the starting bit based on count 152213705f88SJack F Vogel */ 152313705f88SJack F Vogel mask = 0x01 << (count - 1); 152413705f88SJack F Vogel 152513705f88SJack F Vogel for (i = 0; i < count; i++) { 152613705f88SJack F Vogel /* 152713705f88SJack F Vogel * A "1" is shifted out to the EEPROM by setting bit "DI" to a 152813705f88SJack F Vogel * "1", and then raising and then lowering the clock (the SK 152913705f88SJack F Vogel * bit controls the clock input to the EEPROM). A "0" is 153013705f88SJack F Vogel * shifted out to the EEPROM by setting "DI" to "0" and then 153113705f88SJack F Vogel * raising and then lowering the clock. 153213705f88SJack F Vogel */ 153313705f88SJack F Vogel if (data & mask) 153413705f88SJack F Vogel eec |= IXGBE_EEC_DI; 153513705f88SJack F Vogel else 153613705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 153713705f88SJack F Vogel 153813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 153913705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 154013705f88SJack F Vogel 154113705f88SJack F Vogel usec_delay(1); 154213705f88SJack F Vogel 154313705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 154413705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 154513705f88SJack F Vogel 154613705f88SJack F Vogel /* 154713705f88SJack F Vogel * Shift mask to signify next bit of data to shift in to the 154813705f88SJack F Vogel * EEPROM 154913705f88SJack F Vogel */ 155013705f88SJack F Vogel mask = mask >> 1; 155113705f88SJack F Vogel }; 155213705f88SJack F Vogel 155313705f88SJack F Vogel /* We leave the "DI" bit set to "0" when we leave this routine. */ 155413705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 155513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 155613705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 155713705f88SJack F Vogel } 155813705f88SJack F Vogel 155913705f88SJack F Vogel /** 156013705f88SJack F Vogel * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM 156113705f88SJack F Vogel * @hw: pointer to hardware structure 156213705f88SJack F Vogel **/ 156313705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) 156413705f88SJack F Vogel { 156513705f88SJack F Vogel u32 eec; 156613705f88SJack F Vogel u32 i; 156713705f88SJack F Vogel u16 data = 0; 156813705f88SJack F Vogel 15692969bf0eSJack F Vogel DEBUGFUNC("ixgbe_shift_in_eeprom_bits"); 15702969bf0eSJack F Vogel 157113705f88SJack F Vogel /* 157213705f88SJack F Vogel * In order to read a register from the EEPROM, we need to shift 157313705f88SJack F Vogel * 'count' bits in from the EEPROM. Bits are "shifted in" by raising 157413705f88SJack F Vogel * the clock input to the EEPROM (setting the SK bit), and then reading 157513705f88SJack F Vogel * the value of the "DO" bit. During this "shifting in" process the 157613705f88SJack F Vogel * "DI" bit should always be clear. 157713705f88SJack F Vogel */ 157813705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 157913705f88SJack F Vogel 158013705f88SJack F Vogel eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); 158113705f88SJack F Vogel 158213705f88SJack F Vogel for (i = 0; i < count; i++) { 158313705f88SJack F Vogel data = data << 1; 158413705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 158513705f88SJack F Vogel 158613705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 158713705f88SJack F Vogel 158813705f88SJack F Vogel eec &= ~(IXGBE_EEC_DI); 158913705f88SJack F Vogel if (eec & IXGBE_EEC_DO) 159013705f88SJack F Vogel data |= 1; 159113705f88SJack F Vogel 159213705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 159313705f88SJack F Vogel } 159413705f88SJack F Vogel 159513705f88SJack F Vogel return data; 159613705f88SJack F Vogel } 159713705f88SJack F Vogel 159813705f88SJack F Vogel /** 159913705f88SJack F Vogel * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input. 160013705f88SJack F Vogel * @hw: pointer to hardware structure 160113705f88SJack F Vogel * @eec: EEC register's current value 160213705f88SJack F Vogel **/ 160313705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 160413705f88SJack F Vogel { 16052969bf0eSJack F Vogel DEBUGFUNC("ixgbe_raise_eeprom_clk"); 16062969bf0eSJack F Vogel 160713705f88SJack F Vogel /* 160813705f88SJack F Vogel * Raise the clock input to the EEPROM 160913705f88SJack F Vogel * (setting the SK bit), then delay 161013705f88SJack F Vogel */ 161113705f88SJack F Vogel *eec = *eec | IXGBE_EEC_SK; 161213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 161313705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 161413705f88SJack F Vogel usec_delay(1); 161513705f88SJack F Vogel } 161613705f88SJack F Vogel 161713705f88SJack F Vogel /** 161813705f88SJack F Vogel * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input. 161913705f88SJack F Vogel * @hw: pointer to hardware structure 162013705f88SJack F Vogel * @eecd: EECD's current value 162113705f88SJack F Vogel **/ 162213705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 162313705f88SJack F Vogel { 16242969bf0eSJack F Vogel DEBUGFUNC("ixgbe_lower_eeprom_clk"); 16252969bf0eSJack F Vogel 162613705f88SJack F Vogel /* 162713705f88SJack F Vogel * Lower the clock input to the EEPROM (clearing the SK bit), then 162813705f88SJack F Vogel * delay 162913705f88SJack F Vogel */ 163013705f88SJack F Vogel *eec = *eec & ~IXGBE_EEC_SK; 163113705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 163213705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 163313705f88SJack F Vogel usec_delay(1); 163413705f88SJack F Vogel } 163513705f88SJack F Vogel 163613705f88SJack F Vogel /** 163713705f88SJack F Vogel * ixgbe_release_eeprom - Release EEPROM, release semaphores 163813705f88SJack F Vogel * @hw: pointer to hardware structure 163913705f88SJack F Vogel **/ 164013705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw) 164113705f88SJack F Vogel { 164213705f88SJack F Vogel u32 eec; 164313705f88SJack F Vogel 16442969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_eeprom"); 16452969bf0eSJack F Vogel 164613705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 164713705f88SJack F Vogel 164813705f88SJack F Vogel eec |= IXGBE_EEC_CS; /* Pull CS high */ 164913705f88SJack F Vogel eec &= ~IXGBE_EEC_SK; /* Lower SCK */ 165013705f88SJack F Vogel 165113705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 165213705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 165313705f88SJack F Vogel 165413705f88SJack F Vogel usec_delay(1); 165513705f88SJack F Vogel 165613705f88SJack F Vogel /* Stop requesting EEPROM access */ 165713705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 165813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 165913705f88SJack F Vogel 1660*85d0a26eSJack F Vogel hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 1661d8602bb9SJack F Vogel 1662d8602bb9SJack F Vogel /* Delay before attempt to obtain semaphore again to allow FW access */ 1663d8602bb9SJack F Vogel msec_delay(hw->eeprom.semaphore_delay); 166413705f88SJack F Vogel } 166513705f88SJack F Vogel 166613705f88SJack F Vogel /** 16672969bf0eSJack F Vogel * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum 166813705f88SJack F Vogel * @hw: pointer to hardware structure 166913705f88SJack F Vogel **/ 16702969bf0eSJack F Vogel u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) 167113705f88SJack F Vogel { 167213705f88SJack F Vogel u16 i; 167313705f88SJack F Vogel u16 j; 167413705f88SJack F Vogel u16 checksum = 0; 167513705f88SJack F Vogel u16 length = 0; 167613705f88SJack F Vogel u16 pointer = 0; 167713705f88SJack F Vogel u16 word = 0; 167813705f88SJack F Vogel 16792969bf0eSJack F Vogel DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic"); 16802969bf0eSJack F Vogel 168113705f88SJack F Vogel /* Include 0x0-0x3F in the checksum */ 168213705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 16839ca4041bSJack F Vogel if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) { 168413705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 168513705f88SJack F Vogel break; 168613705f88SJack F Vogel } 168713705f88SJack F Vogel checksum += word; 168813705f88SJack F Vogel } 168913705f88SJack F Vogel 169013705f88SJack F Vogel /* Include all data from pointers except for the fw pointer */ 169113705f88SJack F Vogel for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 16929ca4041bSJack F Vogel hw->eeprom.ops.read(hw, i, &pointer); 169313705f88SJack F Vogel 169413705f88SJack F Vogel /* Make sure the pointer seems valid */ 169513705f88SJack F Vogel if (pointer != 0xFFFF && pointer != 0) { 16969ca4041bSJack F Vogel hw->eeprom.ops.read(hw, pointer, &length); 169713705f88SJack F Vogel 169813705f88SJack F Vogel if (length != 0xFFFF && length != 0) { 169913705f88SJack F Vogel for (j = pointer+1; j <= pointer+length; j++) { 17009ca4041bSJack F Vogel hw->eeprom.ops.read(hw, j, &word); 170113705f88SJack F Vogel checksum += word; 170213705f88SJack F Vogel } 170313705f88SJack F Vogel } 170413705f88SJack F Vogel } 170513705f88SJack F Vogel } 170613705f88SJack F Vogel 170713705f88SJack F Vogel checksum = (u16)IXGBE_EEPROM_SUM - checksum; 170813705f88SJack F Vogel 170913705f88SJack F Vogel return checksum; 171013705f88SJack F Vogel } 171113705f88SJack F Vogel 171213705f88SJack F Vogel /** 171313705f88SJack F Vogel * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum 171413705f88SJack F Vogel * @hw: pointer to hardware structure 171513705f88SJack F Vogel * @checksum_val: calculated checksum 171613705f88SJack F Vogel * 171713705f88SJack F Vogel * Performs checksum calculation and validates the EEPROM checksum. If the 171813705f88SJack F Vogel * caller does not need checksum_val, the value can be NULL. 171913705f88SJack F Vogel **/ 172013705f88SJack F Vogel s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, 172113705f88SJack F Vogel u16 *checksum_val) 172213705f88SJack F Vogel { 172313705f88SJack F Vogel s32 status; 172413705f88SJack F Vogel u16 checksum; 172513705f88SJack F Vogel u16 read_checksum = 0; 172613705f88SJack F Vogel 17272969bf0eSJack F Vogel DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic"); 17282969bf0eSJack F Vogel 172913705f88SJack F Vogel /* 173013705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 173113705f88SJack F Vogel * not continue or we could be in for a very long wait while every 173213705f88SJack F Vogel * EEPROM read fails 173313705f88SJack F Vogel */ 17349ca4041bSJack F Vogel status = hw->eeprom.ops.read(hw, 0, &checksum); 173513705f88SJack F Vogel 173613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 17372969bf0eSJack F Vogel checksum = hw->eeprom.ops.calc_checksum(hw); 173813705f88SJack F Vogel 17399ca4041bSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); 174013705f88SJack F Vogel 174113705f88SJack F Vogel /* 174213705f88SJack F Vogel * Verify read checksum from EEPROM is the same as 174313705f88SJack F Vogel * calculated checksum 174413705f88SJack F Vogel */ 17459ca4041bSJack F Vogel if (read_checksum != checksum) 174613705f88SJack F Vogel status = IXGBE_ERR_EEPROM_CHECKSUM; 174713705f88SJack F Vogel 174813705f88SJack F Vogel /* If the user cares, return the calculated checksum */ 17499ca4041bSJack F Vogel if (checksum_val) 175013705f88SJack F Vogel *checksum_val = checksum; 175113705f88SJack F Vogel } else { 175213705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 175313705f88SJack F Vogel } 175413705f88SJack F Vogel 175513705f88SJack F Vogel return status; 175613705f88SJack F Vogel } 175713705f88SJack F Vogel 175813705f88SJack F Vogel /** 17599ca4041bSJack F Vogel * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum 176013705f88SJack F Vogel * @hw: pointer to hardware structure 176113705f88SJack F Vogel **/ 176213705f88SJack F Vogel s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) 176313705f88SJack F Vogel { 176413705f88SJack F Vogel s32 status; 176513705f88SJack F Vogel u16 checksum; 176613705f88SJack F Vogel 17672969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_eeprom_checksum_generic"); 17682969bf0eSJack F Vogel 176913705f88SJack F Vogel /* 177013705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 177113705f88SJack F Vogel * not continue or we could be in for a very long wait while every 177213705f88SJack F Vogel * EEPROM read fails 177313705f88SJack F Vogel */ 17749ca4041bSJack F Vogel status = hw->eeprom.ops.read(hw, 0, &checksum); 177513705f88SJack F Vogel 177613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 17772969bf0eSJack F Vogel checksum = hw->eeprom.ops.calc_checksum(hw); 17789ca4041bSJack F Vogel status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, 177913705f88SJack F Vogel checksum); 178013705f88SJack F Vogel } else { 178113705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 178213705f88SJack F Vogel } 178313705f88SJack F Vogel 178413705f88SJack F Vogel return status; 178513705f88SJack F Vogel } 178613705f88SJack F Vogel 178713705f88SJack F Vogel /** 178813705f88SJack F Vogel * ixgbe_validate_mac_addr - Validate MAC address 178913705f88SJack F Vogel * @mac_addr: pointer to MAC address. 179013705f88SJack F Vogel * 179113705f88SJack F Vogel * Tests a MAC address to ensure it is a valid Individual Address 179213705f88SJack F Vogel **/ 179313705f88SJack F Vogel s32 ixgbe_validate_mac_addr(u8 *mac_addr) 179413705f88SJack F Vogel { 179513705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 179613705f88SJack F Vogel 17972969bf0eSJack F Vogel DEBUGFUNC("ixgbe_validate_mac_addr"); 17982969bf0eSJack F Vogel 179913705f88SJack F Vogel /* Make sure it is not a multicast address */ 180013705f88SJack F Vogel if (IXGBE_IS_MULTICAST(mac_addr)) { 180113705f88SJack F Vogel DEBUGOUT("MAC address is multicast\n"); 180213705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 180313705f88SJack F Vogel /* Not a broadcast address */ 180413705f88SJack F Vogel } else if (IXGBE_IS_BROADCAST(mac_addr)) { 180513705f88SJack F Vogel DEBUGOUT("MAC address is broadcast\n"); 180613705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 180713705f88SJack F Vogel /* Reject the zero address */ 180813705f88SJack F Vogel } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && 180913705f88SJack F Vogel mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { 181013705f88SJack F Vogel DEBUGOUT("MAC address is all zeros\n"); 181113705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 181213705f88SJack F Vogel } 181313705f88SJack F Vogel return status; 181413705f88SJack F Vogel } 181513705f88SJack F Vogel 181613705f88SJack F Vogel /** 18179ca4041bSJack F Vogel * ixgbe_set_rar_generic - Set Rx address register 181813705f88SJack F Vogel * @hw: pointer to hardware structure 181913705f88SJack F Vogel * @index: Receive address register to write 18209ca4041bSJack F Vogel * @addr: Address to put into receive address register 18219ca4041bSJack F Vogel * @vmdq: VMDq "set" or "pool" index 182213705f88SJack F Vogel * @enable_addr: set flag that address is active 182313705f88SJack F Vogel * 182413705f88SJack F Vogel * Puts an ethernet address into a receive address register. 182513705f88SJack F Vogel **/ 18269ca4041bSJack F Vogel s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, 182713705f88SJack F Vogel u32 enable_addr) 182813705f88SJack F Vogel { 182913705f88SJack F Vogel u32 rar_low, rar_high; 18309ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 183113705f88SJack F Vogel 18322969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_rar_generic"); 18332969bf0eSJack F Vogel 18341a4e3449SJack F Vogel /* Make sure we are using a valid rar index range */ 18351a4e3449SJack F Vogel if (index >= rar_entries) { 18361a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", index); 18371a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 18381a4e3449SJack F Vogel } 18391a4e3449SJack F Vogel 18409ca4041bSJack F Vogel /* setup VMDq pool selection before this RAR gets enabled */ 18419ca4041bSJack F Vogel hw->mac.ops.set_vmdq(hw, index, vmdq); 18429ca4041bSJack F Vogel 184313705f88SJack F Vogel /* 18449ca4041bSJack F Vogel * HW expects these in little endian so we reverse the byte 18459ca4041bSJack F Vogel * order from network order (big endian) to little endian 184613705f88SJack F Vogel */ 184713705f88SJack F Vogel rar_low = ((u32)addr[0] | 184813705f88SJack F Vogel ((u32)addr[1] << 8) | 184913705f88SJack F Vogel ((u32)addr[2] << 16) | 185013705f88SJack F Vogel ((u32)addr[3] << 24)); 18519ca4041bSJack F Vogel /* 18529ca4041bSJack F Vogel * Some parts put the VMDq setting in the extra RAH bits, 18539ca4041bSJack F Vogel * so save everything except the lower 16 bits that hold part 18549ca4041bSJack F Vogel * of the address and the address valid bit. 18559ca4041bSJack F Vogel */ 18569ca4041bSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 18579ca4041bSJack F Vogel rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); 18589ca4041bSJack F Vogel rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); 185913705f88SJack F Vogel 186013705f88SJack F Vogel if (enable_addr != 0) 186113705f88SJack F Vogel rar_high |= IXGBE_RAH_AV; 186213705f88SJack F Vogel 186313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); 186413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 186513705f88SJack F Vogel 186613705f88SJack F Vogel return IXGBE_SUCCESS; 186713705f88SJack F Vogel } 186813705f88SJack F Vogel 186913705f88SJack F Vogel /** 18705b7f4cedSJack F Vogel * ixgbe_clear_rar_generic - Remove Rx address register 18715b7f4cedSJack F Vogel * @hw: pointer to hardware structure 18725b7f4cedSJack F Vogel * @index: Receive address register to write 18735b7f4cedSJack F Vogel * 18745b7f4cedSJack F Vogel * Clears an ethernet address from a receive address register. 18755b7f4cedSJack F Vogel **/ 18765b7f4cedSJack F Vogel s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) 18775b7f4cedSJack F Vogel { 18785b7f4cedSJack F Vogel u32 rar_high; 18795b7f4cedSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 18805b7f4cedSJack F Vogel 18812969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_rar_generic"); 18822969bf0eSJack F Vogel 18835b7f4cedSJack F Vogel /* Make sure we are using a valid rar index range */ 18841a4e3449SJack F Vogel if (index >= rar_entries) { 18851a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", index); 18861a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 18871a4e3449SJack F Vogel } 18881a4e3449SJack F Vogel 18895b7f4cedSJack F Vogel /* 18905b7f4cedSJack F Vogel * Some parts put the VMDq setting in the extra RAH bits, 18915b7f4cedSJack F Vogel * so save everything except the lower 16 bits that hold part 18925b7f4cedSJack F Vogel * of the address and the address valid bit. 18935b7f4cedSJack F Vogel */ 18945b7f4cedSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 18955b7f4cedSJack F Vogel rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); 18965b7f4cedSJack F Vogel 18975b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); 18985b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 18995b7f4cedSJack F Vogel 19005b7f4cedSJack F Vogel /* clear VMDq pool/queue selection for this RAR */ 19015b7f4cedSJack F Vogel hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL); 19025b7f4cedSJack F Vogel 19035b7f4cedSJack F Vogel return IXGBE_SUCCESS; 19045b7f4cedSJack F Vogel } 19055b7f4cedSJack F Vogel 19065b7f4cedSJack F Vogel /** 190713705f88SJack F Vogel * ixgbe_init_rx_addrs_generic - Initializes receive address filters. 190813705f88SJack F Vogel * @hw: pointer to hardware structure 190913705f88SJack F Vogel * 191013705f88SJack F Vogel * Places the MAC address in receive address register 0 and clears the rest 19119ca4041bSJack F Vogel * of the receive address registers. Clears the multicast table. Assumes 191213705f88SJack F Vogel * the receiver is in reset when the routine is called. 191313705f88SJack F Vogel **/ 191413705f88SJack F Vogel s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) 191513705f88SJack F Vogel { 191613705f88SJack F Vogel u32 i; 19179ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 191813705f88SJack F Vogel 19192969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_rx_addrs_generic"); 19202969bf0eSJack F Vogel 192113705f88SJack F Vogel /* 192213705f88SJack F Vogel * If the current mac address is valid, assume it is a software override 192313705f88SJack F Vogel * to the permanent address. 192413705f88SJack F Vogel * Otherwise, use the permanent address from the eeprom. 192513705f88SJack F Vogel */ 192613705f88SJack F Vogel if (ixgbe_validate_mac_addr(hw->mac.addr) == 192713705f88SJack F Vogel IXGBE_ERR_INVALID_MAC_ADDR) { 192813705f88SJack F Vogel /* Get the MAC address from the RAR0 for later reference */ 19299ca4041bSJack F Vogel hw->mac.ops.get_mac_addr(hw, hw->mac.addr); 193013705f88SJack F Vogel 193113705f88SJack F Vogel DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ", 193213705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 193313705f88SJack F Vogel hw->mac.addr[2]); 193413705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 193513705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 193613705f88SJack F Vogel } else { 193713705f88SJack F Vogel /* Setup the receive address. */ 193813705f88SJack F Vogel DEBUGOUT("Overriding MAC Address in RAR[0]\n"); 193913705f88SJack F Vogel DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ", 194013705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 194113705f88SJack F Vogel hw->mac.addr[2]); 194213705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 194313705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 194413705f88SJack F Vogel 19459ca4041bSJack F Vogel hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); 1946182b3808SJack F Vogel 1947182b3808SJack F Vogel /* clear VMDq pool/queue selection for RAR 0 */ 1948182b3808SJack F Vogel hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); 194913705f88SJack F Vogel } 19509ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc = 0; 195113705f88SJack F Vogel 195213705f88SJack F Vogel hw->addr_ctrl.rar_used_count = 1; 195313705f88SJack F Vogel 195413705f88SJack F Vogel /* Zero out the other receive addresses. */ 19559ca4041bSJack F Vogel DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1); 195613705f88SJack F Vogel for (i = 1; i < rar_entries; i++) { 195713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); 195813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); 195913705f88SJack F Vogel } 196013705f88SJack F Vogel 196113705f88SJack F Vogel /* Clear the MTA */ 196213705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 196313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 196413705f88SJack F Vogel 196513705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 19669ca4041bSJack F Vogel for (i = 0; i < hw->mac.mcft_size; i++) 196713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); 196813705f88SJack F Vogel 19695b7f4cedSJack F Vogel ixgbe_init_uta_tables(hw); 19705b7f4cedSJack F Vogel 197113705f88SJack F Vogel return IXGBE_SUCCESS; 197213705f88SJack F Vogel } 197313705f88SJack F Vogel 197413705f88SJack F Vogel /** 19759ca4041bSJack F Vogel * ixgbe_add_uc_addr - Adds a secondary unicast address. 19769ca4041bSJack F Vogel * @hw: pointer to hardware structure 19779ca4041bSJack F Vogel * @addr: new address 19789ca4041bSJack F Vogel * 19799ca4041bSJack F Vogel * Adds it to unused receive address register or goes into promiscuous mode. 19809ca4041bSJack F Vogel **/ 19819ca4041bSJack F Vogel void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) 19829ca4041bSJack F Vogel { 19839ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 19849ca4041bSJack F Vogel u32 rar; 19859ca4041bSJack F Vogel 19862969bf0eSJack F Vogel DEBUGFUNC("ixgbe_add_uc_addr"); 19872969bf0eSJack F Vogel 19889ca4041bSJack F Vogel DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", 19899ca4041bSJack F Vogel addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 19909ca4041bSJack F Vogel 19919ca4041bSJack F Vogel /* 19929ca4041bSJack F Vogel * Place this address in the RAR if there is room, 19939ca4041bSJack F Vogel * else put the controller into promiscuous mode 19949ca4041bSJack F Vogel */ 19959ca4041bSJack F Vogel if (hw->addr_ctrl.rar_used_count < rar_entries) { 19960ac6dfecSJack F Vogel rar = hw->addr_ctrl.rar_used_count; 19979ca4041bSJack F Vogel hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 19989ca4041bSJack F Vogel DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar); 19999ca4041bSJack F Vogel hw->addr_ctrl.rar_used_count++; 20009ca4041bSJack F Vogel } else { 20019ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc++; 20029ca4041bSJack F Vogel } 20039ca4041bSJack F Vogel 20049ca4041bSJack F Vogel DEBUGOUT("ixgbe_add_uc_addr Complete\n"); 20059ca4041bSJack F Vogel } 20069ca4041bSJack F Vogel 20079ca4041bSJack F Vogel /** 20089ca4041bSJack F Vogel * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses 20099ca4041bSJack F Vogel * @hw: pointer to hardware structure 20109ca4041bSJack F Vogel * @addr_list: the list of new addresses 20119ca4041bSJack F Vogel * @addr_count: number of addresses 20129ca4041bSJack F Vogel * @next: iterator function to walk the address list 20139ca4041bSJack F Vogel * 20149ca4041bSJack F Vogel * The given list replaces any existing list. Clears the secondary addrs from 20159ca4041bSJack F Vogel * receive address registers. Uses unused receive address registers for the 20169ca4041bSJack F Vogel * first secondary addresses, and falls back to promiscuous mode as needed. 20179ca4041bSJack F Vogel * 20189ca4041bSJack F Vogel * Drivers using secondary unicast addresses must set user_set_promisc when 20199ca4041bSJack F Vogel * manually putting the device into promiscuous mode. 20209ca4041bSJack F Vogel **/ 20219ca4041bSJack F Vogel s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, 20229ca4041bSJack F Vogel u32 addr_count, ixgbe_mc_addr_itr next) 20239ca4041bSJack F Vogel { 20249ca4041bSJack F Vogel u8 *addr; 20259ca4041bSJack F Vogel u32 i; 20269ca4041bSJack F Vogel u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; 20279ca4041bSJack F Vogel u32 uc_addr_in_use; 20289ca4041bSJack F Vogel u32 fctrl; 20299ca4041bSJack F Vogel u32 vmdq; 20309ca4041bSJack F Vogel 20312969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_uc_addr_list_generic"); 20322969bf0eSJack F Vogel 20339ca4041bSJack F Vogel /* 20349ca4041bSJack F Vogel * Clear accounting of old secondary address list, 20359ca4041bSJack F Vogel * don't count RAR[0] 20369ca4041bSJack F Vogel */ 20370ac6dfecSJack F Vogel uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1; 20389ca4041bSJack F Vogel hw->addr_ctrl.rar_used_count -= uc_addr_in_use; 20399ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc = 0; 20409ca4041bSJack F Vogel 20419ca4041bSJack F Vogel /* Zero out the other receive addresses */ 20422969bf0eSJack F Vogel DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use+1); 20432969bf0eSJack F Vogel for (i = 0; i < uc_addr_in_use; i++) { 20442969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0); 20452969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0); 20469ca4041bSJack F Vogel } 20479ca4041bSJack F Vogel 20489ca4041bSJack F Vogel /* Add the new addresses */ 20499ca4041bSJack F Vogel for (i = 0; i < addr_count; i++) { 20509ca4041bSJack F Vogel DEBUGOUT(" Adding the secondary addresses:\n"); 20519ca4041bSJack F Vogel addr = next(hw, &addr_list, &vmdq); 20529ca4041bSJack F Vogel ixgbe_add_uc_addr(hw, addr, vmdq); 20539ca4041bSJack F Vogel } 20549ca4041bSJack F Vogel 20559ca4041bSJack F Vogel if (hw->addr_ctrl.overflow_promisc) { 20569ca4041bSJack F Vogel /* enable promisc if not already in overflow or set by user */ 20579ca4041bSJack F Vogel if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { 20589ca4041bSJack F Vogel DEBUGOUT(" Entering address overflow promisc mode\n"); 20599ca4041bSJack F Vogel fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 20609ca4041bSJack F Vogel fctrl |= IXGBE_FCTRL_UPE; 20619ca4041bSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 20629ca4041bSJack F Vogel } 20639ca4041bSJack F Vogel } else { 20649ca4041bSJack F Vogel /* only disable if set by overflow, not by user */ 20659ca4041bSJack F Vogel if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { 20669ca4041bSJack F Vogel DEBUGOUT(" Leaving address overflow promisc mode\n"); 20679ca4041bSJack F Vogel fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 20689ca4041bSJack F Vogel fctrl &= ~IXGBE_FCTRL_UPE; 20699ca4041bSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 20709ca4041bSJack F Vogel } 20719ca4041bSJack F Vogel } 20729ca4041bSJack F Vogel 20739ca4041bSJack F Vogel DEBUGOUT("ixgbe_update_uc_addr_list_generic Complete\n"); 20749ca4041bSJack F Vogel return IXGBE_SUCCESS; 20759ca4041bSJack F Vogel } 20769ca4041bSJack F Vogel 20779ca4041bSJack F Vogel /** 207813705f88SJack F Vogel * ixgbe_mta_vector - Determines bit-vector in multicast table to set 207913705f88SJack F Vogel * @hw: pointer to hardware structure 208013705f88SJack F Vogel * @mc_addr: the multicast address 208113705f88SJack F Vogel * 208213705f88SJack F Vogel * Extracts the 12 bits, from a multicast address, to determine which 208313705f88SJack F Vogel * bit-vector to set in the multicast table. The hardware uses 12 bits, from 208413705f88SJack F Vogel * incoming rx multicast addresses, to determine the bit-vector to check in 208513705f88SJack F Vogel * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set 20869ca4041bSJack F Vogel * by the MO field of the MCSTCTRL. The MO field is set during initialization 208713705f88SJack F Vogel * to mc_filter_type. 208813705f88SJack F Vogel **/ 208913705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) 209013705f88SJack F Vogel { 209113705f88SJack F Vogel u32 vector = 0; 209213705f88SJack F Vogel 20932969bf0eSJack F Vogel DEBUGFUNC("ixgbe_mta_vector"); 20942969bf0eSJack F Vogel 209513705f88SJack F Vogel switch (hw->mac.mc_filter_type) { 209613705f88SJack F Vogel case 0: /* use bits [47:36] of the address */ 209713705f88SJack F Vogel vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); 209813705f88SJack F Vogel break; 209913705f88SJack F Vogel case 1: /* use bits [46:35] of the address */ 210013705f88SJack F Vogel vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); 210113705f88SJack F Vogel break; 210213705f88SJack F Vogel case 2: /* use bits [45:34] of the address */ 210313705f88SJack F Vogel vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); 210413705f88SJack F Vogel break; 210513705f88SJack F Vogel case 3: /* use bits [43:32] of the address */ 210613705f88SJack F Vogel vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); 210713705f88SJack F Vogel break; 210813705f88SJack F Vogel default: /* Invalid mc_filter_type */ 210913705f88SJack F Vogel DEBUGOUT("MC filter type param set incorrectly\n"); 211013705f88SJack F Vogel ASSERT(0); 211113705f88SJack F Vogel break; 211213705f88SJack F Vogel } 211313705f88SJack F Vogel 211413705f88SJack F Vogel /* vector can only be 12-bits or boundary will be exceeded */ 211513705f88SJack F Vogel vector &= 0xFFF; 211613705f88SJack F Vogel return vector; 211713705f88SJack F Vogel } 211813705f88SJack F Vogel 211913705f88SJack F Vogel /** 212013705f88SJack F Vogel * ixgbe_set_mta - Set bit-vector in multicast table 212113705f88SJack F Vogel * @hw: pointer to hardware structure 212213705f88SJack F Vogel * @hash_value: Multicast address hash value 212313705f88SJack F Vogel * 212413705f88SJack F Vogel * Sets the bit-vector in the multicast table. 212513705f88SJack F Vogel **/ 212613705f88SJack F Vogel void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) 212713705f88SJack F Vogel { 212813705f88SJack F Vogel u32 vector; 212913705f88SJack F Vogel u32 vector_bit; 213013705f88SJack F Vogel u32 vector_reg; 213113705f88SJack F Vogel 21322969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_mta"); 21332969bf0eSJack F Vogel 213413705f88SJack F Vogel hw->addr_ctrl.mta_in_use++; 213513705f88SJack F Vogel 213613705f88SJack F Vogel vector = ixgbe_mta_vector(hw, mc_addr); 213713705f88SJack F Vogel DEBUGOUT1(" bit-vector = 0x%03X\n", vector); 213813705f88SJack F Vogel 213913705f88SJack F Vogel /* 214013705f88SJack F Vogel * The MTA is a register array of 128 32-bit registers. It is treated 214113705f88SJack F Vogel * like an array of 4096 bits. We want to set bit 214213705f88SJack F Vogel * BitArray[vector_value]. So we figure out what register the bit is 214313705f88SJack F Vogel * in, read it, OR in the new bit, then write back the new value. The 214413705f88SJack F Vogel * register is determined by the upper 7 bits of the vector value and 214513705f88SJack F Vogel * the bit within that register are determined by the lower 5 bits of 214613705f88SJack F Vogel * the value. 214713705f88SJack F Vogel */ 214813705f88SJack F Vogel vector_reg = (vector >> 5) & 0x7F; 214913705f88SJack F Vogel vector_bit = vector & 0x1F; 21501a4e3449SJack F Vogel hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); 215113705f88SJack F Vogel } 215213705f88SJack F Vogel 215313705f88SJack F Vogel /** 215413705f88SJack F Vogel * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses 215513705f88SJack F Vogel * @hw: pointer to hardware structure 215613705f88SJack F Vogel * @mc_addr_list: the list of new multicast addresses 215713705f88SJack F Vogel * @mc_addr_count: number of addresses 21589ca4041bSJack F Vogel * @next: iterator function to walk the multicast address list 2159*85d0a26eSJack F Vogel * @clear: flag, when set clears the table beforehand 216013705f88SJack F Vogel * 2161*85d0a26eSJack F Vogel * When the clear flag is set, the given list replaces any existing list. 2162*85d0a26eSJack F Vogel * Hashes the given addresses into the multicast table. 216313705f88SJack F Vogel **/ 216413705f88SJack F Vogel s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, 2165*85d0a26eSJack F Vogel u32 mc_addr_count, ixgbe_mc_addr_itr next, 2166*85d0a26eSJack F Vogel bool clear) 216713705f88SJack F Vogel { 216813705f88SJack F Vogel u32 i; 21699ca4041bSJack F Vogel u32 vmdq; 217013705f88SJack F Vogel 21712969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_mc_addr_list_generic"); 21722969bf0eSJack F Vogel 217313705f88SJack F Vogel /* 217413705f88SJack F Vogel * Set the new number of MC addresses that we are being requested to 217513705f88SJack F Vogel * use. 217613705f88SJack F Vogel */ 217713705f88SJack F Vogel hw->addr_ctrl.num_mc_addrs = mc_addr_count; 217813705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 217913705f88SJack F Vogel 21801a4e3449SJack F Vogel /* Clear mta_shadow */ 2181*85d0a26eSJack F Vogel if (clear) { 218213705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 21831a4e3449SJack F Vogel memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); 2184*85d0a26eSJack F Vogel } 218513705f88SJack F Vogel 21861a4e3449SJack F Vogel /* Update mta_shadow */ 218713705f88SJack F Vogel for (i = 0; i < mc_addr_count; i++) { 218813705f88SJack F Vogel DEBUGOUT(" Adding the multicast addresses:\n"); 21890ac6dfecSJack F Vogel ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); 219013705f88SJack F Vogel } 219113705f88SJack F Vogel 219213705f88SJack F Vogel /* Enable mta */ 21931a4e3449SJack F Vogel for (i = 0; i < hw->mac.mcft_size; i++) 21941a4e3449SJack F Vogel IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i, 21951a4e3449SJack F Vogel hw->mac.mta_shadow[i]); 21961a4e3449SJack F Vogel 219713705f88SJack F Vogel if (hw->addr_ctrl.mta_in_use > 0) 219813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, 219913705f88SJack F Vogel IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); 220013705f88SJack F Vogel 220113705f88SJack F Vogel DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n"); 220213705f88SJack F Vogel return IXGBE_SUCCESS; 220313705f88SJack F Vogel } 220413705f88SJack F Vogel 220513705f88SJack F Vogel /** 220613705f88SJack F Vogel * ixgbe_enable_mc_generic - Enable multicast address in RAR 220713705f88SJack F Vogel * @hw: pointer to hardware structure 220813705f88SJack F Vogel * 220913705f88SJack F Vogel * Enables multicast address in RAR and the use of the multicast hash table. 221013705f88SJack F Vogel **/ 221113705f88SJack F Vogel s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) 221213705f88SJack F Vogel { 221313705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 221413705f88SJack F Vogel 22152969bf0eSJack F Vogel DEBUGFUNC("ixgbe_enable_mc_generic"); 22162969bf0eSJack F Vogel 221713705f88SJack F Vogel if (a->mta_in_use > 0) 221813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | 221913705f88SJack F Vogel hw->mac.mc_filter_type); 222013705f88SJack F Vogel 222113705f88SJack F Vogel return IXGBE_SUCCESS; 222213705f88SJack F Vogel } 222313705f88SJack F Vogel 222413705f88SJack F Vogel /** 22259ca4041bSJack F Vogel * ixgbe_disable_mc_generic - Disable multicast address in RAR 222613705f88SJack F Vogel * @hw: pointer to hardware structure 222713705f88SJack F Vogel * 222813705f88SJack F Vogel * Disables multicast address in RAR and the use of the multicast hash table. 222913705f88SJack F Vogel **/ 223013705f88SJack F Vogel s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) 223113705f88SJack F Vogel { 223213705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 223313705f88SJack F Vogel 22342969bf0eSJack F Vogel DEBUGFUNC("ixgbe_disable_mc_generic"); 22352969bf0eSJack F Vogel 223613705f88SJack F Vogel if (a->mta_in_use > 0) 223713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 223813705f88SJack F Vogel 223913705f88SJack F Vogel return IXGBE_SUCCESS; 224013705f88SJack F Vogel } 224113705f88SJack F Vogel 22421b6e0dbaSJack F Vogel /** 22430ac6dfecSJack F Vogel * ixgbe_fc_enable_generic - Enable flow control 22441b6e0dbaSJack F Vogel * @hw: pointer to hardware structure 22450ac6dfecSJack F Vogel * @packetbuf_num: packet buffer number (0-7) 22461b6e0dbaSJack F Vogel * 22470ac6dfecSJack F Vogel * Enable flow control according to the current settings. 22481b6e0dbaSJack F Vogel **/ 22490ac6dfecSJack F Vogel s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) 22501b6e0dbaSJack F Vogel { 22511b6e0dbaSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 22520ac6dfecSJack F Vogel u32 mflcn_reg, fccfg_reg; 22530ac6dfecSJack F Vogel u32 reg; 22541a4e3449SJack F Vogel u32 fcrtl, fcrth; 22551b6e0dbaSJack F Vogel 22560ac6dfecSJack F Vogel DEBUGFUNC("ixgbe_fc_enable_generic"); 22571b6e0dbaSJack F Vogel 22580ac6dfecSJack F Vogel /* Negotiate the fc mode to use */ 22590ac6dfecSJack F Vogel ret_val = ixgbe_fc_autoneg(hw); 22601a4e3449SJack F Vogel if (ret_val == IXGBE_ERR_FLOW_CONTROL) 22610ac6dfecSJack F Vogel goto out; 22620ac6dfecSJack F Vogel 22630ac6dfecSJack F Vogel /* Disable any previous flow control settings */ 22640ac6dfecSJack F Vogel mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); 22650ac6dfecSJack F Vogel mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE); 22660ac6dfecSJack F Vogel 22670ac6dfecSJack F Vogel fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); 22680ac6dfecSJack F Vogel fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); 22691b6e0dbaSJack F Vogel 22701b6e0dbaSJack F Vogel /* 22711b6e0dbaSJack F Vogel * The possible values of fc.current_mode are: 22721b6e0dbaSJack F Vogel * 0: Flow control is completely disabled 22731b6e0dbaSJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames, 22741b6e0dbaSJack F Vogel * but not send pause frames). 22751b6e0dbaSJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but 22761b6e0dbaSJack F Vogel * we do not support receiving pause frames). 22771b6e0dbaSJack F Vogel * 3: Both Rx and Tx flow control (symmetric) are enabled. 22781b6e0dbaSJack F Vogel * other: Invalid. 22791b6e0dbaSJack F Vogel */ 22801b6e0dbaSJack F Vogel switch (hw->fc.current_mode) { 22811b6e0dbaSJack F Vogel case ixgbe_fc_none: 22821a4e3449SJack F Vogel /* 22831a4e3449SJack F Vogel * Flow control is disabled by software override or autoneg. 22840ac6dfecSJack F Vogel * The code below will actually disable it in the HW. 22850ac6dfecSJack F Vogel */ 22861b6e0dbaSJack F Vogel break; 22871b6e0dbaSJack F Vogel case ixgbe_fc_rx_pause: 22881b6e0dbaSJack F Vogel /* 22891b6e0dbaSJack F Vogel * Rx Flow control is enabled and Tx Flow control is 22901b6e0dbaSJack F Vogel * disabled by software override. Since there really 22911b6e0dbaSJack F Vogel * isn't a way to advertise that we are capable of RX 22921b6e0dbaSJack F Vogel * Pause ONLY, we will advertise that we support both 22931b6e0dbaSJack F Vogel * symmetric and asymmetric Rx PAUSE. Later, we will 22941b6e0dbaSJack F Vogel * disable the adapter's ability to send PAUSE frames. 22951b6e0dbaSJack F Vogel */ 22960ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_RFCE; 22971b6e0dbaSJack F Vogel break; 22981b6e0dbaSJack F Vogel case ixgbe_fc_tx_pause: 22991b6e0dbaSJack F Vogel /* 23001b6e0dbaSJack F Vogel * Tx Flow control is enabled, and Rx Flow control is 23011b6e0dbaSJack F Vogel * disabled by software override. 23021b6e0dbaSJack F Vogel */ 23030ac6dfecSJack F Vogel fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; 23041b6e0dbaSJack F Vogel break; 23051b6e0dbaSJack F Vogel case ixgbe_fc_full: 23061b6e0dbaSJack F Vogel /* Flow control (both Rx and Tx) is enabled by SW override. */ 23070ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_RFCE; 23080ac6dfecSJack F Vogel fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; 23091b6e0dbaSJack F Vogel break; 23101b6e0dbaSJack F Vogel default: 23111b6e0dbaSJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 23122969bf0eSJack F Vogel ret_val = IXGBE_ERR_CONFIG; 23131b6e0dbaSJack F Vogel goto out; 23141b6e0dbaSJack F Vogel break; 23151b6e0dbaSJack F Vogel } 23161b6e0dbaSJack F Vogel 23170ac6dfecSJack F Vogel /* Set 802.3x based flow control settings. */ 23180ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_DPF; 23190ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); 23200ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); 23211b6e0dbaSJack F Vogel 2322*85d0a26eSJack F Vogel fcrth = hw->fc.high_water[packetbuf_num] << 10; 2323*85d0a26eSJack F Vogel fcrtl = hw->fc.low_water << 10; 2324d8602bb9SJack F Vogel 23250ac6dfecSJack F Vogel if (hw->fc.current_mode & ixgbe_fc_tx_pause) { 23261a4e3449SJack F Vogel fcrth |= IXGBE_FCRTH_FCEN; 23271a4e3449SJack F Vogel if (hw->fc.send_xon) 23281a4e3449SJack F Vogel fcrtl |= IXGBE_FCRTL_XONE; 23291b6e0dbaSJack F Vogel } 23301b6e0dbaSJack F Vogel 23311a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth); 23321a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl); 23330ac6dfecSJack F Vogel 23340ac6dfecSJack F Vogel /* Configure pause time (2 TCs per register) */ 2335d8602bb9SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); 23360ac6dfecSJack F Vogel if ((packetbuf_num & 1) == 0) 23370ac6dfecSJack F Vogel reg = (reg & 0xFFFF0000) | hw->fc.pause_time; 23380ac6dfecSJack F Vogel else 23390ac6dfecSJack F Vogel reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16); 23400ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg); 23410ac6dfecSJack F Vogel 23420ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); 23430ac6dfecSJack F Vogel 23440ac6dfecSJack F Vogel out: 23450ac6dfecSJack F Vogel return ret_val; 23460ac6dfecSJack F Vogel } 23470ac6dfecSJack F Vogel 23480ac6dfecSJack F Vogel /** 23490ac6dfecSJack F Vogel * ixgbe_fc_autoneg - Configure flow control 23500ac6dfecSJack F Vogel * @hw: pointer to hardware structure 23510ac6dfecSJack F Vogel * 23520ac6dfecSJack F Vogel * Compares our advertised flow control capabilities to those advertised by 23530ac6dfecSJack F Vogel * our link partner, and determines the proper flow control mode to use. 23540ac6dfecSJack F Vogel **/ 23550ac6dfecSJack F Vogel s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) 23560ac6dfecSJack F Vogel { 23571a4e3449SJack F Vogel s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 23580ac6dfecSJack F Vogel ixgbe_link_speed speed; 23590ac6dfecSJack F Vogel bool link_up; 23600ac6dfecSJack F Vogel 23610ac6dfecSJack F Vogel DEBUGFUNC("ixgbe_fc_autoneg"); 23620ac6dfecSJack F Vogel 23631a4e3449SJack F Vogel if (hw->fc.disable_fc_autoneg) 23641a4e3449SJack F Vogel goto out; 23651a4e3449SJack F Vogel 23660ac6dfecSJack F Vogel /* 23670ac6dfecSJack F Vogel * AN should have completed when the cable was plugged in. 23680ac6dfecSJack F Vogel * Look for reasons to bail out. Bail out if: 23690ac6dfecSJack F Vogel * - FC autoneg is disabled, or if 23702969bf0eSJack F Vogel * - link is not up. 23710ac6dfecSJack F Vogel * 23722969bf0eSJack F Vogel * Since we're being called from an LSC, link is already known to be up. 23730ac6dfecSJack F Vogel * So use link_up_wait_to_complete=FALSE. 23740ac6dfecSJack F Vogel */ 23750ac6dfecSJack F Vogel hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 23761a4e3449SJack F Vogel if (!link_up) { 23771a4e3449SJack F Vogel ret_val = IXGBE_ERR_FLOW_CONTROL; 23782969bf0eSJack F Vogel goto out; 23792969bf0eSJack F Vogel } 23802969bf0eSJack F Vogel 23811a4e3449SJack F Vogel switch (hw->phy.media_type) { 23821a4e3449SJack F Vogel /* Autoneg flow control on fiber adapters */ 23831a4e3449SJack F Vogel case ixgbe_media_type_fiber: 23841a4e3449SJack F Vogel if (speed == IXGBE_LINK_SPEED_1GB_FULL) 23851a4e3449SJack F Vogel ret_val = ixgbe_fc_autoneg_fiber(hw); 23861a4e3449SJack F Vogel break; 23871a4e3449SJack F Vogel 23881a4e3449SJack F Vogel /* Autoneg flow control on backplane adapters */ 23891a4e3449SJack F Vogel case ixgbe_media_type_backplane: 23901a4e3449SJack F Vogel ret_val = ixgbe_fc_autoneg_backplane(hw); 23911a4e3449SJack F Vogel break; 23921a4e3449SJack F Vogel 23931a4e3449SJack F Vogel /* Autoneg flow control on copper adapters */ 23941a4e3449SJack F Vogel case ixgbe_media_type_copper: 23951a4e3449SJack F Vogel if (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS) 23961a4e3449SJack F Vogel ret_val = ixgbe_fc_autoneg_copper(hw); 23971a4e3449SJack F Vogel break; 23981a4e3449SJack F Vogel 23991a4e3449SJack F Vogel default: 24001a4e3449SJack F Vogel break; 24011a4e3449SJack F Vogel } 24021a4e3449SJack F Vogel 24031a4e3449SJack F Vogel out: 24041a4e3449SJack F Vogel if (ret_val == IXGBE_SUCCESS) { 24051a4e3449SJack F Vogel hw->fc.fc_was_autonegged = TRUE; 24061a4e3449SJack F Vogel } else { 24071a4e3449SJack F Vogel hw->fc.fc_was_autonegged = FALSE; 24081a4e3449SJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 24091a4e3449SJack F Vogel } 24101a4e3449SJack F Vogel return ret_val; 24111a4e3449SJack F Vogel } 24121a4e3449SJack F Vogel 24131a4e3449SJack F Vogel /** 24141a4e3449SJack F Vogel * ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber 24151a4e3449SJack F Vogel * @hw: pointer to hardware structure 24161a4e3449SJack F Vogel * 24171a4e3449SJack F Vogel * Enable flow control according on 1 gig fiber. 24181a4e3449SJack F Vogel **/ 24191a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw) 24201a4e3449SJack F Vogel { 24211a4e3449SJack F Vogel u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; 24221a4e3449SJack F Vogel s32 ret_val; 24231a4e3449SJack F Vogel 24241a4e3449SJack F Vogel /* 24251a4e3449SJack F Vogel * On multispeed fiber at 1g, bail out if 24261a4e3449SJack F Vogel * - link is up but AN did not complete, or if 24271a4e3449SJack F Vogel * - link is up and AN completed but timed out 24281a4e3449SJack F Vogel */ 24291a4e3449SJack F Vogel 24301a4e3449SJack F Vogel linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); 2431*85d0a26eSJack F Vogel if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || 2432*85d0a26eSJack F Vogel (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { 24331a4e3449SJack F Vogel ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 24341a4e3449SJack F Vogel goto out; 24351a4e3449SJack F Vogel } 24361a4e3449SJack F Vogel 24371a4e3449SJack F Vogel pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); 24381a4e3449SJack F Vogel pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); 24391a4e3449SJack F Vogel 24401a4e3449SJack F Vogel ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg, 24411a4e3449SJack F Vogel pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE, 24421a4e3449SJack F Vogel IXGBE_PCS1GANA_ASM_PAUSE, 24431a4e3449SJack F Vogel IXGBE_PCS1GANA_SYM_PAUSE, 24441a4e3449SJack F Vogel IXGBE_PCS1GANA_ASM_PAUSE); 24451a4e3449SJack F Vogel 24461a4e3449SJack F Vogel out: 24471a4e3449SJack F Vogel return ret_val; 24481a4e3449SJack F Vogel } 24491a4e3449SJack F Vogel 24501a4e3449SJack F Vogel /** 24511a4e3449SJack F Vogel * ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37 24521a4e3449SJack F Vogel * @hw: pointer to hardware structure 24531a4e3449SJack F Vogel * 24541a4e3449SJack F Vogel * Enable flow control according to IEEE clause 37. 24551a4e3449SJack F Vogel **/ 24561a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw) 24571a4e3449SJack F Vogel { 24581a4e3449SJack F Vogel u32 links2, anlp1_reg, autoc_reg, links; 24591a4e3449SJack F Vogel s32 ret_val; 24601a4e3449SJack F Vogel 24612969bf0eSJack F Vogel /* 24622969bf0eSJack F Vogel * On backplane, bail out if 24632969bf0eSJack F Vogel * - backplane autoneg was not completed, or if 24642969bf0eSJack F Vogel * - we are 82599 and link partner is not AN enabled 24652969bf0eSJack F Vogel */ 24662969bf0eSJack F Vogel links = IXGBE_READ_REG(hw, IXGBE_LINKS); 24672969bf0eSJack F Vogel if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { 24682969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 24692969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 24701a4e3449SJack F Vogel ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 24712969bf0eSJack F Vogel goto out; 24722969bf0eSJack F Vogel } 24732969bf0eSJack F Vogel 24742969bf0eSJack F Vogel if (hw->mac.type == ixgbe_mac_82599EB) { 24752969bf0eSJack F Vogel links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); 24762969bf0eSJack F Vogel if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { 24772969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 24782969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 24791a4e3449SJack F Vogel ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; 24802969bf0eSJack F Vogel goto out; 24812969bf0eSJack F Vogel } 24822969bf0eSJack F Vogel } 24832969bf0eSJack F Vogel /* 24842969bf0eSJack F Vogel * Read the 10g AN autoc and LP ability registers and resolve 24852969bf0eSJack F Vogel * local flow control settings accordingly 24862969bf0eSJack F Vogel */ 24872969bf0eSJack F Vogel autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 24882969bf0eSJack F Vogel anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); 24892969bf0eSJack F Vogel 24901a4e3449SJack F Vogel ret_val = ixgbe_negotiate_fc(hw, autoc_reg, 24911a4e3449SJack F Vogel anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE, 24921a4e3449SJack F Vogel IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE); 24931a4e3449SJack F Vogel 24941a4e3449SJack F Vogel out: 24951a4e3449SJack F Vogel return ret_val; 24961a4e3449SJack F Vogel } 24971a4e3449SJack F Vogel 24981a4e3449SJack F Vogel /** 24991a4e3449SJack F Vogel * ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37 25001a4e3449SJack F Vogel * @hw: pointer to hardware structure 25011a4e3449SJack F Vogel * 25021a4e3449SJack F Vogel * Enable flow control according to IEEE clause 37. 25031a4e3449SJack F Vogel **/ 25041a4e3449SJack F Vogel static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw) 25051a4e3449SJack F Vogel { 25061a4e3449SJack F Vogel u16 technology_ability_reg = 0; 25071a4e3449SJack F Vogel u16 lp_technology_ability_reg = 0; 25081a4e3449SJack F Vogel 25091a4e3449SJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, 25101a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 25111a4e3449SJack F Vogel &technology_ability_reg); 25121a4e3449SJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_LP, 25131a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, 25141a4e3449SJack F Vogel &lp_technology_ability_reg); 25151a4e3449SJack F Vogel 25161a4e3449SJack F Vogel return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg, 25171a4e3449SJack F Vogel (u32)lp_technology_ability_reg, 25181a4e3449SJack F Vogel IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE, 25191a4e3449SJack F Vogel IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE); 25201a4e3449SJack F Vogel } 25211a4e3449SJack F Vogel 25221a4e3449SJack F Vogel /** 25231a4e3449SJack F Vogel * ixgbe_negotiate_fc - Negotiate flow control 25241a4e3449SJack F Vogel * @hw: pointer to hardware structure 25251a4e3449SJack F Vogel * @adv_reg: flow control advertised settings 25261a4e3449SJack F Vogel * @lp_reg: link partner's flow control settings 25271a4e3449SJack F Vogel * @adv_sym: symmetric pause bit in advertisement 25281a4e3449SJack F Vogel * @adv_asm: asymmetric pause bit in advertisement 25291a4e3449SJack F Vogel * @lp_sym: symmetric pause bit in link partner advertisement 25301a4e3449SJack F Vogel * @lp_asm: asymmetric pause bit in link partner advertisement 25311a4e3449SJack F Vogel * 25321a4e3449SJack F Vogel * Find the intersection between advertised settings and link partner's 25331a4e3449SJack F Vogel * advertised settings 25341a4e3449SJack F Vogel **/ 25351a4e3449SJack F Vogel static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, 25361a4e3449SJack F Vogel u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) 25371a4e3449SJack F Vogel { 25381a4e3449SJack F Vogel if ((!(adv_reg)) || (!(lp_reg))) 25391a4e3449SJack F Vogel return IXGBE_ERR_FC_NOT_NEGOTIATED; 25401a4e3449SJack F Vogel 25411a4e3449SJack F Vogel if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { 25422969bf0eSJack F Vogel /* 25432969bf0eSJack F Vogel * Now we need to check if the user selected Rx ONLY 25442969bf0eSJack F Vogel * of pause frames. In this case, we had to advertise 25452969bf0eSJack F Vogel * FULL flow control because we could not advertise RX 25462969bf0eSJack F Vogel * ONLY. Hence, we must now check to see if we need to 25472969bf0eSJack F Vogel * turn OFF the TRANSMISSION of PAUSE frames. 25482969bf0eSJack F Vogel */ 25492969bf0eSJack F Vogel if (hw->fc.requested_mode == ixgbe_fc_full) { 25502969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_full; 25512969bf0eSJack F Vogel DEBUGOUT("Flow Control = FULL.\n"); 25522969bf0eSJack F Vogel } else { 25532969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 25542969bf0eSJack F Vogel DEBUGOUT("Flow Control=RX PAUSE frames only\n"); 25552969bf0eSJack F Vogel } 25561a4e3449SJack F Vogel } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) && 25571a4e3449SJack F Vogel (lp_reg & lp_sym) && (lp_reg & lp_asm)) { 25582969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_tx_pause; 25592969bf0eSJack F Vogel DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); 25601a4e3449SJack F Vogel } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) && 25611a4e3449SJack F Vogel !(lp_reg & lp_sym) && (lp_reg & lp_asm)) { 25622969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 25632969bf0eSJack F Vogel DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); 25642969bf0eSJack F Vogel } else { 25652969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_none; 25662969bf0eSJack F Vogel DEBUGOUT("Flow Control = NONE.\n"); 25672969bf0eSJack F Vogel } 25681a4e3449SJack F Vogel return IXGBE_SUCCESS; 25691b6e0dbaSJack F Vogel } 25701b6e0dbaSJack F Vogel 25710ac6dfecSJack F Vogel /** 25720ac6dfecSJack F Vogel * ixgbe_setup_fc - Set up flow control 25730ac6dfecSJack F Vogel * @hw: pointer to hardware structure 25740ac6dfecSJack F Vogel * 25750ac6dfecSJack F Vogel * Called at init time to set up flow control. 25760ac6dfecSJack F Vogel **/ 2577*85d0a26eSJack F Vogel static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) 25780ac6dfecSJack F Vogel { 25790ac6dfecSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 25801a4e3449SJack F Vogel u32 reg = 0, reg_bp = 0; 25811a4e3449SJack F Vogel u16 reg_cu = 0; 25820ac6dfecSJack F Vogel 25832969bf0eSJack F Vogel DEBUGFUNC("ixgbe_setup_fc"); 25842969bf0eSJack F Vogel 25850ac6dfecSJack F Vogel /* Validate the packetbuf configuration */ 25860ac6dfecSJack F Vogel if (packetbuf_num < 0 || packetbuf_num > 7) { 2587*85d0a26eSJack F Vogel DEBUGOUT1("Invalid packet buffer number [%d], expected range " 2588*85d0a26eSJack F Vogel "is 0-7\n", packetbuf_num); 25890ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 25900ac6dfecSJack F Vogel goto out; 25910ac6dfecSJack F Vogel } 25920ac6dfecSJack F Vogel 25930ac6dfecSJack F Vogel /* 25940ac6dfecSJack F Vogel * Validate the water mark configuration. Zero water marks are invalid 25950ac6dfecSJack F Vogel * because it causes the controller to just blast out fc packets. 25960ac6dfecSJack F Vogel */ 2597*85d0a26eSJack F Vogel if (!hw->fc.low_water || 2598*85d0a26eSJack F Vogel !hw->fc.high_water[packetbuf_num] || 2599*85d0a26eSJack F Vogel !hw->fc.pause_time) { 26000ac6dfecSJack F Vogel DEBUGOUT("Invalid water mark configuration\n"); 26010ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 26020ac6dfecSJack F Vogel goto out; 26030ac6dfecSJack F Vogel } 26040ac6dfecSJack F Vogel 26050ac6dfecSJack F Vogel /* 26060ac6dfecSJack F Vogel * Validate the requested mode. Strict IEEE mode does not allow 26070ac6dfecSJack F Vogel * ixgbe_fc_rx_pause because it will cause us to fail at UNH. 26080ac6dfecSJack F Vogel */ 26090ac6dfecSJack F Vogel if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { 26100ac6dfecSJack F Vogel DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); 26110ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 26120ac6dfecSJack F Vogel goto out; 26130ac6dfecSJack F Vogel } 26140ac6dfecSJack F Vogel 26150ac6dfecSJack F Vogel /* 26160ac6dfecSJack F Vogel * 10gig parts do not have a word in the EEPROM to determine the 26170ac6dfecSJack F Vogel * default flow control setting, so we explicitly set it to full. 26180ac6dfecSJack F Vogel */ 26190ac6dfecSJack F Vogel if (hw->fc.requested_mode == ixgbe_fc_default) 26200ac6dfecSJack F Vogel hw->fc.requested_mode = ixgbe_fc_full; 26210ac6dfecSJack F Vogel 26220ac6dfecSJack F Vogel /* 26231a4e3449SJack F Vogel * Set up the 1G and 10G flow control advertisement registers so the 26241a4e3449SJack F Vogel * HW will be able to do fc autoneg once the cable is plugged in. If 26251a4e3449SJack F Vogel * we link at 10G, the 1G advertisement is harmless and vice versa. 26260ac6dfecSJack F Vogel */ 26271a4e3449SJack F Vogel 26281a4e3449SJack F Vogel switch (hw->phy.media_type) { 26291a4e3449SJack F Vogel case ixgbe_media_type_fiber: 26301a4e3449SJack F Vogel case ixgbe_media_type_backplane: 26310ac6dfecSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); 26321a4e3449SJack F Vogel reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC); 26331a4e3449SJack F Vogel break; 26341a4e3449SJack F Vogel 26351a4e3449SJack F Vogel case ixgbe_media_type_copper: 26361a4e3449SJack F Vogel hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, 26371a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®_cu); 26381a4e3449SJack F Vogel break; 26391a4e3449SJack F Vogel 26401a4e3449SJack F Vogel default: 26411a4e3449SJack F Vogel ; 26421a4e3449SJack F Vogel } 26430ac6dfecSJack F Vogel 26440ac6dfecSJack F Vogel /* 26450ac6dfecSJack F Vogel * The possible values of fc.requested_mode are: 26460ac6dfecSJack F Vogel * 0: Flow control is completely disabled 26470ac6dfecSJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames, 26480ac6dfecSJack F Vogel * but not send pause frames). 26490ac6dfecSJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but 26500ac6dfecSJack F Vogel * we do not support receiving pause frames). 26510ac6dfecSJack F Vogel * 3: Both Rx and Tx flow control (symmetric) are enabled. 26520ac6dfecSJack F Vogel * other: Invalid. 26530ac6dfecSJack F Vogel */ 26540ac6dfecSJack F Vogel switch (hw->fc.requested_mode) { 26550ac6dfecSJack F Vogel case ixgbe_fc_none: 26560ac6dfecSJack F Vogel /* Flow control completely disabled by software override. */ 26570ac6dfecSJack F Vogel reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 26581a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) 26591a4e3449SJack F Vogel reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE | 26601a4e3449SJack F Vogel IXGBE_AUTOC_ASM_PAUSE); 26611a4e3449SJack F Vogel else if (hw->phy.media_type == ixgbe_media_type_copper) 26621a4e3449SJack F Vogel reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); 26630ac6dfecSJack F Vogel break; 26640ac6dfecSJack F Vogel case ixgbe_fc_rx_pause: 26650ac6dfecSJack F Vogel /* 26660ac6dfecSJack F Vogel * Rx Flow control is enabled and Tx Flow control is 26670ac6dfecSJack F Vogel * disabled by software override. Since there really 26680ac6dfecSJack F Vogel * isn't a way to advertise that we are capable of RX 26690ac6dfecSJack F Vogel * Pause ONLY, we will advertise that we support both 26700ac6dfecSJack F Vogel * symmetric and asymmetric Rx PAUSE. Later, we will 26710ac6dfecSJack F Vogel * disable the adapter's ability to send PAUSE frames. 26720ac6dfecSJack F Vogel */ 26730ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 26741a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) 26751a4e3449SJack F Vogel reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | 26761a4e3449SJack F Vogel IXGBE_AUTOC_ASM_PAUSE); 26771a4e3449SJack F Vogel else if (hw->phy.media_type == ixgbe_media_type_copper) 26781a4e3449SJack F Vogel reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); 26790ac6dfecSJack F Vogel break; 26800ac6dfecSJack F Vogel case ixgbe_fc_tx_pause: 26810ac6dfecSJack F Vogel /* 26820ac6dfecSJack F Vogel * Tx Flow control is enabled, and Rx Flow control is 26830ac6dfecSJack F Vogel * disabled by software override. 26840ac6dfecSJack F Vogel */ 26850ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_ASM_PAUSE); 26860ac6dfecSJack F Vogel reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); 26871a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) { 26881a4e3449SJack F Vogel reg_bp |= (IXGBE_AUTOC_ASM_PAUSE); 26891a4e3449SJack F Vogel reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE); 26901a4e3449SJack F Vogel } else if (hw->phy.media_type == ixgbe_media_type_copper) { 26911a4e3449SJack F Vogel reg_cu |= (IXGBE_TAF_ASM_PAUSE); 26921a4e3449SJack F Vogel reg_cu &= ~(IXGBE_TAF_SYM_PAUSE); 26931a4e3449SJack F Vogel } 26940ac6dfecSJack F Vogel break; 26950ac6dfecSJack F Vogel case ixgbe_fc_full: 26960ac6dfecSJack F Vogel /* Flow control (both Rx and Tx) is enabled by SW override. */ 26970ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 26981a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) 26991a4e3449SJack F Vogel reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | 27001a4e3449SJack F Vogel IXGBE_AUTOC_ASM_PAUSE); 27011a4e3449SJack F Vogel else if (hw->phy.media_type == ixgbe_media_type_copper) 27021a4e3449SJack F Vogel reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); 27030ac6dfecSJack F Vogel break; 27040ac6dfecSJack F Vogel default: 27050ac6dfecSJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 27062969bf0eSJack F Vogel ret_val = IXGBE_ERR_CONFIG; 27070ac6dfecSJack F Vogel goto out; 27080ac6dfecSJack F Vogel break; 27090ac6dfecSJack F Vogel } 27100ac6dfecSJack F Vogel 2711*85d0a26eSJack F Vogel if (hw->mac.type != ixgbe_mac_X540) { 27121a4e3449SJack F Vogel /* 27131a4e3449SJack F Vogel * Enable auto-negotiation between the MAC & PHY; 27141a4e3449SJack F Vogel * the MAC will advertise clause 37 flow control. 27151a4e3449SJack F Vogel */ 27160ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); 27170ac6dfecSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); 27180ac6dfecSJack F Vogel 27190ac6dfecSJack F Vogel /* Disable AN timeout */ 27200ac6dfecSJack F Vogel if (hw->fc.strict_ieee) 27210ac6dfecSJack F Vogel reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; 27220ac6dfecSJack F Vogel 27230ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); 27240ac6dfecSJack F Vogel DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg); 2725*85d0a26eSJack F Vogel } 27260ac6dfecSJack F Vogel 27272969bf0eSJack F Vogel /* 27281a4e3449SJack F Vogel * AUTOC restart handles negotiation of 1G and 10G on backplane 27291a4e3449SJack F Vogel * and copper. There is no need to set the PCS1GCTL register. 27301a4e3449SJack F Vogel * 27312969bf0eSJack F Vogel */ 27321a4e3449SJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) { 27331a4e3449SJack F Vogel reg_bp |= IXGBE_AUTOC_AN_RESTART; 27341a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); 27351a4e3449SJack F Vogel } else if ((hw->phy.media_type == ixgbe_media_type_copper) && 27361a4e3449SJack F Vogel (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) { 27371a4e3449SJack F Vogel hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT, 27381a4e3449SJack F Vogel IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu); 27392969bf0eSJack F Vogel } 27402969bf0eSJack F Vogel 27411a4e3449SJack F Vogel DEBUGOUT1("Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); 27420ac6dfecSJack F Vogel out: 27430ac6dfecSJack F Vogel return ret_val; 27440ac6dfecSJack F Vogel } 27451b6e0dbaSJack F Vogel 274613705f88SJack F Vogel /** 274713705f88SJack F Vogel * ixgbe_disable_pcie_master - Disable PCI-express master access 274813705f88SJack F Vogel * @hw: pointer to hardware structure 274913705f88SJack F Vogel * 275013705f88SJack F Vogel * Disables PCI-Express master access and verifies there are no pending 275113705f88SJack F Vogel * requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable 275213705f88SJack F Vogel * bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS 275313705f88SJack F Vogel * is returned signifying master requests disabled. 275413705f88SJack F Vogel **/ 275513705f88SJack F Vogel s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) 275613705f88SJack F Vogel { 2757c0014855SJack F Vogel s32 status = IXGBE_SUCCESS; 2758*85d0a26eSJack F Vogel u32 i; 275913705f88SJack F Vogel 27602969bf0eSJack F Vogel DEBUGFUNC("ixgbe_disable_pcie_master"); 27612969bf0eSJack F Vogel 2762*85d0a26eSJack F Vogel /* Always set this bit to ensure any future transactions are blocked */ 2763*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS); 2764*85d0a26eSJack F Vogel 2765*85d0a26eSJack F Vogel /* Exit if master requets are blocked */ 2766c0014855SJack F Vogel if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) 2767c0014855SJack F Vogel goto out; 2768c0014855SJack F Vogel 2769*85d0a26eSJack F Vogel /* Poll for master request bit to clear */ 277013705f88SJack F Vogel for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 2771*85d0a26eSJack F Vogel usec_delay(100); 2772c0014855SJack F Vogel if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) 2773182b3808SJack F Vogel goto out; 2774*85d0a26eSJack F Vogel } 2775c0014855SJack F Vogel 2776c0014855SJack F Vogel /* 2777c0014855SJack F Vogel * Two consecutive resets are required via CTRL.RST per datasheet 2778c0014855SJack F Vogel * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine 2779c0014855SJack F Vogel * of this need. The first reset prevents new master requests from 2780*85d0a26eSJack F Vogel * being issued by our device. We then must wait 1usec or more for any 2781c0014855SJack F Vogel * remaining completions from the PCIe bus to trickle in, and then reset 2782c0014855SJack F Vogel * again to clear out any effects they may have had on our device. 2783c0014855SJack F Vogel */ 2784*85d0a26eSJack F Vogel DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n"); 2785c0014855SJack F Vogel hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 2786c0014855SJack F Vogel 2787*85d0a26eSJack F Vogel /* 2788*85d0a26eSJack F Vogel * Before proceeding, make sure that the PCIe block does not have 2789*85d0a26eSJack F Vogel * transactions pending. 2790*85d0a26eSJack F Vogel */ 2791*85d0a26eSJack F Vogel for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 2792*85d0a26eSJack F Vogel usec_delay(100); 2793*85d0a26eSJack F Vogel if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) & 2794*85d0a26eSJack F Vogel IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) 2795*85d0a26eSJack F Vogel goto out; 2796*85d0a26eSJack F Vogel } 2797*85d0a26eSJack F Vogel 2798*85d0a26eSJack F Vogel DEBUGOUT("PCIe transaction pending bit also did not clear.\n"); 2799*85d0a26eSJack F Vogel status = IXGBE_ERR_MASTER_REQUESTS_PENDING; 2800*85d0a26eSJack F Vogel 2801c0014855SJack F Vogel out: 280213705f88SJack F Vogel return status; 280313705f88SJack F Vogel } 280413705f88SJack F Vogel 280513705f88SJack F Vogel /** 28069ca4041bSJack F Vogel * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore 280713705f88SJack F Vogel * @hw: pointer to hardware structure 28089ca4041bSJack F Vogel * @mask: Mask to specify which semaphore to acquire 280913705f88SJack F Vogel * 2810*85d0a26eSJack F Vogel * Acquires the SWFW semaphore through the GSSR register for the specified 281113705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 281213705f88SJack F Vogel **/ 281313705f88SJack F Vogel s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) 281413705f88SJack F Vogel { 281513705f88SJack F Vogel u32 gssr; 281613705f88SJack F Vogel u32 swmask = mask; 281713705f88SJack F Vogel u32 fwmask = mask << 5; 281813705f88SJack F Vogel s32 timeout = 200; 281913705f88SJack F Vogel 28202969bf0eSJack F Vogel DEBUGFUNC("ixgbe_acquire_swfw_sync"); 28212969bf0eSJack F Vogel 282213705f88SJack F Vogel while (timeout) { 28230ac6dfecSJack F Vogel /* 28240ac6dfecSJack F Vogel * SW EEPROM semaphore bit is used for access to all 28250ac6dfecSJack F Vogel * SW_FW_SYNC/GSSR bits (not just EEPROM) 28260ac6dfecSJack F Vogel */ 282713705f88SJack F Vogel if (ixgbe_get_eeprom_semaphore(hw)) 28282969bf0eSJack F Vogel return IXGBE_ERR_SWFW_SYNC; 282913705f88SJack F Vogel 283013705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 283113705f88SJack F Vogel if (!(gssr & (fwmask | swmask))) 283213705f88SJack F Vogel break; 283313705f88SJack F Vogel 283413705f88SJack F Vogel /* 283513705f88SJack F Vogel * Firmware currently using resource (fwmask) or other software 283613705f88SJack F Vogel * thread currently using resource (swmask) 283713705f88SJack F Vogel */ 283813705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 283913705f88SJack F Vogel msec_delay(5); 284013705f88SJack F Vogel timeout--; 284113705f88SJack F Vogel } 284213705f88SJack F Vogel 284313705f88SJack F Vogel if (!timeout) { 28440ac6dfecSJack F Vogel DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); 28452969bf0eSJack F Vogel return IXGBE_ERR_SWFW_SYNC; 284613705f88SJack F Vogel } 284713705f88SJack F Vogel 284813705f88SJack F Vogel gssr |= swmask; 284913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 285013705f88SJack F Vogel 285113705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 285213705f88SJack F Vogel return IXGBE_SUCCESS; 285313705f88SJack F Vogel } 285413705f88SJack F Vogel 285513705f88SJack F Vogel /** 285613705f88SJack F Vogel * ixgbe_release_swfw_sync - Release SWFW semaphore 285713705f88SJack F Vogel * @hw: pointer to hardware structure 28589ca4041bSJack F Vogel * @mask: Mask to specify which semaphore to release 285913705f88SJack F Vogel * 2860*85d0a26eSJack F Vogel * Releases the SWFW semaphore through the GSSR register for the specified 286113705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 286213705f88SJack F Vogel **/ 286313705f88SJack F Vogel void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) 286413705f88SJack F Vogel { 286513705f88SJack F Vogel u32 gssr; 286613705f88SJack F Vogel u32 swmask = mask; 286713705f88SJack F Vogel 28682969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_swfw_sync"); 28692969bf0eSJack F Vogel 287013705f88SJack F Vogel ixgbe_get_eeprom_semaphore(hw); 287113705f88SJack F Vogel 287213705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 287313705f88SJack F Vogel gssr &= ~swmask; 287413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 287513705f88SJack F Vogel 287613705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 28770ac6dfecSJack F Vogel } 28780ac6dfecSJack F Vogel 28790ac6dfecSJack F Vogel /** 2880*85d0a26eSJack F Vogel * ixgbe_disable_sec_rx_path_generic - Stops the receive data path 2881*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 2882*85d0a26eSJack F Vogel * 2883*85d0a26eSJack F Vogel * Stops the receive data path and waits for the HW to internally empty 2884*85d0a26eSJack F Vogel * the Rx security block 2885*85d0a26eSJack F Vogel **/ 2886*85d0a26eSJack F Vogel s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw) 2887*85d0a26eSJack F Vogel { 2888*85d0a26eSJack F Vogel #define IXGBE_MAX_SECRX_POLL 40 2889*85d0a26eSJack F Vogel 2890*85d0a26eSJack F Vogel int i; 2891*85d0a26eSJack F Vogel int secrxreg; 2892*85d0a26eSJack F Vogel 2893*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_disable_sec_rx_path_generic"); 2894*85d0a26eSJack F Vogel 2895*85d0a26eSJack F Vogel 2896*85d0a26eSJack F Vogel secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); 2897*85d0a26eSJack F Vogel secrxreg |= IXGBE_SECRXCTRL_RX_DIS; 2898*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg); 2899*85d0a26eSJack F Vogel for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) { 2900*85d0a26eSJack F Vogel secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT); 2901*85d0a26eSJack F Vogel if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY) 2902*85d0a26eSJack F Vogel break; 2903*85d0a26eSJack F Vogel else 2904*85d0a26eSJack F Vogel /* Use interrupt-safe sleep just in case */ 2905*85d0a26eSJack F Vogel usec_delay(1000); 2906*85d0a26eSJack F Vogel } 2907*85d0a26eSJack F Vogel 2908*85d0a26eSJack F Vogel /* For informational purposes only */ 2909*85d0a26eSJack F Vogel if (i >= IXGBE_MAX_SECRX_POLL) 2910*85d0a26eSJack F Vogel DEBUGOUT("Rx unit being enabled before security " 2911*85d0a26eSJack F Vogel "path fully disabled. Continuing with init.\n"); 2912*85d0a26eSJack F Vogel 2913*85d0a26eSJack F Vogel return IXGBE_SUCCESS; 2914*85d0a26eSJack F Vogel } 2915*85d0a26eSJack F Vogel 2916*85d0a26eSJack F Vogel /** 2917*85d0a26eSJack F Vogel * ixgbe_enable_sec_rx_path_generic - Enables the receive data path 2918*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 2919*85d0a26eSJack F Vogel * 2920*85d0a26eSJack F Vogel * Enables the receive data path. 2921*85d0a26eSJack F Vogel **/ 2922*85d0a26eSJack F Vogel s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw) 2923*85d0a26eSJack F Vogel { 2924*85d0a26eSJack F Vogel int secrxreg; 2925*85d0a26eSJack F Vogel 2926*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_enable_sec_rx_path_generic"); 2927*85d0a26eSJack F Vogel 2928*85d0a26eSJack F Vogel secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); 2929*85d0a26eSJack F Vogel secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS; 2930*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg); 2931*85d0a26eSJack F Vogel IXGBE_WRITE_FLUSH(hw); 2932*85d0a26eSJack F Vogel 2933*85d0a26eSJack F Vogel return IXGBE_SUCCESS; 2934*85d0a26eSJack F Vogel } 2935*85d0a26eSJack F Vogel 2936*85d0a26eSJack F Vogel /** 29370ac6dfecSJack F Vogel * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit 29380ac6dfecSJack F Vogel * @hw: pointer to hardware structure 29390ac6dfecSJack F Vogel * @regval: register value to write to RXCTRL 29400ac6dfecSJack F Vogel * 29410ac6dfecSJack F Vogel * Enables the Rx DMA unit 29420ac6dfecSJack F Vogel **/ 29430ac6dfecSJack F Vogel s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) 29440ac6dfecSJack F Vogel { 29452969bf0eSJack F Vogel DEBUGFUNC("ixgbe_enable_rx_dma_generic"); 29462969bf0eSJack F Vogel 29470ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); 29480ac6dfecSJack F Vogel 29490ac6dfecSJack F Vogel return IXGBE_SUCCESS; 29500ac6dfecSJack F Vogel } 29510ac6dfecSJack F Vogel 29520ac6dfecSJack F Vogel /** 29530ac6dfecSJack F Vogel * ixgbe_blink_led_start_generic - Blink LED based on index. 29540ac6dfecSJack F Vogel * @hw: pointer to hardware structure 29550ac6dfecSJack F Vogel * @index: led number to blink 29560ac6dfecSJack F Vogel **/ 29570ac6dfecSJack F Vogel s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) 29580ac6dfecSJack F Vogel { 29590ac6dfecSJack F Vogel ixgbe_link_speed speed = 0; 29600ac6dfecSJack F Vogel bool link_up = 0; 29610ac6dfecSJack F Vogel u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 29620ac6dfecSJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 29630ac6dfecSJack F Vogel 29642969bf0eSJack F Vogel DEBUGFUNC("ixgbe_blink_led_start_generic"); 29652969bf0eSJack F Vogel 29660ac6dfecSJack F Vogel /* 29670ac6dfecSJack F Vogel * Link must be up to auto-blink the LEDs; 29680ac6dfecSJack F Vogel * Force it if link is down. 29690ac6dfecSJack F Vogel */ 29700ac6dfecSJack F Vogel hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 29710ac6dfecSJack F Vogel 29720ac6dfecSJack F Vogel if (!link_up) { 2973d8602bb9SJack F Vogel autoc_reg |= IXGBE_AUTOC_AN_RESTART; 29740ac6dfecSJack F Vogel autoc_reg |= IXGBE_AUTOC_FLU; 29750ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 2976*85d0a26eSJack F Vogel IXGBE_WRITE_FLUSH(hw); 29770ac6dfecSJack F Vogel msec_delay(10); 29780ac6dfecSJack F Vogel } 29790ac6dfecSJack F Vogel 29800ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 29810ac6dfecSJack F Vogel led_reg |= IXGBE_LED_BLINK(index); 29820ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 29830ac6dfecSJack F Vogel IXGBE_WRITE_FLUSH(hw); 29840ac6dfecSJack F Vogel 29850ac6dfecSJack F Vogel return IXGBE_SUCCESS; 29860ac6dfecSJack F Vogel } 29870ac6dfecSJack F Vogel 29880ac6dfecSJack F Vogel /** 29890ac6dfecSJack F Vogel * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. 29900ac6dfecSJack F Vogel * @hw: pointer to hardware structure 29910ac6dfecSJack F Vogel * @index: led number to stop blinking 29920ac6dfecSJack F Vogel **/ 29930ac6dfecSJack F Vogel s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) 29940ac6dfecSJack F Vogel { 29950ac6dfecSJack F Vogel u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 29960ac6dfecSJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 29970ac6dfecSJack F Vogel 29982969bf0eSJack F Vogel DEBUGFUNC("ixgbe_blink_led_stop_generic"); 29992969bf0eSJack F Vogel 3000d8602bb9SJack F Vogel 30010ac6dfecSJack F Vogel autoc_reg &= ~IXGBE_AUTOC_FLU; 30020ac6dfecSJack F Vogel autoc_reg |= IXGBE_AUTOC_AN_RESTART; 30030ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 30040ac6dfecSJack F Vogel 30050ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 30060ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_BLINK(index); 30070ac6dfecSJack F Vogel led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 30080ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 30090ac6dfecSJack F Vogel IXGBE_WRITE_FLUSH(hw); 30100ac6dfecSJack F Vogel 30110ac6dfecSJack F Vogel return IXGBE_SUCCESS; 301213705f88SJack F Vogel } 301313705f88SJack F Vogel 30142969bf0eSJack F Vogel /** 30152969bf0eSJack F Vogel * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM 30162969bf0eSJack F Vogel * @hw: pointer to hardware structure 30172969bf0eSJack F Vogel * @san_mac_offset: SAN MAC address offset 30182969bf0eSJack F Vogel * 30192969bf0eSJack F Vogel * This function will read the EEPROM location for the SAN MAC address 30202969bf0eSJack F Vogel * pointer, and returns the value at that location. This is used in both 30212969bf0eSJack F Vogel * get and set mac_addr routines. 30222969bf0eSJack F Vogel **/ 30232969bf0eSJack F Vogel static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, 30242969bf0eSJack F Vogel u16 *san_mac_offset) 30252969bf0eSJack F Vogel { 30262969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_san_mac_addr_offset"); 30272969bf0eSJack F Vogel 30282969bf0eSJack F Vogel /* 30292969bf0eSJack F Vogel * First read the EEPROM pointer to see if the MAC addresses are 30302969bf0eSJack F Vogel * available. 30312969bf0eSJack F Vogel */ 30322969bf0eSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset); 30332969bf0eSJack F Vogel 30342969bf0eSJack F Vogel return IXGBE_SUCCESS; 30352969bf0eSJack F Vogel } 30362969bf0eSJack F Vogel 30372969bf0eSJack F Vogel /** 30382969bf0eSJack F Vogel * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM 30392969bf0eSJack F Vogel * @hw: pointer to hardware structure 30402969bf0eSJack F Vogel * @san_mac_addr: SAN MAC address 30412969bf0eSJack F Vogel * 30422969bf0eSJack F Vogel * Reads the SAN MAC address from the EEPROM, if it's available. This is 30432969bf0eSJack F Vogel * per-port, so set_lan_id() must be called before reading the addresses. 30442969bf0eSJack F Vogel * set_lan_id() is called by identify_sfp(), but this cannot be relied 30452969bf0eSJack F Vogel * upon for non-SFP connections, so we must call it here. 30462969bf0eSJack F Vogel **/ 30472969bf0eSJack F Vogel s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) 30482969bf0eSJack F Vogel { 30492969bf0eSJack F Vogel u16 san_mac_data, san_mac_offset; 30502969bf0eSJack F Vogel u8 i; 30512969bf0eSJack F Vogel 30522969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_san_mac_addr_generic"); 30532969bf0eSJack F Vogel 30542969bf0eSJack F Vogel /* 30552969bf0eSJack F Vogel * First read the EEPROM pointer to see if the MAC addresses are 30562969bf0eSJack F Vogel * available. If they're not, no point in calling set_lan_id() here. 30572969bf0eSJack F Vogel */ 30582969bf0eSJack F Vogel ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); 30592969bf0eSJack F Vogel 30602969bf0eSJack F Vogel if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { 30612969bf0eSJack F Vogel /* 30622969bf0eSJack F Vogel * No addresses available in this EEPROM. It's not an 30632969bf0eSJack F Vogel * error though, so just wipe the local address and return. 30642969bf0eSJack F Vogel */ 30652969bf0eSJack F Vogel for (i = 0; i < 6; i++) 30662969bf0eSJack F Vogel san_mac_addr[i] = 0xFF; 30672969bf0eSJack F Vogel 30682969bf0eSJack F Vogel goto san_mac_addr_out; 30692969bf0eSJack F Vogel } 30702969bf0eSJack F Vogel 30712969bf0eSJack F Vogel /* make sure we know which port we need to program */ 30722969bf0eSJack F Vogel hw->mac.ops.set_lan_id(hw); 30732969bf0eSJack F Vogel /* apply the port offset to the address offset */ 30742969bf0eSJack F Vogel (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : 30752969bf0eSJack F Vogel (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); 30762969bf0eSJack F Vogel for (i = 0; i < 3; i++) { 30772969bf0eSJack F Vogel hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data); 30782969bf0eSJack F Vogel san_mac_addr[i * 2] = (u8)(san_mac_data); 30792969bf0eSJack F Vogel san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); 30802969bf0eSJack F Vogel san_mac_offset++; 30812969bf0eSJack F Vogel } 30822969bf0eSJack F Vogel 30832969bf0eSJack F Vogel san_mac_addr_out: 30842969bf0eSJack F Vogel return IXGBE_SUCCESS; 30852969bf0eSJack F Vogel } 30862969bf0eSJack F Vogel 30872969bf0eSJack F Vogel /** 30882969bf0eSJack F Vogel * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM 30892969bf0eSJack F Vogel * @hw: pointer to hardware structure 30902969bf0eSJack F Vogel * @san_mac_addr: SAN MAC address 30912969bf0eSJack F Vogel * 30922969bf0eSJack F Vogel * Write a SAN MAC address to the EEPROM. 30932969bf0eSJack F Vogel **/ 30942969bf0eSJack F Vogel s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) 30952969bf0eSJack F Vogel { 30962969bf0eSJack F Vogel s32 status = IXGBE_SUCCESS; 30972969bf0eSJack F Vogel u16 san_mac_data, san_mac_offset; 30982969bf0eSJack F Vogel u8 i; 30992969bf0eSJack F Vogel 31002969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_san_mac_addr_generic"); 31012969bf0eSJack F Vogel 31022969bf0eSJack F Vogel /* Look for SAN mac address pointer. If not defined, return */ 31032969bf0eSJack F Vogel ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); 31042969bf0eSJack F Vogel 31052969bf0eSJack F Vogel if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { 31062969bf0eSJack F Vogel status = IXGBE_ERR_NO_SAN_ADDR_PTR; 31072969bf0eSJack F Vogel goto san_mac_addr_out; 31082969bf0eSJack F Vogel } 31092969bf0eSJack F Vogel 31102969bf0eSJack F Vogel /* Make sure we know which port we need to write */ 31112969bf0eSJack F Vogel hw->mac.ops.set_lan_id(hw); 31122969bf0eSJack F Vogel /* Apply the port offset to the address offset */ 31132969bf0eSJack F Vogel (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : 31142969bf0eSJack F Vogel (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); 31152969bf0eSJack F Vogel 31162969bf0eSJack F Vogel for (i = 0; i < 3; i++) { 31172969bf0eSJack F Vogel san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8); 31182969bf0eSJack F Vogel san_mac_data |= (u16)(san_mac_addr[i * 2]); 31192969bf0eSJack F Vogel hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); 31202969bf0eSJack F Vogel san_mac_offset++; 31212969bf0eSJack F Vogel } 31222969bf0eSJack F Vogel 31232969bf0eSJack F Vogel san_mac_addr_out: 31242969bf0eSJack F Vogel return status; 31252969bf0eSJack F Vogel } 31262969bf0eSJack F Vogel 31272969bf0eSJack F Vogel /** 31282969bf0eSJack F Vogel * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count 31292969bf0eSJack F Vogel * @hw: pointer to hardware structure 31302969bf0eSJack F Vogel * 31312969bf0eSJack F Vogel * Read PCIe configuration space, and get the MSI-X vector count from 31322969bf0eSJack F Vogel * the capabilities table. 31332969bf0eSJack F Vogel **/ 31342969bf0eSJack F Vogel u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) 31352969bf0eSJack F Vogel { 31362969bf0eSJack F Vogel u32 msix_count = 64; 31372969bf0eSJack F Vogel 31382969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); 31392969bf0eSJack F Vogel if (hw->mac.msix_vectors_from_pcie) { 31402969bf0eSJack F Vogel msix_count = IXGBE_READ_PCIE_WORD(hw, 31412969bf0eSJack F Vogel IXGBE_PCIE_MSIX_82599_CAPS); 31422969bf0eSJack F Vogel msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; 31432969bf0eSJack F Vogel 31442969bf0eSJack F Vogel /* MSI-X count is zero-based in HW, so increment to give 31452969bf0eSJack F Vogel * proper value */ 31462969bf0eSJack F Vogel msix_count++; 31472969bf0eSJack F Vogel } 31482969bf0eSJack F Vogel 31492969bf0eSJack F Vogel return msix_count; 31502969bf0eSJack F Vogel } 31512969bf0eSJack F Vogel 31522969bf0eSJack F Vogel /** 31532969bf0eSJack F Vogel * ixgbe_insert_mac_addr_generic - Find a RAR for this mac address 31542969bf0eSJack F Vogel * @hw: pointer to hardware structure 31552969bf0eSJack F Vogel * @addr: Address to put into receive address register 31562969bf0eSJack F Vogel * @vmdq: VMDq pool to assign 31572969bf0eSJack F Vogel * 31582969bf0eSJack F Vogel * Puts an ethernet address into a receive address register, or 31592969bf0eSJack F Vogel * finds the rar that it is aleady in; adds to the pool list 31602969bf0eSJack F Vogel **/ 31612969bf0eSJack F Vogel s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) 31622969bf0eSJack F Vogel { 31632969bf0eSJack F Vogel static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF; 31642969bf0eSJack F Vogel u32 first_empty_rar = NO_EMPTY_RAR_FOUND; 31652969bf0eSJack F Vogel u32 rar; 31662969bf0eSJack F Vogel u32 rar_low, rar_high; 31672969bf0eSJack F Vogel u32 addr_low, addr_high; 31682969bf0eSJack F Vogel 31692969bf0eSJack F Vogel DEBUGFUNC("ixgbe_insert_mac_addr_generic"); 31702969bf0eSJack F Vogel 31712969bf0eSJack F Vogel /* swap bytes for HW little endian */ 31722969bf0eSJack F Vogel addr_low = addr[0] | (addr[1] << 8) 31732969bf0eSJack F Vogel | (addr[2] << 16) 31742969bf0eSJack F Vogel | (addr[3] << 24); 31752969bf0eSJack F Vogel addr_high = addr[4] | (addr[5] << 8); 31762969bf0eSJack F Vogel 31772969bf0eSJack F Vogel /* 31782969bf0eSJack F Vogel * Either find the mac_id in rar or find the first empty space. 31792969bf0eSJack F Vogel * rar_highwater points to just after the highest currently used 31802969bf0eSJack F Vogel * rar in order to shorten the search. It grows when we add a new 31812969bf0eSJack F Vogel * rar to the top. 31822969bf0eSJack F Vogel */ 31832969bf0eSJack F Vogel for (rar = 0; rar < hw->mac.rar_highwater; rar++) { 31842969bf0eSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); 31852969bf0eSJack F Vogel 31862969bf0eSJack F Vogel if (((IXGBE_RAH_AV & rar_high) == 0) 31872969bf0eSJack F Vogel && first_empty_rar == NO_EMPTY_RAR_FOUND) { 31882969bf0eSJack F Vogel first_empty_rar = rar; 31892969bf0eSJack F Vogel } else if ((rar_high & 0xFFFF) == addr_high) { 31902969bf0eSJack F Vogel rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar)); 31912969bf0eSJack F Vogel if (rar_low == addr_low) 31922969bf0eSJack F Vogel break; /* found it already in the rars */ 31932969bf0eSJack F Vogel } 31942969bf0eSJack F Vogel } 31952969bf0eSJack F Vogel 31962969bf0eSJack F Vogel if (rar < hw->mac.rar_highwater) { 31972969bf0eSJack F Vogel /* already there so just add to the pool bits */ 31982969bf0eSJack F Vogel ixgbe_set_vmdq(hw, rar, vmdq); 31992969bf0eSJack F Vogel } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { 32002969bf0eSJack F Vogel /* stick it into first empty RAR slot we found */ 32012969bf0eSJack F Vogel rar = first_empty_rar; 32022969bf0eSJack F Vogel ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 32032969bf0eSJack F Vogel } else if (rar == hw->mac.rar_highwater) { 32042969bf0eSJack F Vogel /* add it to the top of the list and inc the highwater mark */ 32052969bf0eSJack F Vogel ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 32062969bf0eSJack F Vogel hw->mac.rar_highwater++; 32072969bf0eSJack F Vogel } else if (rar >= hw->mac.num_rar_entries) { 32082969bf0eSJack F Vogel return IXGBE_ERR_INVALID_MAC_ADDR; 32092969bf0eSJack F Vogel } 32102969bf0eSJack F Vogel 32112969bf0eSJack F Vogel /* 32122969bf0eSJack F Vogel * If we found rar[0], make sure the default pool bit (we use pool 0) 32132969bf0eSJack F Vogel * remains cleared to be sure default pool packets will get delivered 32142969bf0eSJack F Vogel */ 32152969bf0eSJack F Vogel if (rar == 0) 32162969bf0eSJack F Vogel ixgbe_clear_vmdq(hw, rar, 0); 32172969bf0eSJack F Vogel 32182969bf0eSJack F Vogel return rar; 32192969bf0eSJack F Vogel } 32202969bf0eSJack F Vogel 32212969bf0eSJack F Vogel /** 32222969bf0eSJack F Vogel * ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address 32232969bf0eSJack F Vogel * @hw: pointer to hardware struct 32242969bf0eSJack F Vogel * @rar: receive address register index to disassociate 32252969bf0eSJack F Vogel * @vmdq: VMDq pool index to remove from the rar 32262969bf0eSJack F Vogel **/ 32272969bf0eSJack F Vogel s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) 32282969bf0eSJack F Vogel { 32292969bf0eSJack F Vogel u32 mpsar_lo, mpsar_hi; 32302969bf0eSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 32312969bf0eSJack F Vogel 32322969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_vmdq_generic"); 32332969bf0eSJack F Vogel 32341a4e3449SJack F Vogel /* Make sure we are using a valid rar index range */ 32351a4e3449SJack F Vogel if (rar >= rar_entries) { 32361a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", rar); 32371a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 32381a4e3449SJack F Vogel } 32391a4e3449SJack F Vogel 32402969bf0eSJack F Vogel mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); 32412969bf0eSJack F Vogel mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); 32422969bf0eSJack F Vogel 32432969bf0eSJack F Vogel if (!mpsar_lo && !mpsar_hi) 32442969bf0eSJack F Vogel goto done; 32452969bf0eSJack F Vogel 32462969bf0eSJack F Vogel if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { 32472969bf0eSJack F Vogel if (mpsar_lo) { 32482969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); 32492969bf0eSJack F Vogel mpsar_lo = 0; 32502969bf0eSJack F Vogel } 32512969bf0eSJack F Vogel if (mpsar_hi) { 32522969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); 32532969bf0eSJack F Vogel mpsar_hi = 0; 32542969bf0eSJack F Vogel } 32552969bf0eSJack F Vogel } else if (vmdq < 32) { 32562969bf0eSJack F Vogel mpsar_lo &= ~(1 << vmdq); 32572969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); 32582969bf0eSJack F Vogel } else { 32592969bf0eSJack F Vogel mpsar_hi &= ~(1 << (vmdq - 32)); 32602969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); 32612969bf0eSJack F Vogel } 32622969bf0eSJack F Vogel 32632969bf0eSJack F Vogel /* was that the last pool using this rar? */ 32642969bf0eSJack F Vogel if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) 32652969bf0eSJack F Vogel hw->mac.ops.clear_rar(hw, rar); 32662969bf0eSJack F Vogel done: 32672969bf0eSJack F Vogel return IXGBE_SUCCESS; 32682969bf0eSJack F Vogel } 32692969bf0eSJack F Vogel 32702969bf0eSJack F Vogel /** 32712969bf0eSJack F Vogel * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address 32722969bf0eSJack F Vogel * @hw: pointer to hardware struct 32732969bf0eSJack F Vogel * @rar: receive address register index to associate with a VMDq index 32742969bf0eSJack F Vogel * @vmdq: VMDq pool index 32752969bf0eSJack F Vogel **/ 32762969bf0eSJack F Vogel s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) 32772969bf0eSJack F Vogel { 32782969bf0eSJack F Vogel u32 mpsar; 32792969bf0eSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 32802969bf0eSJack F Vogel 32812969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_vmdq_generic"); 32822969bf0eSJack F Vogel 32831a4e3449SJack F Vogel /* Make sure we are using a valid rar index range */ 32841a4e3449SJack F Vogel if (rar >= rar_entries) { 32851a4e3449SJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", rar); 32861a4e3449SJack F Vogel return IXGBE_ERR_INVALID_ARGUMENT; 32871a4e3449SJack F Vogel } 32881a4e3449SJack F Vogel 32892969bf0eSJack F Vogel if (vmdq < 32) { 32902969bf0eSJack F Vogel mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); 32912969bf0eSJack F Vogel mpsar |= 1 << vmdq; 32922969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); 32932969bf0eSJack F Vogel } else { 32942969bf0eSJack F Vogel mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); 32952969bf0eSJack F Vogel mpsar |= 1 << (vmdq - 32); 32962969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); 32972969bf0eSJack F Vogel } 32982969bf0eSJack F Vogel return IXGBE_SUCCESS; 32992969bf0eSJack F Vogel } 33002969bf0eSJack F Vogel 33012969bf0eSJack F Vogel /** 33022969bf0eSJack F Vogel * ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array 33032969bf0eSJack F Vogel * @hw: pointer to hardware structure 33042969bf0eSJack F Vogel **/ 33052969bf0eSJack F Vogel s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) 33062969bf0eSJack F Vogel { 33072969bf0eSJack F Vogel int i; 33082969bf0eSJack F Vogel 33092969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_uta_tables_generic"); 33102969bf0eSJack F Vogel DEBUGOUT(" Clearing UTA\n"); 33112969bf0eSJack F Vogel 33122969bf0eSJack F Vogel for (i = 0; i < 128; i++) 33132969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); 33142969bf0eSJack F Vogel 33152969bf0eSJack F Vogel return IXGBE_SUCCESS; 33162969bf0eSJack F Vogel } 33172969bf0eSJack F Vogel 33182969bf0eSJack F Vogel /** 33192969bf0eSJack F Vogel * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot 33202969bf0eSJack F Vogel * @hw: pointer to hardware structure 33212969bf0eSJack F Vogel * @vlan: VLAN id to write to VLAN filter 33222969bf0eSJack F Vogel * 33232969bf0eSJack F Vogel * return the VLVF index where this VLAN id should be placed 33242969bf0eSJack F Vogel * 33252969bf0eSJack F Vogel **/ 33262969bf0eSJack F Vogel s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) 33272969bf0eSJack F Vogel { 33282969bf0eSJack F Vogel u32 bits = 0; 33292969bf0eSJack F Vogel u32 first_empty_slot = 0; 33302969bf0eSJack F Vogel s32 regindex; 33312969bf0eSJack F Vogel 3332c0014855SJack F Vogel /* short cut the special case */ 3333c0014855SJack F Vogel if (vlan == 0) 3334c0014855SJack F Vogel return 0; 3335c0014855SJack F Vogel 33362969bf0eSJack F Vogel /* 33372969bf0eSJack F Vogel * Search for the vlan id in the VLVF entries. Save off the first empty 33382969bf0eSJack F Vogel * slot found along the way 33392969bf0eSJack F Vogel */ 33402969bf0eSJack F Vogel for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { 33412969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); 33422969bf0eSJack F Vogel if (!bits && !(first_empty_slot)) 33432969bf0eSJack F Vogel first_empty_slot = regindex; 33442969bf0eSJack F Vogel else if ((bits & 0x0FFF) == vlan) 33452969bf0eSJack F Vogel break; 33462969bf0eSJack F Vogel } 33472969bf0eSJack F Vogel 33482969bf0eSJack F Vogel /* 33492969bf0eSJack F Vogel * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan 33502969bf0eSJack F Vogel * in the VLVF. Else use the first empty VLVF register for this 33512969bf0eSJack F Vogel * vlan id. 33522969bf0eSJack F Vogel */ 33532969bf0eSJack F Vogel if (regindex >= IXGBE_VLVF_ENTRIES) { 33542969bf0eSJack F Vogel if (first_empty_slot) 33552969bf0eSJack F Vogel regindex = first_empty_slot; 33562969bf0eSJack F Vogel else { 33572969bf0eSJack F Vogel DEBUGOUT("No space in VLVF.\n"); 3358c0014855SJack F Vogel regindex = IXGBE_ERR_NO_SPACE; 33592969bf0eSJack F Vogel } 33602969bf0eSJack F Vogel } 33612969bf0eSJack F Vogel 33622969bf0eSJack F Vogel return regindex; 33632969bf0eSJack F Vogel } 33642969bf0eSJack F Vogel 33652969bf0eSJack F Vogel /** 33662969bf0eSJack F Vogel * ixgbe_set_vfta_generic - Set VLAN filter table 33672969bf0eSJack F Vogel * @hw: pointer to hardware structure 33682969bf0eSJack F Vogel * @vlan: VLAN id to write to VLAN filter 33692969bf0eSJack F Vogel * @vind: VMDq output index that maps queue to VLAN id in VFVFB 33702969bf0eSJack F Vogel * @vlan_on: boolean flag to turn on/off VLAN in VFVF 33712969bf0eSJack F Vogel * 33722969bf0eSJack F Vogel * Turn on/off specified VLAN in the VLAN filter table. 33732969bf0eSJack F Vogel **/ 33742969bf0eSJack F Vogel s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, 33752969bf0eSJack F Vogel bool vlan_on) 33762969bf0eSJack F Vogel { 33772969bf0eSJack F Vogel s32 regindex; 33782969bf0eSJack F Vogel u32 bitindex; 3379c0014855SJack F Vogel u32 vfta; 3380c0014855SJack F Vogel u32 targetbit; 3381*85d0a26eSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 3382c0014855SJack F Vogel bool vfta_changed = FALSE; 33832969bf0eSJack F Vogel 33842969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_vfta_generic"); 33852969bf0eSJack F Vogel 33862969bf0eSJack F Vogel if (vlan > 4095) 33872969bf0eSJack F Vogel return IXGBE_ERR_PARAM; 33882969bf0eSJack F Vogel 33892969bf0eSJack F Vogel /* 33902969bf0eSJack F Vogel * this is a 2 part operation - first the VFTA, then the 33912969bf0eSJack F Vogel * VLVF and VLVFB if VT Mode is set 3392c0014855SJack F Vogel * We don't write the VFTA until we know the VLVF part succeeded. 33932969bf0eSJack F Vogel */ 33942969bf0eSJack F Vogel 33952969bf0eSJack F Vogel /* Part 1 33962969bf0eSJack F Vogel * The VFTA is a bitstring made up of 128 32-bit registers 33972969bf0eSJack F Vogel * that enable the particular VLAN id, much like the MTA: 33982969bf0eSJack F Vogel * bits[11-5]: which register 33992969bf0eSJack F Vogel * bits[4-0]: which bit in the register 34002969bf0eSJack F Vogel */ 34012969bf0eSJack F Vogel regindex = (vlan >> 5) & 0x7F; 34022969bf0eSJack F Vogel bitindex = vlan & 0x1F; 3403c0014855SJack F Vogel targetbit = (1 << bitindex); 3404c0014855SJack F Vogel vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); 34052969bf0eSJack F Vogel 3406c0014855SJack F Vogel if (vlan_on) { 3407c0014855SJack F Vogel if (!(vfta & targetbit)) { 3408c0014855SJack F Vogel vfta |= targetbit; 3409c0014855SJack F Vogel vfta_changed = TRUE; 3410c0014855SJack F Vogel } 3411c0014855SJack F Vogel } else { 3412c0014855SJack F Vogel if ((vfta & targetbit)) { 3413c0014855SJack F Vogel vfta &= ~targetbit; 3414c0014855SJack F Vogel vfta_changed = TRUE; 3415c0014855SJack F Vogel } 3416c0014855SJack F Vogel } 34172969bf0eSJack F Vogel 34182969bf0eSJack F Vogel /* Part 2 3419*85d0a26eSJack F Vogel * Call ixgbe_set_vlvf_generic to set VLVFB and VLVF 3420*85d0a26eSJack F Vogel */ 3421*85d0a26eSJack F Vogel ret_val = ixgbe_set_vlvf_generic(hw, vlan, vind, vlan_on, 3422*85d0a26eSJack F Vogel &vfta_changed); 3423*85d0a26eSJack F Vogel if (ret_val != IXGBE_SUCCESS) 3424*85d0a26eSJack F Vogel return ret_val; 3425*85d0a26eSJack F Vogel 3426*85d0a26eSJack F Vogel if (vfta_changed) 3427*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); 3428*85d0a26eSJack F Vogel 3429*85d0a26eSJack F Vogel return IXGBE_SUCCESS; 3430*85d0a26eSJack F Vogel } 3431*85d0a26eSJack F Vogel 3432*85d0a26eSJack F Vogel /** 3433*85d0a26eSJack F Vogel * ixgbe_set_vlvf_generic - Set VLAN Pool Filter 3434*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 3435*85d0a26eSJack F Vogel * @vlan: VLAN id to write to VLAN filter 3436*85d0a26eSJack F Vogel * @vind: VMDq output index that maps queue to VLAN id in VFVFB 3437*85d0a26eSJack F Vogel * @vlan_on: boolean flag to turn on/off VLAN in VFVF 3438*85d0a26eSJack F Vogel * @vfta_changed: pointer to boolean flag which indicates whether VFTA 3439*85d0a26eSJack F Vogel * should be changed 3440*85d0a26eSJack F Vogel * 3441*85d0a26eSJack F Vogel * Turn on/off specified bit in VLVF table. 3442*85d0a26eSJack F Vogel **/ 3443*85d0a26eSJack F Vogel s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, 3444*85d0a26eSJack F Vogel bool vlan_on, bool *vfta_changed) 3445*85d0a26eSJack F Vogel { 3446*85d0a26eSJack F Vogel u32 vt; 3447*85d0a26eSJack F Vogel 3448*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_set_vlvf_generic"); 3449*85d0a26eSJack F Vogel 3450*85d0a26eSJack F Vogel if (vlan > 4095) 3451*85d0a26eSJack F Vogel return IXGBE_ERR_PARAM; 3452*85d0a26eSJack F Vogel 3453*85d0a26eSJack F Vogel /* If VT Mode is set 34542969bf0eSJack F Vogel * Either vlan_on 34552969bf0eSJack F Vogel * make sure the vlan is in VLVF 34562969bf0eSJack F Vogel * set the vind bit in the matching VLVFB 34572969bf0eSJack F Vogel * Or !vlan_on 34582969bf0eSJack F Vogel * clear the pool bit and possibly the vind 34592969bf0eSJack F Vogel */ 34602969bf0eSJack F Vogel vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); 34612969bf0eSJack F Vogel if (vt & IXGBE_VT_CTL_VT_ENABLE) { 3462c0014855SJack F Vogel s32 vlvf_index; 3463*85d0a26eSJack F Vogel u32 bits; 3464c0014855SJack F Vogel 3465c0014855SJack F Vogel vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); 3466c0014855SJack F Vogel if (vlvf_index < 0) 3467c0014855SJack F Vogel return vlvf_index; 34682969bf0eSJack F Vogel 34692969bf0eSJack F Vogel if (vlan_on) { 34702969bf0eSJack F Vogel /* set the pool bit */ 34712969bf0eSJack F Vogel if (vind < 32) { 34722969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3473c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index * 2)); 34742969bf0eSJack F Vogel bits |= (1 << vind); 34752969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3476c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index * 2), 34772969bf0eSJack F Vogel bits); 34782969bf0eSJack F Vogel } else { 34792969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3480c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index * 2) + 1)); 3481c0014855SJack F Vogel bits |= (1 << (vind - 32)); 34822969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3483c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index * 2) + 1), 34842969bf0eSJack F Vogel bits); 34852969bf0eSJack F Vogel } 34862969bf0eSJack F Vogel } else { 34872969bf0eSJack F Vogel /* clear the pool bit */ 34882969bf0eSJack F Vogel if (vind < 32) { 34892969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3490c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index * 2)); 34912969bf0eSJack F Vogel bits &= ~(1 << vind); 34922969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3493c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index * 2), 34942969bf0eSJack F Vogel bits); 34952969bf0eSJack F Vogel bits |= IXGBE_READ_REG(hw, 3496c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index * 2) + 1)); 34972969bf0eSJack F Vogel } else { 34982969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 3499c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index * 2) + 1)); 3500c0014855SJack F Vogel bits &= ~(1 << (vind - 32)); 35012969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 3502c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index * 2) + 1), 35032969bf0eSJack F Vogel bits); 35042969bf0eSJack F Vogel bits |= IXGBE_READ_REG(hw, 3505c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index * 2)); 35062969bf0eSJack F Vogel } 35072969bf0eSJack F Vogel } 35082969bf0eSJack F Vogel 3509c0014855SJack F Vogel /* 3510c0014855SJack F Vogel * If there are still bits set in the VLVFB registers 3511c0014855SJack F Vogel * for the VLAN ID indicated we need to see if the 3512c0014855SJack F Vogel * caller is requesting that we clear the VFTA entry bit. 3513c0014855SJack F Vogel * If the caller has requested that we clear the VFTA 3514c0014855SJack F Vogel * entry bit but there are still pools/VFs using this VLAN 3515c0014855SJack F Vogel * ID entry then ignore the request. We're not worried 3516c0014855SJack F Vogel * about the case where we're turning the VFTA VLAN ID 3517c0014855SJack F Vogel * entry bit on, only when requested to turn it off as 3518c0014855SJack F Vogel * there may be multiple pools and/or VFs using the 3519c0014855SJack F Vogel * VLAN ID entry. In that case we cannot clear the 3520c0014855SJack F Vogel * VFTA bit until all pools/VFs using that VLAN ID have also 3521c0014855SJack F Vogel * been cleared. This will be indicated by "bits" being 3522c0014855SJack F Vogel * zero. 3523c0014855SJack F Vogel */ 3524c0014855SJack F Vogel if (bits) { 3525c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 35262969bf0eSJack F Vogel (IXGBE_VLVF_VIEN | vlan)); 3527*85d0a26eSJack F Vogel if ((!vlan_on) && (vfta_changed != NULL)) { 3528c0014855SJack F Vogel /* someone wants to clear the vfta entry 3529c0014855SJack F Vogel * but some pools/VFs are still using it. 3530c0014855SJack F Vogel * Ignore it. */ 3531*85d0a26eSJack F Vogel *vfta_changed = FALSE; 35322969bf0eSJack F Vogel } 3533*85d0a26eSJack F Vogel } else 3534c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); 3535c0014855SJack F Vogel } 3536c0014855SJack F Vogel 35372969bf0eSJack F Vogel return IXGBE_SUCCESS; 35382969bf0eSJack F Vogel } 35392969bf0eSJack F Vogel 35402969bf0eSJack F Vogel /** 35412969bf0eSJack F Vogel * ixgbe_clear_vfta_generic - Clear VLAN filter table 35422969bf0eSJack F Vogel * @hw: pointer to hardware structure 35432969bf0eSJack F Vogel * 35442969bf0eSJack F Vogel * Clears the VLAN filer table, and the VMDq index associated with the filter 35452969bf0eSJack F Vogel **/ 35462969bf0eSJack F Vogel s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) 35472969bf0eSJack F Vogel { 35482969bf0eSJack F Vogel u32 offset; 35492969bf0eSJack F Vogel 35502969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_vfta_generic"); 35512969bf0eSJack F Vogel 35522969bf0eSJack F Vogel for (offset = 0; offset < hw->mac.vft_size; offset++) 35532969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); 35542969bf0eSJack F Vogel 35552969bf0eSJack F Vogel for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { 35562969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); 35572969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0); 35582969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0); 35592969bf0eSJack F Vogel } 35602969bf0eSJack F Vogel 35612969bf0eSJack F Vogel return IXGBE_SUCCESS; 35622969bf0eSJack F Vogel } 35632969bf0eSJack F Vogel 35642969bf0eSJack F Vogel /** 35652969bf0eSJack F Vogel * ixgbe_check_mac_link_generic - Determine link and speed status 35662969bf0eSJack F Vogel * @hw: pointer to hardware structure 35672969bf0eSJack F Vogel * @speed: pointer to link speed 35682969bf0eSJack F Vogel * @link_up: TRUE when link is up 35692969bf0eSJack F Vogel * @link_up_wait_to_complete: bool used to wait for link up or not 35702969bf0eSJack F Vogel * 35712969bf0eSJack F Vogel * Reads the links register to determine if link is up and the current speed 35722969bf0eSJack F Vogel **/ 35732969bf0eSJack F Vogel s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, 35742969bf0eSJack F Vogel bool *link_up, bool link_up_wait_to_complete) 35752969bf0eSJack F Vogel { 3576c0014855SJack F Vogel u32 links_reg, links_orig; 35772969bf0eSJack F Vogel u32 i; 35782969bf0eSJack F Vogel 35792969bf0eSJack F Vogel DEBUGFUNC("ixgbe_check_mac_link_generic"); 35802969bf0eSJack F Vogel 3581c0014855SJack F Vogel /* clear the old state */ 3582c0014855SJack F Vogel links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); 3583c0014855SJack F Vogel 35842969bf0eSJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); 3585c0014855SJack F Vogel 3586c0014855SJack F Vogel if (links_orig != links_reg) { 3587c0014855SJack F Vogel DEBUGOUT2("LINKS changed from %08X to %08X\n", 3588c0014855SJack F Vogel links_orig, links_reg); 3589c0014855SJack F Vogel } 3590c0014855SJack F Vogel 35912969bf0eSJack F Vogel if (link_up_wait_to_complete) { 35922969bf0eSJack F Vogel for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { 35932969bf0eSJack F Vogel if (links_reg & IXGBE_LINKS_UP) { 35942969bf0eSJack F Vogel *link_up = TRUE; 35952969bf0eSJack F Vogel break; 35962969bf0eSJack F Vogel } else { 35972969bf0eSJack F Vogel *link_up = FALSE; 35982969bf0eSJack F Vogel } 35992969bf0eSJack F Vogel msec_delay(100); 36002969bf0eSJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); 36012969bf0eSJack F Vogel } 36022969bf0eSJack F Vogel } else { 36032969bf0eSJack F Vogel if (links_reg & IXGBE_LINKS_UP) 36042969bf0eSJack F Vogel *link_up = TRUE; 36052969bf0eSJack F Vogel else 36062969bf0eSJack F Vogel *link_up = FALSE; 36072969bf0eSJack F Vogel } 36082969bf0eSJack F Vogel 36092969bf0eSJack F Vogel if ((links_reg & IXGBE_LINKS_SPEED_82599) == 36102969bf0eSJack F Vogel IXGBE_LINKS_SPEED_10G_82599) 36112969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_10GB_FULL; 36122969bf0eSJack F Vogel else if ((links_reg & IXGBE_LINKS_SPEED_82599) == 36132969bf0eSJack F Vogel IXGBE_LINKS_SPEED_1G_82599) 36142969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_1GB_FULL; 36151a4e3449SJack F Vogel else if ((links_reg & IXGBE_LINKS_SPEED_82599) == 36161a4e3449SJack F Vogel IXGBE_LINKS_SPEED_100_82599) 36172969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_100_FULL; 36181a4e3449SJack F Vogel else 36191a4e3449SJack F Vogel *speed = IXGBE_LINK_SPEED_UNKNOWN; 36202969bf0eSJack F Vogel 36212969bf0eSJack F Vogel return IXGBE_SUCCESS; 36222969bf0eSJack F Vogel } 36232969bf0eSJack F Vogel 36242969bf0eSJack F Vogel /** 36252969bf0eSJack F Vogel * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from 36262969bf0eSJack F Vogel * the EEPROM 36272969bf0eSJack F Vogel * @hw: pointer to hardware structure 36282969bf0eSJack F Vogel * @wwnn_prefix: the alternative WWNN prefix 36292969bf0eSJack F Vogel * @wwpn_prefix: the alternative WWPN prefix 36302969bf0eSJack F Vogel * 36312969bf0eSJack F Vogel * This function will read the EEPROM from the alternative SAN MAC address 36322969bf0eSJack F Vogel * block to check the support for the alternative WWNN/WWPN prefix support. 36332969bf0eSJack F Vogel **/ 36342969bf0eSJack F Vogel s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, 36352969bf0eSJack F Vogel u16 *wwpn_prefix) 36362969bf0eSJack F Vogel { 36372969bf0eSJack F Vogel u16 offset, caps; 36382969bf0eSJack F Vogel u16 alt_san_mac_blk_offset; 36392969bf0eSJack F Vogel 36402969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_wwn_prefix_generic"); 36412969bf0eSJack F Vogel 36422969bf0eSJack F Vogel /* clear output first */ 36432969bf0eSJack F Vogel *wwnn_prefix = 0xFFFF; 36442969bf0eSJack F Vogel *wwpn_prefix = 0xFFFF; 36452969bf0eSJack F Vogel 36462969bf0eSJack F Vogel /* check if alternative SAN MAC is supported */ 36472969bf0eSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, 36482969bf0eSJack F Vogel &alt_san_mac_blk_offset); 36492969bf0eSJack F Vogel 36502969bf0eSJack F Vogel if ((alt_san_mac_blk_offset == 0) || 36512969bf0eSJack F Vogel (alt_san_mac_blk_offset == 0xFFFF)) 36522969bf0eSJack F Vogel goto wwn_prefix_out; 36532969bf0eSJack F Vogel 36542969bf0eSJack F Vogel /* check capability in alternative san mac address block */ 36552969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; 36562969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, &caps); 36572969bf0eSJack F Vogel if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) 36582969bf0eSJack F Vogel goto wwn_prefix_out; 36592969bf0eSJack F Vogel 36602969bf0eSJack F Vogel /* get the corresponding prefix for WWNN/WWPN */ 36612969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; 36622969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, wwnn_prefix); 36632969bf0eSJack F Vogel 36642969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; 36652969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, wwpn_prefix); 36662969bf0eSJack F Vogel 36672969bf0eSJack F Vogel wwn_prefix_out: 36682969bf0eSJack F Vogel return IXGBE_SUCCESS; 36692969bf0eSJack F Vogel } 36701a4e3449SJack F Vogel 36711a4e3449SJack F Vogel /** 36721a4e3449SJack F Vogel * ixgbe_get_fcoe_boot_status_generic - Get FCOE boot status from EEPROM 36731a4e3449SJack F Vogel * @hw: pointer to hardware structure 36741a4e3449SJack F Vogel * @bs: the fcoe boot status 36751a4e3449SJack F Vogel * 36761a4e3449SJack F Vogel * This function will read the FCOE boot status from the iSCSI FCOE block 36771a4e3449SJack F Vogel **/ 36781a4e3449SJack F Vogel s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs) 36791a4e3449SJack F Vogel { 36801a4e3449SJack F Vogel u16 offset, caps, flags; 36811a4e3449SJack F Vogel s32 status; 36821a4e3449SJack F Vogel 36831a4e3449SJack F Vogel DEBUGFUNC("ixgbe_get_fcoe_boot_status_generic"); 36841a4e3449SJack F Vogel 36851a4e3449SJack F Vogel /* clear output first */ 36861a4e3449SJack F Vogel *bs = ixgbe_fcoe_bootstatus_unavailable; 36871a4e3449SJack F Vogel 36881a4e3449SJack F Vogel /* check if FCOE IBA block is present */ 36891a4e3449SJack F Vogel offset = IXGBE_FCOE_IBA_CAPS_BLK_PTR; 36901a4e3449SJack F Vogel status = hw->eeprom.ops.read(hw, offset, &caps); 36911a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) 36921a4e3449SJack F Vogel goto out; 36931a4e3449SJack F Vogel 36941a4e3449SJack F Vogel if (!(caps & IXGBE_FCOE_IBA_CAPS_FCOE)) 36951a4e3449SJack F Vogel goto out; 36961a4e3449SJack F Vogel 36971a4e3449SJack F Vogel /* check if iSCSI FCOE block is populated */ 36981a4e3449SJack F Vogel status = hw->eeprom.ops.read(hw, IXGBE_ISCSI_FCOE_BLK_PTR, &offset); 36991a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) 37001a4e3449SJack F Vogel goto out; 37011a4e3449SJack F Vogel 37021a4e3449SJack F Vogel if ((offset == 0) || (offset == 0xFFFF)) 37031a4e3449SJack F Vogel goto out; 37041a4e3449SJack F Vogel 37051a4e3449SJack F Vogel /* read fcoe flags in iSCSI FCOE block */ 37061a4e3449SJack F Vogel offset = offset + IXGBE_ISCSI_FCOE_FLAGS_OFFSET; 37071a4e3449SJack F Vogel status = hw->eeprom.ops.read(hw, offset, &flags); 37081a4e3449SJack F Vogel if (status != IXGBE_SUCCESS) 37091a4e3449SJack F Vogel goto out; 37101a4e3449SJack F Vogel 37111a4e3449SJack F Vogel if (flags & IXGBE_ISCSI_FCOE_FLAGS_ENABLE) 37121a4e3449SJack F Vogel *bs = ixgbe_fcoe_bootstatus_enabled; 37131a4e3449SJack F Vogel else 37141a4e3449SJack F Vogel *bs = ixgbe_fcoe_bootstatus_disabled; 37151a4e3449SJack F Vogel 37161a4e3449SJack F Vogel out: 37171a4e3449SJack F Vogel return status; 37181a4e3449SJack F Vogel } 37191a4e3449SJack F Vogel 37201a4e3449SJack F Vogel /** 37211a4e3449SJack F Vogel * ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow 37221a4e3449SJack F Vogel * control 37231a4e3449SJack F Vogel * @hw: pointer to hardware structure 37241a4e3449SJack F Vogel * 37251a4e3449SJack F Vogel * There are several phys that do not support autoneg flow control. This 37261a4e3449SJack F Vogel * function check the device id to see if the associated phy supports 37271a4e3449SJack F Vogel * autoneg flow control. 37281a4e3449SJack F Vogel **/ 37291a4e3449SJack F Vogel static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) 37301a4e3449SJack F Vogel { 37311a4e3449SJack F Vogel 37321a4e3449SJack F Vogel DEBUGFUNC("ixgbe_device_supports_autoneg_fc"); 37331a4e3449SJack F Vogel 37341a4e3449SJack F Vogel switch (hw->device_id) { 3735*85d0a26eSJack F Vogel case IXGBE_DEV_ID_X540T: 3736*85d0a26eSJack F Vogel return IXGBE_SUCCESS; 37371a4e3449SJack F Vogel case IXGBE_DEV_ID_82599_T3_LOM: 37381a4e3449SJack F Vogel return IXGBE_SUCCESS; 37391a4e3449SJack F Vogel default: 37401a4e3449SJack F Vogel return IXGBE_ERR_FC_NOT_SUPPORTED; 37411a4e3449SJack F Vogel } 37421a4e3449SJack F Vogel } 37431a4e3449SJack F Vogel 37441a4e3449SJack F Vogel /** 37451a4e3449SJack F Vogel * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing 37461a4e3449SJack F Vogel * @hw: pointer to hardware structure 37471a4e3449SJack F Vogel * @enable: enable or disable switch for anti-spoofing 37481a4e3449SJack F Vogel * @pf: Physical Function pool - do not enable anti-spoofing for the PF 37491a4e3449SJack F Vogel * 37501a4e3449SJack F Vogel **/ 37511a4e3449SJack F Vogel void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf) 37521a4e3449SJack F Vogel { 37531a4e3449SJack F Vogel int j; 37541a4e3449SJack F Vogel int pf_target_reg = pf >> 3; 37551a4e3449SJack F Vogel int pf_target_shift = pf % 8; 37561a4e3449SJack F Vogel u32 pfvfspoof = 0; 37571a4e3449SJack F Vogel 37581a4e3449SJack F Vogel if (hw->mac.type == ixgbe_mac_82598EB) 37591a4e3449SJack F Vogel return; 37601a4e3449SJack F Vogel 37611a4e3449SJack F Vogel if (enable) 37621a4e3449SJack F Vogel pfvfspoof = IXGBE_SPOOF_MACAS_MASK; 37631a4e3449SJack F Vogel 37641a4e3449SJack F Vogel /* 37651a4e3449SJack F Vogel * PFVFSPOOF register array is size 8 with 8 bits assigned to 37661a4e3449SJack F Vogel * MAC anti-spoof enables in each register array element. 37671a4e3449SJack F Vogel */ 37681a4e3449SJack F Vogel for (j = 0; j < IXGBE_PFVFSPOOF_REG_COUNT; j++) 37691a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(j), pfvfspoof); 37701a4e3449SJack F Vogel 37711a4e3449SJack F Vogel /* If not enabling anti-spoofing then done */ 37721a4e3449SJack F Vogel if (!enable) 37731a4e3449SJack F Vogel return; 37741a4e3449SJack F Vogel 37751a4e3449SJack F Vogel /* 37761a4e3449SJack F Vogel * The PF should be allowed to spoof so that it can support 37771a4e3449SJack F Vogel * emulation mode NICs. Reset the bit assigned to the PF 37781a4e3449SJack F Vogel */ 37791a4e3449SJack F Vogel pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg)); 37801a4e3449SJack F Vogel pfvfspoof ^= (1 << pf_target_shift); 37811a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(pf_target_reg), pfvfspoof); 37821a4e3449SJack F Vogel } 37831a4e3449SJack F Vogel 37841a4e3449SJack F Vogel /** 37851a4e3449SJack F Vogel * ixgbe_set_vlan_anti_spoofing - Enable/Disable VLAN anti-spoofing 37861a4e3449SJack F Vogel * @hw: pointer to hardware structure 37871a4e3449SJack F Vogel * @enable: enable or disable switch for VLAN anti-spoofing 37881a4e3449SJack F Vogel * @pf: Virtual Function pool - VF Pool to set for VLAN anti-spoofing 37891a4e3449SJack F Vogel * 37901a4e3449SJack F Vogel **/ 37911a4e3449SJack F Vogel void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) 37921a4e3449SJack F Vogel { 37931a4e3449SJack F Vogel int vf_target_reg = vf >> 3; 37941a4e3449SJack F Vogel int vf_target_shift = vf % 8 + IXGBE_SPOOF_VLANAS_SHIFT; 37951a4e3449SJack F Vogel u32 pfvfspoof; 37961a4e3449SJack F Vogel 37971a4e3449SJack F Vogel if (hw->mac.type == ixgbe_mac_82598EB) 37981a4e3449SJack F Vogel return; 37991a4e3449SJack F Vogel 38001a4e3449SJack F Vogel pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); 38011a4e3449SJack F Vogel if (enable) 38021a4e3449SJack F Vogel pfvfspoof |= (1 << vf_target_shift); 38031a4e3449SJack F Vogel else 38041a4e3449SJack F Vogel pfvfspoof &= ~(1 << vf_target_shift); 38051a4e3449SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); 38061a4e3449SJack F Vogel } 3807182b3808SJack F Vogel 3808182b3808SJack F Vogel /** 3809182b3808SJack F Vogel * ixgbe_get_device_caps_generic - Get additional device capabilities 3810182b3808SJack F Vogel * @hw: pointer to hardware structure 3811182b3808SJack F Vogel * @device_caps: the EEPROM word with the extra device capabilities 3812182b3808SJack F Vogel * 3813182b3808SJack F Vogel * This function will read the EEPROM location for the device capabilities, 3814182b3808SJack F Vogel * and return the word through device_caps. 3815182b3808SJack F Vogel **/ 3816182b3808SJack F Vogel s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps) 3817182b3808SJack F Vogel { 3818182b3808SJack F Vogel DEBUGFUNC("ixgbe_get_device_caps_generic"); 3819182b3808SJack F Vogel 3820182b3808SJack F Vogel hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); 3821182b3808SJack F Vogel 3822182b3808SJack F Vogel return IXGBE_SUCCESS; 3823182b3808SJack F Vogel } 3824182b3808SJack F Vogel 3825182b3808SJack F Vogel /** 3826182b3808SJack F Vogel * ixgbe_enable_relaxed_ordering_gen2 - Enable relaxed ordering 3827182b3808SJack F Vogel * @hw: pointer to hardware structure 3828182b3808SJack F Vogel * 3829182b3808SJack F Vogel **/ 3830182b3808SJack F Vogel void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw) 3831182b3808SJack F Vogel { 3832182b3808SJack F Vogel u32 regval; 3833182b3808SJack F Vogel u32 i; 3834182b3808SJack F Vogel 3835182b3808SJack F Vogel DEBUGFUNC("ixgbe_enable_relaxed_ordering_gen2"); 3836182b3808SJack F Vogel 3837182b3808SJack F Vogel /* Enable relaxed ordering */ 3838182b3808SJack F Vogel for (i = 0; i < hw->mac.max_tx_queues; i++) { 3839182b3808SJack F Vogel regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); 3840182b3808SJack F Vogel regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN; 3841182b3808SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); 3842182b3808SJack F Vogel } 3843182b3808SJack F Vogel 3844182b3808SJack F Vogel for (i = 0; i < hw->mac.max_rx_queues; i++) { 3845182b3808SJack F Vogel regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); 3846182b3808SJack F Vogel regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN | 3847182b3808SJack F Vogel IXGBE_DCA_RXCTRL_DESC_HSRO_EN); 3848182b3808SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); 3849182b3808SJack F Vogel } 3850182b3808SJack F Vogel 3851182b3808SJack F Vogel } 3852*85d0a26eSJack F Vogel 3853*85d0a26eSJack F Vogel /** 3854*85d0a26eSJack F Vogel * ixgbe_calculate_checksum - Calculate checksum for buffer 3855*85d0a26eSJack F Vogel * @buffer: pointer to EEPROM 3856*85d0a26eSJack F Vogel * @length: size of EEPROM to calculate a checksum for 3857*85d0a26eSJack F Vogel * Calculates the checksum for some buffer on a specified length. The 3858*85d0a26eSJack F Vogel * checksum calculated is returned. 3859*85d0a26eSJack F Vogel **/ 3860*85d0a26eSJack F Vogel static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) 3861*85d0a26eSJack F Vogel { 3862*85d0a26eSJack F Vogel u32 i; 3863*85d0a26eSJack F Vogel u8 sum = 0; 3864*85d0a26eSJack F Vogel 3865*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_calculate_checksum"); 3866*85d0a26eSJack F Vogel 3867*85d0a26eSJack F Vogel if (!buffer) 3868*85d0a26eSJack F Vogel return 0; 3869*85d0a26eSJack F Vogel 3870*85d0a26eSJack F Vogel for (i = 0; i < length; i++) 3871*85d0a26eSJack F Vogel sum += buffer[i]; 3872*85d0a26eSJack F Vogel 3873*85d0a26eSJack F Vogel return (u8) (0 - sum); 3874*85d0a26eSJack F Vogel } 3875*85d0a26eSJack F Vogel 3876*85d0a26eSJack F Vogel /** 3877*85d0a26eSJack F Vogel * ixgbe_host_interface_command - Issue command to manageability block 3878*85d0a26eSJack F Vogel * @hw: pointer to the HW structure 3879*85d0a26eSJack F Vogel * @buffer: contains the command to write and where the return status will 3880*85d0a26eSJack F Vogel * be placed 3881*85d0a26eSJack F Vogel * @lenght: lenght of buffer, must be multiple of 4 bytes 3882*85d0a26eSJack F Vogel * 3883*85d0a26eSJack F Vogel * Communicates with the manageability block. On success return IXGBE_SUCCESS 3884*85d0a26eSJack F Vogel * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. 3885*85d0a26eSJack F Vogel **/ 3886*85d0a26eSJack F Vogel static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, 3887*85d0a26eSJack F Vogel u32 length) 3888*85d0a26eSJack F Vogel { 3889*85d0a26eSJack F Vogel u32 hicr, i, bi; 3890*85d0a26eSJack F Vogel u32 hdr_size = sizeof(struct ixgbe_hic_hdr); 3891*85d0a26eSJack F Vogel u8 buf_len, dword_len; 3892*85d0a26eSJack F Vogel 3893*85d0a26eSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 3894*85d0a26eSJack F Vogel 3895*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_host_interface_command"); 3896*85d0a26eSJack F Vogel 3897*85d0a26eSJack F Vogel if (length == 0 || length & 0x3 || 3898*85d0a26eSJack F Vogel length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { 3899*85d0a26eSJack F Vogel DEBUGOUT("Buffer length failure.\n"); 3900*85d0a26eSJack F Vogel ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; 3901*85d0a26eSJack F Vogel goto out; 3902*85d0a26eSJack F Vogel } 3903*85d0a26eSJack F Vogel 3904*85d0a26eSJack F Vogel /* Check that the host interface is enabled. */ 3905*85d0a26eSJack F Vogel hicr = IXGBE_READ_REG(hw, IXGBE_HICR); 3906*85d0a26eSJack F Vogel if ((hicr & IXGBE_HICR_EN) == 0) { 3907*85d0a26eSJack F Vogel DEBUGOUT("IXGBE_HOST_EN bit disabled.\n"); 3908*85d0a26eSJack F Vogel ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; 3909*85d0a26eSJack F Vogel goto out; 3910*85d0a26eSJack F Vogel } 3911*85d0a26eSJack F Vogel 3912*85d0a26eSJack F Vogel /* Calculate length in DWORDs */ 3913*85d0a26eSJack F Vogel dword_len = length >> 2; 3914*85d0a26eSJack F Vogel 3915*85d0a26eSJack F Vogel /* 3916*85d0a26eSJack F Vogel * The device driver writes the relevant command block 3917*85d0a26eSJack F Vogel * into the ram area. 3918*85d0a26eSJack F Vogel */ 3919*85d0a26eSJack F Vogel for (i = 0; i < dword_len; i++) 3920*85d0a26eSJack F Vogel IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG, 3921*85d0a26eSJack F Vogel i, IXGBE_CPU_TO_LE32(buffer[i])); 3922*85d0a26eSJack F Vogel 3923*85d0a26eSJack F Vogel /* Setting this bit tells the ARC that a new command is pending. */ 3924*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); 3925*85d0a26eSJack F Vogel 3926*85d0a26eSJack F Vogel for (i = 0; i < IXGBE_HI_COMMAND_TIMEOUT; i++) { 3927*85d0a26eSJack F Vogel hicr = IXGBE_READ_REG(hw, IXGBE_HICR); 3928*85d0a26eSJack F Vogel if (!(hicr & IXGBE_HICR_C)) 3929*85d0a26eSJack F Vogel break; 3930*85d0a26eSJack F Vogel msec_delay(1); 3931*85d0a26eSJack F Vogel } 3932*85d0a26eSJack F Vogel 3933*85d0a26eSJack F Vogel /* Check command successful completion. */ 3934*85d0a26eSJack F Vogel if (i == IXGBE_HI_COMMAND_TIMEOUT || 3935*85d0a26eSJack F Vogel (!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) { 3936*85d0a26eSJack F Vogel DEBUGOUT("Command has failed with no status valid.\n"); 3937*85d0a26eSJack F Vogel ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; 3938*85d0a26eSJack F Vogel goto out; 3939*85d0a26eSJack F Vogel } 3940*85d0a26eSJack F Vogel 3941*85d0a26eSJack F Vogel /* Calculate length in DWORDs */ 3942*85d0a26eSJack F Vogel dword_len = hdr_size >> 2; 3943*85d0a26eSJack F Vogel 3944*85d0a26eSJack F Vogel /* first pull in the header so we know the buffer length */ 3945*85d0a26eSJack F Vogel for (bi = 0; bi < dword_len; bi++) { 3946*85d0a26eSJack F Vogel buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); 3947*85d0a26eSJack F Vogel IXGBE_LE32_TO_CPUS(&buffer[bi]); 3948*85d0a26eSJack F Vogel } 3949*85d0a26eSJack F Vogel 3950*85d0a26eSJack F Vogel /* If there is any thing in data position pull it in */ 3951*85d0a26eSJack F Vogel buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len; 3952*85d0a26eSJack F Vogel if (buf_len == 0) 3953*85d0a26eSJack F Vogel goto out; 3954*85d0a26eSJack F Vogel 3955*85d0a26eSJack F Vogel if (length < (buf_len + hdr_size)) { 3956*85d0a26eSJack F Vogel DEBUGOUT("Buffer not large enough for reply message.\n"); 3957*85d0a26eSJack F Vogel ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; 3958*85d0a26eSJack F Vogel goto out; 3959*85d0a26eSJack F Vogel } 3960*85d0a26eSJack F Vogel 3961*85d0a26eSJack F Vogel /* Calculate length in DWORDs, add 3 for odd lengths */ 3962*85d0a26eSJack F Vogel dword_len = (buf_len + 3) >> 2; 3963*85d0a26eSJack F Vogel 3964*85d0a26eSJack F Vogel /* Pull in the rest of the buffer (bi is where we left off)*/ 3965*85d0a26eSJack F Vogel for (; bi <= dword_len; bi++) { 3966*85d0a26eSJack F Vogel buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); 3967*85d0a26eSJack F Vogel IXGBE_LE32_TO_CPUS(&buffer[bi]); 3968*85d0a26eSJack F Vogel } 3969*85d0a26eSJack F Vogel 3970*85d0a26eSJack F Vogel out: 3971*85d0a26eSJack F Vogel return ret_val; 3972*85d0a26eSJack F Vogel } 3973*85d0a26eSJack F Vogel 3974*85d0a26eSJack F Vogel /** 3975*85d0a26eSJack F Vogel * ixgbe_set_fw_drv_ver_generic - Sends driver version to firmware 3976*85d0a26eSJack F Vogel * @hw: pointer to the HW structure 3977*85d0a26eSJack F Vogel * @maj: driver version major number 3978*85d0a26eSJack F Vogel * @min: driver version minor number 3979*85d0a26eSJack F Vogel * @build: driver version build number 3980*85d0a26eSJack F Vogel * @sub: driver version sub build number 3981*85d0a26eSJack F Vogel * 3982*85d0a26eSJack F Vogel * Sends driver version number to firmware through the manageability 3983*85d0a26eSJack F Vogel * block. On success return IXGBE_SUCCESS 3984*85d0a26eSJack F Vogel * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring 3985*85d0a26eSJack F Vogel * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. 3986*85d0a26eSJack F Vogel **/ 3987*85d0a26eSJack F Vogel s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, 3988*85d0a26eSJack F Vogel u8 build, u8 sub) 3989*85d0a26eSJack F Vogel { 3990*85d0a26eSJack F Vogel struct ixgbe_hic_drv_info fw_cmd; 3991*85d0a26eSJack F Vogel int i; 3992*85d0a26eSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 3993*85d0a26eSJack F Vogel 3994*85d0a26eSJack F Vogel DEBUGFUNC("ixgbe_set_fw_drv_ver_generic"); 3995*85d0a26eSJack F Vogel 3996*85d0a26eSJack F Vogel if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM) 3997*85d0a26eSJack F Vogel != IXGBE_SUCCESS) { 3998*85d0a26eSJack F Vogel ret_val = IXGBE_ERR_SWFW_SYNC; 3999*85d0a26eSJack F Vogel goto out; 4000*85d0a26eSJack F Vogel } 4001*85d0a26eSJack F Vogel 4002*85d0a26eSJack F Vogel fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; 4003*85d0a26eSJack F Vogel fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; 4004*85d0a26eSJack F Vogel fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 4005*85d0a26eSJack F Vogel fw_cmd.port_num = (u8)hw->bus.func; 4006*85d0a26eSJack F Vogel fw_cmd.ver_maj = maj; 4007*85d0a26eSJack F Vogel fw_cmd.ver_min = min; 4008*85d0a26eSJack F Vogel fw_cmd.ver_build = build; 4009*85d0a26eSJack F Vogel fw_cmd.ver_sub = sub; 4010*85d0a26eSJack F Vogel fw_cmd.hdr.checksum = 0; 4011*85d0a26eSJack F Vogel fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd, 4012*85d0a26eSJack F Vogel (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len)); 4013*85d0a26eSJack F Vogel fw_cmd.pad = 0; 4014*85d0a26eSJack F Vogel fw_cmd.pad2 = 0; 4015*85d0a26eSJack F Vogel 4016*85d0a26eSJack F Vogel for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { 4017*85d0a26eSJack F Vogel ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, 4018*85d0a26eSJack F Vogel sizeof(fw_cmd)); 4019*85d0a26eSJack F Vogel if (ret_val != IXGBE_SUCCESS) 4020*85d0a26eSJack F Vogel continue; 4021*85d0a26eSJack F Vogel 4022*85d0a26eSJack F Vogel if (fw_cmd.hdr.cmd_or_resp.ret_status == 4023*85d0a26eSJack F Vogel FW_CEM_RESP_STATUS_SUCCESS) 4024*85d0a26eSJack F Vogel ret_val = IXGBE_SUCCESS; 4025*85d0a26eSJack F Vogel else 4026*85d0a26eSJack F Vogel ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; 4027*85d0a26eSJack F Vogel 4028*85d0a26eSJack F Vogel break; 4029*85d0a26eSJack F Vogel } 4030*85d0a26eSJack F Vogel 4031*85d0a26eSJack F Vogel hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); 4032*85d0a26eSJack F Vogel out: 4033*85d0a26eSJack F Vogel return ret_val; 4034*85d0a26eSJack F Vogel } 4035*85d0a26eSJack F Vogel 4036*85d0a26eSJack F Vogel /** 4037*85d0a26eSJack F Vogel * ixgbe_set_rxpba_generic - Initialize Rx packet buffer 4038*85d0a26eSJack F Vogel * @hw: pointer to hardware structure 4039*85d0a26eSJack F Vogel * @num_pb: number of packet buffers to allocate 4040*85d0a26eSJack F Vogel * @headroom: reserve n KB of headroom 4041*85d0a26eSJack F Vogel * @strategy: packet buffer allocation strategy 4042*85d0a26eSJack F Vogel **/ 4043*85d0a26eSJack F Vogel void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom, 4044*85d0a26eSJack F Vogel int strategy) 4045*85d0a26eSJack F Vogel { 4046*85d0a26eSJack F Vogel u32 pbsize = hw->mac.rx_pb_size; 4047*85d0a26eSJack F Vogel int i = 0; 4048*85d0a26eSJack F Vogel u32 rxpktsize, txpktsize, txpbthresh; 4049*85d0a26eSJack F Vogel 4050*85d0a26eSJack F Vogel /* Reserve headroom */ 4051*85d0a26eSJack F Vogel pbsize -= headroom; 4052*85d0a26eSJack F Vogel 4053*85d0a26eSJack F Vogel if (!num_pb) 4054*85d0a26eSJack F Vogel num_pb = 1; 4055*85d0a26eSJack F Vogel 4056*85d0a26eSJack F Vogel /* Divide remaining packet buffer space amongst the number of packet 4057*85d0a26eSJack F Vogel * buffers requested using supplied strategy. 4058*85d0a26eSJack F Vogel */ 4059*85d0a26eSJack F Vogel switch (strategy) { 4060*85d0a26eSJack F Vogel case (PBA_STRATEGY_WEIGHTED): 4061*85d0a26eSJack F Vogel /* ixgbe_dcb_pba_80_48 strategy weight first half of packet 4062*85d0a26eSJack F Vogel * buffer with 5/8 of the packet buffer space. 4063*85d0a26eSJack F Vogel */ 4064*85d0a26eSJack F Vogel rxpktsize = (pbsize * 5 * 2) / (num_pb * 8); 4065*85d0a26eSJack F Vogel pbsize -= rxpktsize * (num_pb / 2); 4066*85d0a26eSJack F Vogel rxpktsize <<= IXGBE_RXPBSIZE_SHIFT; 4067*85d0a26eSJack F Vogel for (; i < (num_pb / 2); i++) 4068*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); 4069*85d0a26eSJack F Vogel /* Fall through to configure remaining packet buffers */ 4070*85d0a26eSJack F Vogel case (PBA_STRATEGY_EQUAL): 4071*85d0a26eSJack F Vogel rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT; 4072*85d0a26eSJack F Vogel for (; i < num_pb; i++) 4073*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); 4074*85d0a26eSJack F Vogel break; 4075*85d0a26eSJack F Vogel default: 4076*85d0a26eSJack F Vogel break; 4077*85d0a26eSJack F Vogel } 4078*85d0a26eSJack F Vogel 4079*85d0a26eSJack F Vogel /* Only support an equally distributed Tx packet buffer strategy. */ 4080*85d0a26eSJack F Vogel txpktsize = IXGBE_TXPBSIZE_MAX / num_pb; 4081*85d0a26eSJack F Vogel txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX; 4082*85d0a26eSJack F Vogel for (i = 0; i < num_pb; i++) { 4083*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize); 4084*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh); 4085*85d0a26eSJack F Vogel } 4086*85d0a26eSJack F Vogel 4087*85d0a26eSJack F Vogel /* Clear unused TCs, if any, to zero buffer size*/ 4088*85d0a26eSJack F Vogel for (; i < IXGBE_MAX_PB; i++) { 4089*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); 4090*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0); 4091*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0); 4092*85d0a26eSJack F Vogel } 4093*85d0a26eSJack F Vogel } 4094*85d0a26eSJack F Vogel 4095*85d0a26eSJack F Vogel /** 4096*85d0a26eSJack F Vogel * ixgbe_clear_tx_pending - Clear pending TX work from the PCIe fifo 4097*85d0a26eSJack F Vogel * @hw: pointer to the hardware structure 4098*85d0a26eSJack F Vogel * 4099*85d0a26eSJack F Vogel * The 82599 and x540 MACs can experience issues if TX work is still pending 4100*85d0a26eSJack F Vogel * when a reset occurs. This function prevents this by flushing the PCIe 4101*85d0a26eSJack F Vogel * buffers on the system. 4102*85d0a26eSJack F Vogel **/ 4103*85d0a26eSJack F Vogel void ixgbe_clear_tx_pending(struct ixgbe_hw *hw) 4104*85d0a26eSJack F Vogel { 4105*85d0a26eSJack F Vogel u32 gcr_ext, hlreg0; 4106*85d0a26eSJack F Vogel 4107*85d0a26eSJack F Vogel /* 4108*85d0a26eSJack F Vogel * If double reset is not requested then all transactions should 4109*85d0a26eSJack F Vogel * already be clear and as such there is no work to do 4110*85d0a26eSJack F Vogel */ 4111*85d0a26eSJack F Vogel if (!(hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED)) 4112*85d0a26eSJack F Vogel return; 4113*85d0a26eSJack F Vogel 4114*85d0a26eSJack F Vogel /* 4115*85d0a26eSJack F Vogel * Set loopback enable to prevent any transmits from being sent 4116*85d0a26eSJack F Vogel * should the link come up. This assumes that the RXCTRL.RXEN bit 4117*85d0a26eSJack F Vogel * has already been cleared. 4118*85d0a26eSJack F Vogel */ 4119*85d0a26eSJack F Vogel hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); 4120*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK); 4121*85d0a26eSJack F Vogel 4122*85d0a26eSJack F Vogel /* initiate cleaning flow for buffers in the PCIe transaction layer */ 4123*85d0a26eSJack F Vogel gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); 4124*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, 4125*85d0a26eSJack F Vogel gcr_ext | IXGBE_GCR_EXT_BUFFERS_CLEAR); 4126*85d0a26eSJack F Vogel 4127*85d0a26eSJack F Vogel /* Flush all writes and allow 20usec for all transactions to clear */ 4128*85d0a26eSJack F Vogel IXGBE_WRITE_FLUSH(hw); 4129*85d0a26eSJack F Vogel usec_delay(20); 4130*85d0a26eSJack F Vogel 4131*85d0a26eSJack F Vogel /* restore previous register values */ 4132*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); 4133*85d0a26eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); 4134*85d0a26eSJack F Vogel } 4135*85d0a26eSJack F Vogel 4136