19ca4041bSJack F Vogel /****************************************************************************** 213705f88SJack F Vogel 3c0014855SJack F Vogel Copyright (c) 2001-2010, Intel Corporation 413705f88SJack F Vogel All rights reserved. 513705f88SJack F Vogel 613705f88SJack F Vogel Redistribution and use in source and binary forms, with or without 713705f88SJack F Vogel modification, are permitted provided that the following conditions are met: 813705f88SJack F Vogel 913705f88SJack F Vogel 1. Redistributions of source code must retain the above copyright notice, 1013705f88SJack F Vogel this list of conditions and the following disclaimer. 1113705f88SJack F Vogel 1213705f88SJack F Vogel 2. Redistributions in binary form must reproduce the above copyright 1313705f88SJack F Vogel notice, this list of conditions and the following disclaimer in the 1413705f88SJack F Vogel documentation and/or other materials provided with the distribution. 1513705f88SJack F Vogel 1613705f88SJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its 1713705f88SJack F Vogel contributors may be used to endorse or promote products derived from 1813705f88SJack F Vogel this software without specific prior written permission. 1913705f88SJack F Vogel 2013705f88SJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2113705f88SJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2213705f88SJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2313705f88SJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2413705f88SJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2513705f88SJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2613705f88SJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2713705f88SJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2813705f88SJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2913705f88SJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3013705f88SJack F Vogel POSSIBILITY OF SUCH DAMAGE. 3113705f88SJack F Vogel 329ca4041bSJack F Vogel ******************************************************************************/ 3313705f88SJack F Vogel /*$FreeBSD$*/ 3413705f88SJack F Vogel 3513705f88SJack F Vogel #include "ixgbe_common.h" 3613705f88SJack F Vogel #include "ixgbe_api.h" 3713705f88SJack F Vogel 3813705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); 3913705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); 4013705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); 4113705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw); 4213705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw); 4313705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, 4413705f88SJack F Vogel u16 count); 4513705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); 4613705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); 4713705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); 4813705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw); 4913705f88SJack F Vogel 5013705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); 512969bf0eSJack F Vogel static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, 522969bf0eSJack F Vogel u16 *san_mac_offset); 532969bf0eSJack F Vogel s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan); 5413705f88SJack F Vogel 5513705f88SJack F Vogel /** 569ca4041bSJack F Vogel * ixgbe_init_ops_generic - Inits function ptrs 579ca4041bSJack F Vogel * @hw: pointer to the hardware structure 5813705f88SJack F Vogel * 599ca4041bSJack F Vogel * Initialize the function pointers. 6013705f88SJack F Vogel **/ 619ca4041bSJack F Vogel s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) 6213705f88SJack F Vogel { 639ca4041bSJack F Vogel struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 649ca4041bSJack F Vogel struct ixgbe_mac_info *mac = &hw->mac; 659ca4041bSJack F Vogel u32 eec = IXGBE_READ_REG(hw, IXGBE_EEC); 6613705f88SJack F Vogel 672969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_ops_generic"); 682969bf0eSJack F Vogel 6913705f88SJack F Vogel /* EEPROM */ 709ca4041bSJack F Vogel eeprom->ops.init_params = &ixgbe_init_eeprom_params_generic; 719ca4041bSJack F Vogel /* If EEPROM is valid (bit 8 = 1), use EERD otherwise use bit bang */ 729ca4041bSJack F Vogel if (eec & (1 << 8)) 732969bf0eSJack F Vogel eeprom->ops.read = &ixgbe_read_eerd_generic; 749ca4041bSJack F Vogel else 759ca4041bSJack F Vogel eeprom->ops.read = &ixgbe_read_eeprom_bit_bang_generic; 769ca4041bSJack F Vogel eeprom->ops.write = &ixgbe_write_eeprom_generic; 779ca4041bSJack F Vogel eeprom->ops.validate_checksum = 7813705f88SJack F Vogel &ixgbe_validate_eeprom_checksum_generic; 799ca4041bSJack F Vogel eeprom->ops.update_checksum = &ixgbe_update_eeprom_checksum_generic; 802969bf0eSJack F Vogel eeprom->ops.calc_checksum = &ixgbe_calc_eeprom_checksum_generic; 819ca4041bSJack F Vogel 829ca4041bSJack F Vogel /* MAC */ 839ca4041bSJack F Vogel mac->ops.init_hw = &ixgbe_init_hw_generic; 849ca4041bSJack F Vogel mac->ops.reset_hw = NULL; 859ca4041bSJack F Vogel mac->ops.start_hw = &ixgbe_start_hw_generic; 869ca4041bSJack F Vogel mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic; 879ca4041bSJack F Vogel mac->ops.get_media_type = NULL; 881b6e0dbaSJack F Vogel mac->ops.get_supported_physical_layer = NULL; 890ac6dfecSJack F Vogel mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic; 909ca4041bSJack F Vogel mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic; 919ca4041bSJack F Vogel mac->ops.stop_adapter = &ixgbe_stop_adapter_generic; 929ca4041bSJack F Vogel mac->ops.get_bus_info = &ixgbe_get_bus_info_generic; 931b6e0dbaSJack F Vogel mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie; 94d8602bb9SJack F Vogel mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync; 95d8602bb9SJack F Vogel mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync; 969ca4041bSJack F Vogel 979ca4041bSJack F Vogel /* LEDs */ 989ca4041bSJack F Vogel mac->ops.led_on = &ixgbe_led_on_generic; 999ca4041bSJack F Vogel mac->ops.led_off = &ixgbe_led_off_generic; 1000ac6dfecSJack F Vogel mac->ops.blink_led_start = &ixgbe_blink_led_start_generic; 1010ac6dfecSJack F Vogel mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic; 1029ca4041bSJack F Vogel 10313705f88SJack F Vogel /* RAR, Multicast, VLAN */ 1049ca4041bSJack F Vogel mac->ops.set_rar = &ixgbe_set_rar_generic; 1055b7f4cedSJack F Vogel mac->ops.clear_rar = &ixgbe_clear_rar_generic; 1060ac6dfecSJack F Vogel mac->ops.insert_mac_addr = NULL; 1079ca4041bSJack F Vogel mac->ops.set_vmdq = NULL; 1085b7f4cedSJack F Vogel mac->ops.clear_vmdq = NULL; 1099ca4041bSJack F Vogel mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic; 1109ca4041bSJack F Vogel mac->ops.update_uc_addr_list = &ixgbe_update_uc_addr_list_generic; 1119ca4041bSJack F Vogel mac->ops.update_mc_addr_list = &ixgbe_update_mc_addr_list_generic; 1129ca4041bSJack F Vogel mac->ops.enable_mc = &ixgbe_enable_mc_generic; 1139ca4041bSJack F Vogel mac->ops.disable_mc = &ixgbe_disable_mc_generic; 1145b7f4cedSJack F Vogel mac->ops.clear_vfta = NULL; 1155b7f4cedSJack F Vogel mac->ops.set_vfta = NULL; 1165b7f4cedSJack F Vogel mac->ops.init_uta_tables = NULL; 1179ca4041bSJack F Vogel 1180ac6dfecSJack F Vogel /* Flow Control */ 1190ac6dfecSJack F Vogel mac->ops.fc_enable = &ixgbe_fc_enable_generic; 1209ca4041bSJack F Vogel 1219ca4041bSJack F Vogel /* Link */ 1229ca4041bSJack F Vogel mac->ops.get_link_capabilities = NULL; 1239ca4041bSJack F Vogel mac->ops.setup_link = NULL; 1249ca4041bSJack F Vogel mac->ops.check_link = NULL; 12513705f88SJack F Vogel 12613705f88SJack F Vogel return IXGBE_SUCCESS; 12713705f88SJack F Vogel } 12813705f88SJack F Vogel 12913705f88SJack F Vogel /** 1309ca4041bSJack F Vogel * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx 13113705f88SJack F Vogel * @hw: pointer to hardware structure 13213705f88SJack F Vogel * 13313705f88SJack F Vogel * Starts the hardware by filling the bus info structure and media type, clears 13413705f88SJack F Vogel * all on chip counters, initializes receive address registers, multicast 13513705f88SJack F Vogel * table, VLAN filter table, calls routine to set up link and flow control 13613705f88SJack F Vogel * settings, and leaves transmit and receive units disabled and uninitialized 13713705f88SJack F Vogel **/ 13813705f88SJack F Vogel s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) 13913705f88SJack F Vogel { 14013705f88SJack F Vogel u32 ctrl_ext; 1410ac6dfecSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 14213705f88SJack F Vogel 1432969bf0eSJack F Vogel DEBUGFUNC("ixgbe_start_hw_generic"); 1442969bf0eSJack F Vogel 14513705f88SJack F Vogel /* Set the media type */ 1469ca4041bSJack F Vogel hw->phy.media_type = hw->mac.ops.get_media_type(hw); 14713705f88SJack F Vogel 1480ac6dfecSJack F Vogel /* PHY ops initialization must be done in reset_hw() */ 14913705f88SJack F Vogel 15013705f88SJack F Vogel /* Clear the VLAN filter table */ 1519ca4041bSJack F Vogel hw->mac.ops.clear_vfta(hw); 15213705f88SJack F Vogel 15313705f88SJack F Vogel /* Clear statistics registers */ 1549ca4041bSJack F Vogel hw->mac.ops.clear_hw_cntrs(hw); 15513705f88SJack F Vogel 15613705f88SJack F Vogel /* Set No Snoop Disable */ 15713705f88SJack F Vogel ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); 15813705f88SJack F Vogel ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; 15913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); 1609ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 16113705f88SJack F Vogel 1620ac6dfecSJack F Vogel /* Setup flow control */ 1630ac6dfecSJack F Vogel ixgbe_setup_fc(hw, 0); 1640ac6dfecSJack F Vogel 16513705f88SJack F Vogel /* Clear adapter stopped flag */ 16613705f88SJack F Vogel hw->adapter_stopped = FALSE; 16713705f88SJack F Vogel 1680ac6dfecSJack F Vogel return ret_val; 16913705f88SJack F Vogel } 17013705f88SJack F Vogel 17113705f88SJack F Vogel /** 17213705f88SJack F Vogel * ixgbe_init_hw_generic - Generic hardware initialization 17313705f88SJack F Vogel * @hw: pointer to hardware structure 17413705f88SJack F Vogel * 1759ca4041bSJack F Vogel * Initialize the hardware by resetting the hardware, filling the bus info 17613705f88SJack F Vogel * structure and media type, clears all on chip counters, initializes receive 17713705f88SJack F Vogel * address registers, multicast table, VLAN filter table, calls routine to set 17813705f88SJack F Vogel * up link and flow control settings, and leaves transmit and receive units 17913705f88SJack F Vogel * disabled and uninitialized 18013705f88SJack F Vogel **/ 18113705f88SJack F Vogel s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) 18213705f88SJack F Vogel { 1830ac6dfecSJack F Vogel s32 status = IXGBE_SUCCESS; 1840ac6dfecSJack F Vogel 1852969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_hw_generic"); 1862969bf0eSJack F Vogel 18713705f88SJack F Vogel /* Reset the hardware */ 1880ac6dfecSJack F Vogel status = hw->mac.ops.reset_hw(hw); 18913705f88SJack F Vogel 1900ac6dfecSJack F Vogel if (status == IXGBE_SUCCESS) { 19113705f88SJack F Vogel /* Start the HW */ 1920ac6dfecSJack F Vogel status = hw->mac.ops.start_hw(hw); 1930ac6dfecSJack F Vogel } 19413705f88SJack F Vogel 1950ac6dfecSJack F Vogel return status; 19613705f88SJack F Vogel } 19713705f88SJack F Vogel 19813705f88SJack F Vogel /** 19913705f88SJack F Vogel * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters 20013705f88SJack F Vogel * @hw: pointer to hardware structure 20113705f88SJack F Vogel * 20213705f88SJack F Vogel * Clears all hardware statistics counters by reading them from the hardware 20313705f88SJack F Vogel * Statistics counters are clear on read. 20413705f88SJack F Vogel **/ 20513705f88SJack F Vogel s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) 20613705f88SJack F Vogel { 20713705f88SJack F Vogel u16 i = 0; 20813705f88SJack F Vogel 2092969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_hw_cntrs_generic"); 2102969bf0eSJack F Vogel 21113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_CRCERRS); 21213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ILLERRC); 21313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ERRBC); 21413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MSPDC); 21513705f88SJack F Vogel for (i = 0; i < 8; i++) 21613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPC(i)); 21713705f88SJack F Vogel 21813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MLFC); 21913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MRFC); 22013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RLEC); 22113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONTXC); 22213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); 2230ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 2240ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); 2250ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); 2260ac6dfecSJack F Vogel } else { 2271b6e0dbaSJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONRXC); 22813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); 2290ac6dfecSJack F Vogel } 23013705f88SJack F Vogel 23113705f88SJack F Vogel for (i = 0; i < 8; i++) { 23213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); 23313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); 2340ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) { 2350ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); 2360ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); 2370ac6dfecSJack F Vogel } else { 2381b6e0dbaSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); 23913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); 24013705f88SJack F Vogel } 2410ac6dfecSJack F Vogel } 2420ac6dfecSJack F Vogel if (hw->mac.type >= ixgbe_mac_82599EB) 2430ac6dfecSJack F Vogel for (i = 0; i < 8; i++) 2440ac6dfecSJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); 24513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC64); 24613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC127); 24713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC255); 24813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC511); 24913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1023); 25013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1522); 25113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPRC); 25213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPRC); 25313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPRC); 25413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPTC); 25513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCL); 25613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCH); 25713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCL); 25813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCH); 25913705f88SJack F Vogel for (i = 0; i < 8; i++) 26013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RNBC(i)); 26113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RUC); 26213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RFC); 26313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ROC); 26413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RJC); 26513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPRC); 26613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPDC); 26713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPTC); 26813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORL); 26913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORH); 27013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPR); 27113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPT); 27213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC64); 27313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC127); 27413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC255); 27513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC511); 27613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1023); 27713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1522); 27813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPTC); 27913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPTC); 28013705f88SJack F Vogel for (i = 0; i < 16; i++) { 28113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPRC(i)); 28213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC(i)); 28313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPTC(i)); 28413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC(i)); 28513705f88SJack F Vogel } 28613705f88SJack F Vogel 28713705f88SJack F Vogel return IXGBE_SUCCESS; 28813705f88SJack F Vogel } 28913705f88SJack F Vogel 29013705f88SJack F Vogel /** 2911b6e0dbaSJack F Vogel * ixgbe_read_pba_num_generic - Reads part number from EEPROM 2929ca4041bSJack F Vogel * @hw: pointer to hardware structure 2939ca4041bSJack F Vogel * @pba_num: stores the part number from the EEPROM 2949ca4041bSJack F Vogel * 2959ca4041bSJack F Vogel * Reads the part number from the EEPROM. 2969ca4041bSJack F Vogel **/ 2979ca4041bSJack F Vogel s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) 2989ca4041bSJack F Vogel { 2999ca4041bSJack F Vogel s32 ret_val; 3009ca4041bSJack F Vogel u16 data; 3019ca4041bSJack F Vogel 3029ca4041bSJack F Vogel DEBUGFUNC("ixgbe_read_pba_num_generic"); 3039ca4041bSJack F Vogel 3049ca4041bSJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); 3059ca4041bSJack F Vogel if (ret_val) { 3069ca4041bSJack F Vogel DEBUGOUT("NVM Read Error\n"); 3079ca4041bSJack F Vogel return ret_val; 3089ca4041bSJack F Vogel } 3099ca4041bSJack F Vogel *pba_num = (u32)(data << 16); 3109ca4041bSJack F Vogel 3119ca4041bSJack F Vogel ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data); 3129ca4041bSJack F Vogel if (ret_val) { 3139ca4041bSJack F Vogel DEBUGOUT("NVM Read Error\n"); 3149ca4041bSJack F Vogel return ret_val; 3159ca4041bSJack F Vogel } 3169ca4041bSJack F Vogel *pba_num |= data; 3179ca4041bSJack F Vogel 3189ca4041bSJack F Vogel return IXGBE_SUCCESS; 3199ca4041bSJack F Vogel } 3209ca4041bSJack F Vogel 3219ca4041bSJack F Vogel /** 32213705f88SJack F Vogel * ixgbe_get_mac_addr_generic - Generic get MAC address 32313705f88SJack F Vogel * @hw: pointer to hardware structure 32413705f88SJack F Vogel * @mac_addr: Adapter MAC address 32513705f88SJack F Vogel * 32613705f88SJack F Vogel * Reads the adapter's MAC address from first Receive Address Register (RAR0) 32713705f88SJack F Vogel * A reset of the adapter must be performed prior to calling this function 32813705f88SJack F Vogel * in order for the MAC address to have been loaded from the EEPROM into RAR0 32913705f88SJack F Vogel **/ 33013705f88SJack F Vogel s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) 33113705f88SJack F Vogel { 33213705f88SJack F Vogel u32 rar_high; 33313705f88SJack F Vogel u32 rar_low; 33413705f88SJack F Vogel u16 i; 33513705f88SJack F Vogel 3362969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_mac_addr_generic"); 3372969bf0eSJack F Vogel 33813705f88SJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0)); 33913705f88SJack F Vogel rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0)); 34013705f88SJack F Vogel 34113705f88SJack F Vogel for (i = 0; i < 4; i++) 34213705f88SJack F Vogel mac_addr[i] = (u8)(rar_low >> (i*8)); 34313705f88SJack F Vogel 34413705f88SJack F Vogel for (i = 0; i < 2; i++) 34513705f88SJack F Vogel mac_addr[i+4] = (u8)(rar_high >> (i*8)); 34613705f88SJack F Vogel 34713705f88SJack F Vogel return IXGBE_SUCCESS; 34813705f88SJack F Vogel } 34913705f88SJack F Vogel 35013705f88SJack F Vogel /** 35113705f88SJack F Vogel * ixgbe_get_bus_info_generic - Generic set PCI bus info 35213705f88SJack F Vogel * @hw: pointer to hardware structure 35313705f88SJack F Vogel * 35413705f88SJack F Vogel * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure 35513705f88SJack F Vogel **/ 35613705f88SJack F Vogel s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) 35713705f88SJack F Vogel { 3581b6e0dbaSJack F Vogel struct ixgbe_mac_info *mac = &hw->mac; 35913705f88SJack F Vogel u16 link_status; 36013705f88SJack F Vogel 3612969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_bus_info_generic"); 3622969bf0eSJack F Vogel 36313705f88SJack F Vogel hw->bus.type = ixgbe_bus_type_pci_express; 36413705f88SJack F Vogel 36513705f88SJack F Vogel /* Get the negotiated link width and speed from PCI config space */ 36613705f88SJack F Vogel link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); 36713705f88SJack F Vogel 36813705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_WIDTH) { 36913705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_1: 37013705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x1; 37113705f88SJack F Vogel break; 37213705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_2: 37313705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x2; 37413705f88SJack F Vogel break; 37513705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_4: 37613705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x4; 37713705f88SJack F Vogel break; 37813705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_8: 37913705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x8; 38013705f88SJack F Vogel break; 38113705f88SJack F Vogel default: 38213705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_unknown; 38313705f88SJack F Vogel break; 38413705f88SJack F Vogel } 38513705f88SJack F Vogel 38613705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_SPEED) { 38713705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_2500: 38813705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_2500; 38913705f88SJack F Vogel break; 39013705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_5000: 39113705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_5000; 39213705f88SJack F Vogel break; 39313705f88SJack F Vogel default: 39413705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_unknown; 39513705f88SJack F Vogel break; 39613705f88SJack F Vogel } 39713705f88SJack F Vogel 3981b6e0dbaSJack F Vogel mac->ops.set_lan_id(hw); 3991b6e0dbaSJack F Vogel 40013705f88SJack F Vogel return IXGBE_SUCCESS; 40113705f88SJack F Vogel } 40213705f88SJack F Vogel 40313705f88SJack F Vogel /** 4041b6e0dbaSJack F Vogel * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices 4051b6e0dbaSJack F Vogel * @hw: pointer to the HW structure 4061b6e0dbaSJack F Vogel * 4071b6e0dbaSJack F Vogel * Determines the LAN function id by reading memory-mapped registers 4081b6e0dbaSJack F Vogel * and swaps the port value if requested. 4091b6e0dbaSJack F Vogel **/ 4101b6e0dbaSJack F Vogel void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) 4111b6e0dbaSJack F Vogel { 4121b6e0dbaSJack F Vogel struct ixgbe_bus_info *bus = &hw->bus; 4131b6e0dbaSJack F Vogel u32 reg; 4141b6e0dbaSJack F Vogel 4152969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie"); 4162969bf0eSJack F Vogel 4171b6e0dbaSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_STATUS); 4181b6e0dbaSJack F Vogel bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; 4190ac6dfecSJack F Vogel bus->lan_id = bus->func; 4201b6e0dbaSJack F Vogel 4211b6e0dbaSJack F Vogel /* check for a port swap */ 4221b6e0dbaSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_FACTPS); 4231b6e0dbaSJack F Vogel if (reg & IXGBE_FACTPS_LFS) 4241b6e0dbaSJack F Vogel bus->func ^= 0x1; 4251b6e0dbaSJack F Vogel } 4261b6e0dbaSJack F Vogel 4271b6e0dbaSJack F Vogel /** 4289ca4041bSJack F Vogel * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units 42913705f88SJack F Vogel * @hw: pointer to hardware structure 43013705f88SJack F Vogel * 43113705f88SJack F Vogel * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, 43213705f88SJack F Vogel * disables transmit and receive units. The adapter_stopped flag is used by 43313705f88SJack F Vogel * the shared code and drivers to determine if the adapter is in a stopped 43413705f88SJack F Vogel * state and should not touch the hardware. 43513705f88SJack F Vogel **/ 43613705f88SJack F Vogel s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) 43713705f88SJack F Vogel { 43813705f88SJack F Vogel u32 number_of_queues; 43913705f88SJack F Vogel u32 reg_val; 44013705f88SJack F Vogel u16 i; 44113705f88SJack F Vogel 4422969bf0eSJack F Vogel DEBUGFUNC("ixgbe_stop_adapter_generic"); 4432969bf0eSJack F Vogel 44413705f88SJack F Vogel /* 44513705f88SJack F Vogel * Set the adapter_stopped flag so other driver functions stop touching 44613705f88SJack F Vogel * the hardware 44713705f88SJack F Vogel */ 44813705f88SJack F Vogel hw->adapter_stopped = TRUE; 44913705f88SJack F Vogel 45013705f88SJack F Vogel /* Disable the receive unit */ 45113705f88SJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 45213705f88SJack F Vogel reg_val &= ~(IXGBE_RXCTRL_RXEN); 45313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val); 4549ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 45513705f88SJack F Vogel msec_delay(2); 45613705f88SJack F Vogel 45713705f88SJack F Vogel /* Clear interrupt mask to stop from interrupts being generated */ 45813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); 45913705f88SJack F Vogel 46013705f88SJack F Vogel /* Clear any pending interrupts */ 46113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_EICR); 46213705f88SJack F Vogel 46313705f88SJack F Vogel /* Disable the transmit unit. Each queue must be disabled. */ 4649ca4041bSJack F Vogel number_of_queues = hw->mac.max_tx_queues; 46513705f88SJack F Vogel for (i = 0; i < number_of_queues; i++) { 46613705f88SJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); 46713705f88SJack F Vogel if (reg_val & IXGBE_TXDCTL_ENABLE) { 46813705f88SJack F Vogel reg_val &= ~IXGBE_TXDCTL_ENABLE; 46913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), reg_val); 47013705f88SJack F Vogel } 47113705f88SJack F Vogel } 47213705f88SJack F Vogel 4739ca4041bSJack F Vogel /* 4749ca4041bSJack F Vogel * Prevent the PCI-E bus from from hanging by disabling PCI-E master 4759ca4041bSJack F Vogel * access and verify no pending requests 4769ca4041bSJack F Vogel */ 477c0014855SJack F Vogel ixgbe_disable_pcie_master(hw); 4789ca4041bSJack F Vogel 47913705f88SJack F Vogel return IXGBE_SUCCESS; 48013705f88SJack F Vogel } 48113705f88SJack F Vogel 48213705f88SJack F Vogel /** 48313705f88SJack F Vogel * ixgbe_led_on_generic - Turns on the software controllable LEDs. 48413705f88SJack F Vogel * @hw: pointer to hardware structure 48513705f88SJack F Vogel * @index: led number to turn on 48613705f88SJack F Vogel **/ 48713705f88SJack F Vogel s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) 48813705f88SJack F Vogel { 48913705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 49013705f88SJack F Vogel 4912969bf0eSJack F Vogel DEBUGFUNC("ixgbe_led_on_generic"); 4922969bf0eSJack F Vogel 49313705f88SJack F Vogel /* To turn on the LED, set mode to ON. */ 49413705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 49513705f88SJack F Vogel led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); 49613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 4979ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 49813705f88SJack F Vogel 49913705f88SJack F Vogel return IXGBE_SUCCESS; 50013705f88SJack F Vogel } 50113705f88SJack F Vogel 50213705f88SJack F Vogel /** 50313705f88SJack F Vogel * ixgbe_led_off_generic - Turns off the software controllable LEDs. 50413705f88SJack F Vogel * @hw: pointer to hardware structure 50513705f88SJack F Vogel * @index: led number to turn off 50613705f88SJack F Vogel **/ 50713705f88SJack F Vogel s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) 50813705f88SJack F Vogel { 50913705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 51013705f88SJack F Vogel 5112969bf0eSJack F Vogel DEBUGFUNC("ixgbe_led_off_generic"); 5122969bf0eSJack F Vogel 51313705f88SJack F Vogel /* To turn off the LED, set mode to OFF. */ 51413705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 51513705f88SJack F Vogel led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); 51613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 5179ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 51813705f88SJack F Vogel 51913705f88SJack F Vogel return IXGBE_SUCCESS; 52013705f88SJack F Vogel } 52113705f88SJack F Vogel 52213705f88SJack F Vogel /** 52313705f88SJack F Vogel * ixgbe_init_eeprom_params_generic - Initialize EEPROM params 52413705f88SJack F Vogel * @hw: pointer to hardware structure 52513705f88SJack F Vogel * 52613705f88SJack F Vogel * Initializes the EEPROM parameters ixgbe_eeprom_info within the 52713705f88SJack F Vogel * ixgbe_hw struct in order to set up EEPROM access. 52813705f88SJack F Vogel **/ 52913705f88SJack F Vogel s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) 53013705f88SJack F Vogel { 53113705f88SJack F Vogel struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 53213705f88SJack F Vogel u32 eec; 53313705f88SJack F Vogel u16 eeprom_size; 53413705f88SJack F Vogel 5352969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_eeprom_params_generic"); 5362969bf0eSJack F Vogel 53713705f88SJack F Vogel if (eeprom->type == ixgbe_eeprom_uninitialized) { 53813705f88SJack F Vogel eeprom->type = ixgbe_eeprom_none; 5395b7f4cedSJack F Vogel /* Set default semaphore delay to 10ms which is a well 5405b7f4cedSJack F Vogel * tested value */ 5415b7f4cedSJack F Vogel eeprom->semaphore_delay = 10; 54213705f88SJack F Vogel 54313705f88SJack F Vogel /* 54413705f88SJack F Vogel * Check for EEPROM present first. 54513705f88SJack F Vogel * If not present leave as none 54613705f88SJack F Vogel */ 54713705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 54813705f88SJack F Vogel if (eec & IXGBE_EEC_PRES) { 54913705f88SJack F Vogel eeprom->type = ixgbe_eeprom_spi; 55013705f88SJack F Vogel 55113705f88SJack F Vogel /* 55213705f88SJack F Vogel * SPI EEPROM is assumed here. This code would need to 55313705f88SJack F Vogel * change if a future EEPROM is not SPI. 55413705f88SJack F Vogel */ 55513705f88SJack F Vogel eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 55613705f88SJack F Vogel IXGBE_EEC_SIZE_SHIFT); 55713705f88SJack F Vogel eeprom->word_size = 1 << (eeprom_size + 5582969bf0eSJack F Vogel IXGBE_EEPROM_WORD_SIZE_BASE_SHIFT); 55913705f88SJack F Vogel } 56013705f88SJack F Vogel 56113705f88SJack F Vogel if (eec & IXGBE_EEC_ADDR_SIZE) 56213705f88SJack F Vogel eeprom->address_bits = 16; 56313705f88SJack F Vogel else 56413705f88SJack F Vogel eeprom->address_bits = 8; 56513705f88SJack F Vogel DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: " 56613705f88SJack F Vogel "%d\n", eeprom->type, eeprom->word_size, 56713705f88SJack F Vogel eeprom->address_bits); 56813705f88SJack F Vogel } 56913705f88SJack F Vogel 57013705f88SJack F Vogel return IXGBE_SUCCESS; 57113705f88SJack F Vogel } 57213705f88SJack F Vogel 57313705f88SJack F Vogel /** 57413705f88SJack F Vogel * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM 57513705f88SJack F Vogel * @hw: pointer to hardware structure 57613705f88SJack F Vogel * @offset: offset within the EEPROM to be written to 57713705f88SJack F Vogel * @data: 16 bit word to be written to the EEPROM 57813705f88SJack F Vogel * 57913705f88SJack F Vogel * If ixgbe_eeprom_update_checksum is not called after this function, the 58013705f88SJack F Vogel * EEPROM will most likely contain an invalid checksum. 58113705f88SJack F Vogel **/ 58213705f88SJack F Vogel s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) 58313705f88SJack F Vogel { 58413705f88SJack F Vogel s32 status; 58513705f88SJack F Vogel u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI; 58613705f88SJack F Vogel 5872969bf0eSJack F Vogel DEBUGFUNC("ixgbe_write_eeprom_generic"); 5882969bf0eSJack F Vogel 5899ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 5909ca4041bSJack F Vogel 5919ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 5929ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 5939ca4041bSJack F Vogel goto out; 5949ca4041bSJack F Vogel } 5959ca4041bSJack F Vogel 59613705f88SJack F Vogel /* Prepare the EEPROM for writing */ 59713705f88SJack F Vogel status = ixgbe_acquire_eeprom(hw); 59813705f88SJack F Vogel 59913705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 60013705f88SJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 60113705f88SJack F Vogel ixgbe_release_eeprom(hw); 60213705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 60313705f88SJack F Vogel } 60413705f88SJack F Vogel } 60513705f88SJack F Vogel 60613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 60713705f88SJack F Vogel ixgbe_standby_eeprom(hw); 60813705f88SJack F Vogel 60913705f88SJack F Vogel /* Send the WRITE ENABLE command (8 bit opcode ) */ 61013705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI, 61113705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 61213705f88SJack F Vogel 61313705f88SJack F Vogel ixgbe_standby_eeprom(hw); 61413705f88SJack F Vogel 61513705f88SJack F Vogel /* 61613705f88SJack F Vogel * Some SPI eeproms use the 8th address bit embedded in the 61713705f88SJack F Vogel * opcode 61813705f88SJack F Vogel */ 61913705f88SJack F Vogel if ((hw->eeprom.address_bits == 8) && (offset >= 128)) 62013705f88SJack F Vogel write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 62113705f88SJack F Vogel 62213705f88SJack F Vogel /* Send the Write command (8-bit opcode + addr) */ 62313705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, write_opcode, 62413705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 62513705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), 62613705f88SJack F Vogel hw->eeprom.address_bits); 62713705f88SJack F Vogel 62813705f88SJack F Vogel /* Send the data */ 62913705f88SJack F Vogel data = (data >> 8) | (data << 8); 63013705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, data, 16); 63113705f88SJack F Vogel ixgbe_standby_eeprom(hw); 63213705f88SJack F Vogel 63313705f88SJack F Vogel /* Done with writing - release the EEPROM */ 63413705f88SJack F Vogel ixgbe_release_eeprom(hw); 63513705f88SJack F Vogel } 63613705f88SJack F Vogel 6379ca4041bSJack F Vogel out: 63813705f88SJack F Vogel return status; 63913705f88SJack F Vogel } 64013705f88SJack F Vogel 64113705f88SJack F Vogel /** 64213705f88SJack F Vogel * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang 64313705f88SJack F Vogel * @hw: pointer to hardware structure 64413705f88SJack F Vogel * @offset: offset within the EEPROM to be read 64513705f88SJack F Vogel * @data: read 16 bit value from EEPROM 64613705f88SJack F Vogel * 64713705f88SJack F Vogel * Reads 16 bit value from EEPROM through bit-bang method 64813705f88SJack F Vogel **/ 64913705f88SJack F Vogel s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, 65013705f88SJack F Vogel u16 *data) 65113705f88SJack F Vogel { 65213705f88SJack F Vogel s32 status; 65313705f88SJack F Vogel u16 word_in; 65413705f88SJack F Vogel u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; 65513705f88SJack F Vogel 6562969bf0eSJack F Vogel DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic"); 6572969bf0eSJack F Vogel 6589ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 6599ca4041bSJack F Vogel 6609ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 6619ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 6629ca4041bSJack F Vogel goto out; 6639ca4041bSJack F Vogel } 6649ca4041bSJack F Vogel 66513705f88SJack F Vogel /* Prepare the EEPROM for reading */ 66613705f88SJack F Vogel status = ixgbe_acquire_eeprom(hw); 66713705f88SJack F Vogel 66813705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 66913705f88SJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 67013705f88SJack F Vogel ixgbe_release_eeprom(hw); 67113705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 67213705f88SJack F Vogel } 67313705f88SJack F Vogel } 67413705f88SJack F Vogel 67513705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 67613705f88SJack F Vogel ixgbe_standby_eeprom(hw); 67713705f88SJack F Vogel 67813705f88SJack F Vogel /* 67913705f88SJack F Vogel * Some SPI eeproms use the 8th address bit embedded in the 68013705f88SJack F Vogel * opcode 68113705f88SJack F Vogel */ 68213705f88SJack F Vogel if ((hw->eeprom.address_bits == 8) && (offset >= 128)) 68313705f88SJack F Vogel read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 68413705f88SJack F Vogel 68513705f88SJack F Vogel /* Send the READ command (opcode + addr) */ 68613705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, read_opcode, 68713705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 68813705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), 68913705f88SJack F Vogel hw->eeprom.address_bits); 69013705f88SJack F Vogel 69113705f88SJack F Vogel /* Read the data. */ 69213705f88SJack F Vogel word_in = ixgbe_shift_in_eeprom_bits(hw, 16); 69313705f88SJack F Vogel *data = (word_in >> 8) | (word_in << 8); 69413705f88SJack F Vogel 69513705f88SJack F Vogel /* End this read operation */ 69613705f88SJack F Vogel ixgbe_release_eeprom(hw); 69713705f88SJack F Vogel } 69813705f88SJack F Vogel 6999ca4041bSJack F Vogel out: 70013705f88SJack F Vogel return status; 70113705f88SJack F Vogel } 70213705f88SJack F Vogel 70313705f88SJack F Vogel /** 7042969bf0eSJack F Vogel * ixgbe_read_eerd_generic - Read EEPROM word using EERD 70513705f88SJack F Vogel * @hw: pointer to hardware structure 70613705f88SJack F Vogel * @offset: offset of word in the EEPROM to read 70713705f88SJack F Vogel * @data: word read from the EEPROM 70813705f88SJack F Vogel * 70913705f88SJack F Vogel * Reads a 16 bit word from the EEPROM using the EERD register. 71013705f88SJack F Vogel **/ 7112969bf0eSJack F Vogel s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) 71213705f88SJack F Vogel { 71313705f88SJack F Vogel u32 eerd; 71413705f88SJack F Vogel s32 status; 71513705f88SJack F Vogel 7162969bf0eSJack F Vogel DEBUGFUNC("ixgbe_read_eerd_generic"); 7172969bf0eSJack F Vogel 7189ca4041bSJack F Vogel hw->eeprom.ops.init_params(hw); 7199ca4041bSJack F Vogel 7209ca4041bSJack F Vogel if (offset >= hw->eeprom.word_size) { 7219ca4041bSJack F Vogel status = IXGBE_ERR_EEPROM; 7229ca4041bSJack F Vogel goto out; 7239ca4041bSJack F Vogel } 7249ca4041bSJack F Vogel 7252969bf0eSJack F Vogel eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) + 7262969bf0eSJack F Vogel IXGBE_EEPROM_RW_REG_START; 72713705f88SJack F Vogel 72813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); 7292969bf0eSJack F Vogel status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ); 73013705f88SJack F Vogel 73113705f88SJack F Vogel if (status == IXGBE_SUCCESS) 73213705f88SJack F Vogel *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >> 7332969bf0eSJack F Vogel IXGBE_EEPROM_RW_REG_DATA); 73413705f88SJack F Vogel else 73513705f88SJack F Vogel DEBUGOUT("Eeprom read timed out\n"); 73613705f88SJack F Vogel 7379ca4041bSJack F Vogel out: 73813705f88SJack F Vogel return status; 73913705f88SJack F Vogel } 74013705f88SJack F Vogel 74113705f88SJack F Vogel /** 7422969bf0eSJack F Vogel * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status 74313705f88SJack F Vogel * @hw: pointer to hardware structure 7442969bf0eSJack F Vogel * @ee_reg: EEPROM flag for polling 74513705f88SJack F Vogel * 7462969bf0eSJack F Vogel * Polls the status bit (bit 1) of the EERD or EEWR to determine when the 7472969bf0eSJack F Vogel * read or write is done respectively. 74813705f88SJack F Vogel **/ 7492969bf0eSJack F Vogel s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) 75013705f88SJack F Vogel { 75113705f88SJack F Vogel u32 i; 75213705f88SJack F Vogel u32 reg; 75313705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 75413705f88SJack F Vogel 7552969bf0eSJack F Vogel DEBUGFUNC("ixgbe_poll_eerd_eewr_done"); 7562969bf0eSJack F Vogel 7572969bf0eSJack F Vogel for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) { 7582969bf0eSJack F Vogel if (ee_reg == IXGBE_NVM_POLL_READ) 75913705f88SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_EERD); 7602969bf0eSJack F Vogel else 7612969bf0eSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_EEWR); 7622969bf0eSJack F Vogel 7632969bf0eSJack F Vogel if (reg & IXGBE_EEPROM_RW_REG_DONE) { 76413705f88SJack F Vogel status = IXGBE_SUCCESS; 76513705f88SJack F Vogel break; 76613705f88SJack F Vogel } 76713705f88SJack F Vogel usec_delay(5); 76813705f88SJack F Vogel } 76913705f88SJack F Vogel return status; 77013705f88SJack F Vogel } 77113705f88SJack F Vogel 77213705f88SJack F Vogel /** 77313705f88SJack F Vogel * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang 77413705f88SJack F Vogel * @hw: pointer to hardware structure 77513705f88SJack F Vogel * 77613705f88SJack F Vogel * Prepares EEPROM for access using bit-bang method. This function should 77713705f88SJack F Vogel * be called before issuing a command to the EEPROM. 77813705f88SJack F Vogel **/ 77913705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) 78013705f88SJack F Vogel { 78113705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 78213705f88SJack F Vogel u32 eec; 78313705f88SJack F Vogel u32 i; 78413705f88SJack F Vogel 7852969bf0eSJack F Vogel DEBUGFUNC("ixgbe_acquire_eeprom"); 7862969bf0eSJack F Vogel 78713705f88SJack F Vogel if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != IXGBE_SUCCESS) 78813705f88SJack F Vogel status = IXGBE_ERR_SWFW_SYNC; 78913705f88SJack F Vogel 79013705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 79113705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 79213705f88SJack F Vogel 79313705f88SJack F Vogel /* Request EEPROM Access */ 79413705f88SJack F Vogel eec |= IXGBE_EEC_REQ; 79513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 79613705f88SJack F Vogel 79713705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { 79813705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 79913705f88SJack F Vogel if (eec & IXGBE_EEC_GNT) 80013705f88SJack F Vogel break; 80113705f88SJack F Vogel usec_delay(5); 80213705f88SJack F Vogel } 80313705f88SJack F Vogel 8049ca4041bSJack F Vogel /* Release if grant not acquired */ 80513705f88SJack F Vogel if (!(eec & IXGBE_EEC_GNT)) { 80613705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 80713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 80813705f88SJack F Vogel DEBUGOUT("Could not acquire EEPROM grant\n"); 80913705f88SJack F Vogel 81013705f88SJack F Vogel ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 81113705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 81213705f88SJack F Vogel } 81313705f88SJack F Vogel } 81413705f88SJack F Vogel 81513705f88SJack F Vogel /* Setup EEPROM for Read/Write */ 81613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 81713705f88SJack F Vogel /* Clear CS and SK */ 81813705f88SJack F Vogel eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); 81913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 82013705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 82113705f88SJack F Vogel usec_delay(1); 82213705f88SJack F Vogel } 82313705f88SJack F Vogel return status; 82413705f88SJack F Vogel } 82513705f88SJack F Vogel 82613705f88SJack F Vogel /** 82713705f88SJack F Vogel * ixgbe_get_eeprom_semaphore - Get hardware semaphore 82813705f88SJack F Vogel * @hw: pointer to hardware structure 82913705f88SJack F Vogel * 83013705f88SJack F Vogel * Sets the hardware semaphores so EEPROM access can occur for bit-bang method 83113705f88SJack F Vogel **/ 83213705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) 83313705f88SJack F Vogel { 83413705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 835d8602bb9SJack F Vogel u32 timeout = 2000; 83613705f88SJack F Vogel u32 i; 83713705f88SJack F Vogel u32 swsm; 83813705f88SJack F Vogel 8392969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_eeprom_semaphore"); 8402969bf0eSJack F Vogel 84113705f88SJack F Vogel /* Get SMBI software semaphore between device drivers first */ 84213705f88SJack F Vogel for (i = 0; i < timeout; i++) { 84313705f88SJack F Vogel /* 84413705f88SJack F Vogel * If the SMBI bit is 0 when we read it, then the bit will be 84513705f88SJack F Vogel * set and we have the semaphore 84613705f88SJack F Vogel */ 84713705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 84813705f88SJack F Vogel if (!(swsm & IXGBE_SWSM_SMBI)) { 84913705f88SJack F Vogel status = IXGBE_SUCCESS; 85013705f88SJack F Vogel break; 85113705f88SJack F Vogel } 8520ac6dfecSJack F Vogel usec_delay(50); 85313705f88SJack F Vogel } 85413705f88SJack F Vogel 85513705f88SJack F Vogel /* Now get the semaphore between SW/FW through the SWESMBI bit */ 85613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 85713705f88SJack F Vogel for (i = 0; i < timeout; i++) { 85813705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 85913705f88SJack F Vogel 86013705f88SJack F Vogel /* Set the SW EEPROM semaphore bit to request access */ 86113705f88SJack F Vogel swsm |= IXGBE_SWSM_SWESMBI; 86213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 86313705f88SJack F Vogel 86413705f88SJack F Vogel /* 86513705f88SJack F Vogel * If we set the bit successfully then we got the 86613705f88SJack F Vogel * semaphore. 86713705f88SJack F Vogel */ 86813705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 86913705f88SJack F Vogel if (swsm & IXGBE_SWSM_SWESMBI) 87013705f88SJack F Vogel break; 87113705f88SJack F Vogel 87213705f88SJack F Vogel usec_delay(50); 87313705f88SJack F Vogel } 87413705f88SJack F Vogel 87513705f88SJack F Vogel /* 87613705f88SJack F Vogel * Release semaphores and return error if SW EEPROM semaphore 87713705f88SJack F Vogel * was not granted because we don't have access to the EEPROM 87813705f88SJack F Vogel */ 87913705f88SJack F Vogel if (i >= timeout) { 8800ac6dfecSJack F Vogel DEBUGOUT("SWESMBI Software EEPROM semaphore " 88113705f88SJack F Vogel "not granted.\n"); 88213705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 88313705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 88413705f88SJack F Vogel } 8850ac6dfecSJack F Vogel } else { 8860ac6dfecSJack F Vogel DEBUGOUT("Software semaphore SMBI between device drivers " 8870ac6dfecSJack F Vogel "not granted.\n"); 88813705f88SJack F Vogel } 88913705f88SJack F Vogel 89013705f88SJack F Vogel return status; 89113705f88SJack F Vogel } 89213705f88SJack F Vogel 89313705f88SJack F Vogel /** 89413705f88SJack F Vogel * ixgbe_release_eeprom_semaphore - Release hardware semaphore 89513705f88SJack F Vogel * @hw: pointer to hardware structure 89613705f88SJack F Vogel * 89713705f88SJack F Vogel * This function clears hardware semaphore bits. 89813705f88SJack F Vogel **/ 89913705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) 90013705f88SJack F Vogel { 90113705f88SJack F Vogel u32 swsm; 90213705f88SJack F Vogel 9032969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_eeprom_semaphore"); 9042969bf0eSJack F Vogel 90513705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 90613705f88SJack F Vogel 90713705f88SJack F Vogel /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ 90813705f88SJack F Vogel swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI); 90913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 9109ca4041bSJack F Vogel IXGBE_WRITE_FLUSH(hw); 91113705f88SJack F Vogel } 91213705f88SJack F Vogel 91313705f88SJack F Vogel /** 91413705f88SJack F Vogel * ixgbe_ready_eeprom - Polls for EEPROM ready 91513705f88SJack F Vogel * @hw: pointer to hardware structure 91613705f88SJack F Vogel **/ 91713705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) 91813705f88SJack F Vogel { 91913705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 92013705f88SJack F Vogel u16 i; 92113705f88SJack F Vogel u8 spi_stat_reg; 92213705f88SJack F Vogel 9232969bf0eSJack F Vogel DEBUGFUNC("ixgbe_ready_eeprom"); 9242969bf0eSJack F Vogel 92513705f88SJack F Vogel /* 92613705f88SJack F Vogel * Read "Status Register" repeatedly until the LSB is cleared. The 92713705f88SJack F Vogel * EEPROM will signal that the command has been completed by clearing 92813705f88SJack F Vogel * bit 0 of the internal status register. If it's not cleared within 92913705f88SJack F Vogel * 5 milliseconds, then error out. 93013705f88SJack F Vogel */ 93113705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) { 93213705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI, 93313705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 93413705f88SJack F Vogel spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8); 93513705f88SJack F Vogel if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI)) 93613705f88SJack F Vogel break; 93713705f88SJack F Vogel 93813705f88SJack F Vogel usec_delay(5); 93913705f88SJack F Vogel ixgbe_standby_eeprom(hw); 94013705f88SJack F Vogel }; 94113705f88SJack F Vogel 94213705f88SJack F Vogel /* 94313705f88SJack F Vogel * On some parts, SPI write time could vary from 0-20mSec on 3.3V 94413705f88SJack F Vogel * devices (and only 0-5mSec on 5V devices) 94513705f88SJack F Vogel */ 94613705f88SJack F Vogel if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { 94713705f88SJack F Vogel DEBUGOUT("SPI EEPROM Status error\n"); 94813705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 94913705f88SJack F Vogel } 95013705f88SJack F Vogel 95113705f88SJack F Vogel return status; 95213705f88SJack F Vogel } 95313705f88SJack F Vogel 95413705f88SJack F Vogel /** 95513705f88SJack F Vogel * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state 95613705f88SJack F Vogel * @hw: pointer to hardware structure 95713705f88SJack F Vogel **/ 95813705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw) 95913705f88SJack F Vogel { 96013705f88SJack F Vogel u32 eec; 96113705f88SJack F Vogel 9622969bf0eSJack F Vogel DEBUGFUNC("ixgbe_standby_eeprom"); 9632969bf0eSJack F Vogel 96413705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 96513705f88SJack F Vogel 96613705f88SJack F Vogel /* Toggle CS to flush commands */ 96713705f88SJack F Vogel eec |= IXGBE_EEC_CS; 96813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 96913705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 97013705f88SJack F Vogel usec_delay(1); 97113705f88SJack F Vogel eec &= ~IXGBE_EEC_CS; 97213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 97313705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 97413705f88SJack F Vogel usec_delay(1); 97513705f88SJack F Vogel } 97613705f88SJack F Vogel 97713705f88SJack F Vogel /** 97813705f88SJack F Vogel * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM. 97913705f88SJack F Vogel * @hw: pointer to hardware structure 98013705f88SJack F Vogel * @data: data to send to the EEPROM 98113705f88SJack F Vogel * @count: number of bits to shift out 98213705f88SJack F Vogel **/ 98313705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, 98413705f88SJack F Vogel u16 count) 98513705f88SJack F Vogel { 98613705f88SJack F Vogel u32 eec; 98713705f88SJack F Vogel u32 mask; 98813705f88SJack F Vogel u32 i; 98913705f88SJack F Vogel 9902969bf0eSJack F Vogel DEBUGFUNC("ixgbe_shift_out_eeprom_bits"); 9912969bf0eSJack F Vogel 99213705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 99313705f88SJack F Vogel 99413705f88SJack F Vogel /* 99513705f88SJack F Vogel * Mask is used to shift "count" bits of "data" out to the EEPROM 99613705f88SJack F Vogel * one bit at a time. Determine the starting bit based on count 99713705f88SJack F Vogel */ 99813705f88SJack F Vogel mask = 0x01 << (count - 1); 99913705f88SJack F Vogel 100013705f88SJack F Vogel for (i = 0; i < count; i++) { 100113705f88SJack F Vogel /* 100213705f88SJack F Vogel * A "1" is shifted out to the EEPROM by setting bit "DI" to a 100313705f88SJack F Vogel * "1", and then raising and then lowering the clock (the SK 100413705f88SJack F Vogel * bit controls the clock input to the EEPROM). A "0" is 100513705f88SJack F Vogel * shifted out to the EEPROM by setting "DI" to "0" and then 100613705f88SJack F Vogel * raising and then lowering the clock. 100713705f88SJack F Vogel */ 100813705f88SJack F Vogel if (data & mask) 100913705f88SJack F Vogel eec |= IXGBE_EEC_DI; 101013705f88SJack F Vogel else 101113705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 101213705f88SJack F Vogel 101313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 101413705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 101513705f88SJack F Vogel 101613705f88SJack F Vogel usec_delay(1); 101713705f88SJack F Vogel 101813705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 101913705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 102013705f88SJack F Vogel 102113705f88SJack F Vogel /* 102213705f88SJack F Vogel * Shift mask to signify next bit of data to shift in to the 102313705f88SJack F Vogel * EEPROM 102413705f88SJack F Vogel */ 102513705f88SJack F Vogel mask = mask >> 1; 102613705f88SJack F Vogel }; 102713705f88SJack F Vogel 102813705f88SJack F Vogel /* We leave the "DI" bit set to "0" when we leave this routine. */ 102913705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 103013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 103113705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 103213705f88SJack F Vogel } 103313705f88SJack F Vogel 103413705f88SJack F Vogel /** 103513705f88SJack F Vogel * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM 103613705f88SJack F Vogel * @hw: pointer to hardware structure 103713705f88SJack F Vogel **/ 103813705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) 103913705f88SJack F Vogel { 104013705f88SJack F Vogel u32 eec; 104113705f88SJack F Vogel u32 i; 104213705f88SJack F Vogel u16 data = 0; 104313705f88SJack F Vogel 10442969bf0eSJack F Vogel DEBUGFUNC("ixgbe_shift_in_eeprom_bits"); 10452969bf0eSJack F Vogel 104613705f88SJack F Vogel /* 104713705f88SJack F Vogel * In order to read a register from the EEPROM, we need to shift 104813705f88SJack F Vogel * 'count' bits in from the EEPROM. Bits are "shifted in" by raising 104913705f88SJack F Vogel * the clock input to the EEPROM (setting the SK bit), and then reading 105013705f88SJack F Vogel * the value of the "DO" bit. During this "shifting in" process the 105113705f88SJack F Vogel * "DI" bit should always be clear. 105213705f88SJack F Vogel */ 105313705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 105413705f88SJack F Vogel 105513705f88SJack F Vogel eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); 105613705f88SJack F Vogel 105713705f88SJack F Vogel for (i = 0; i < count; i++) { 105813705f88SJack F Vogel data = data << 1; 105913705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 106013705f88SJack F Vogel 106113705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 106213705f88SJack F Vogel 106313705f88SJack F Vogel eec &= ~(IXGBE_EEC_DI); 106413705f88SJack F Vogel if (eec & IXGBE_EEC_DO) 106513705f88SJack F Vogel data |= 1; 106613705f88SJack F Vogel 106713705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 106813705f88SJack F Vogel } 106913705f88SJack F Vogel 107013705f88SJack F Vogel return data; 107113705f88SJack F Vogel } 107213705f88SJack F Vogel 107313705f88SJack F Vogel /** 107413705f88SJack F Vogel * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input. 107513705f88SJack F Vogel * @hw: pointer to hardware structure 107613705f88SJack F Vogel * @eec: EEC register's current value 107713705f88SJack F Vogel **/ 107813705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 107913705f88SJack F Vogel { 10802969bf0eSJack F Vogel DEBUGFUNC("ixgbe_raise_eeprom_clk"); 10812969bf0eSJack F Vogel 108213705f88SJack F Vogel /* 108313705f88SJack F Vogel * Raise the clock input to the EEPROM 108413705f88SJack F Vogel * (setting the SK bit), then delay 108513705f88SJack F Vogel */ 108613705f88SJack F Vogel *eec = *eec | IXGBE_EEC_SK; 108713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 108813705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 108913705f88SJack F Vogel usec_delay(1); 109013705f88SJack F Vogel } 109113705f88SJack F Vogel 109213705f88SJack F Vogel /** 109313705f88SJack F Vogel * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input. 109413705f88SJack F Vogel * @hw: pointer to hardware structure 109513705f88SJack F Vogel * @eecd: EECD's current value 109613705f88SJack F Vogel **/ 109713705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 109813705f88SJack F Vogel { 10992969bf0eSJack F Vogel DEBUGFUNC("ixgbe_lower_eeprom_clk"); 11002969bf0eSJack F Vogel 110113705f88SJack F Vogel /* 110213705f88SJack F Vogel * Lower the clock input to the EEPROM (clearing the SK bit), then 110313705f88SJack F Vogel * delay 110413705f88SJack F Vogel */ 110513705f88SJack F Vogel *eec = *eec & ~IXGBE_EEC_SK; 110613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 110713705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 110813705f88SJack F Vogel usec_delay(1); 110913705f88SJack F Vogel } 111013705f88SJack F Vogel 111113705f88SJack F Vogel /** 111213705f88SJack F Vogel * ixgbe_release_eeprom - Release EEPROM, release semaphores 111313705f88SJack F Vogel * @hw: pointer to hardware structure 111413705f88SJack F Vogel **/ 111513705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw) 111613705f88SJack F Vogel { 111713705f88SJack F Vogel u32 eec; 111813705f88SJack F Vogel 11192969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_eeprom"); 11202969bf0eSJack F Vogel 112113705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 112213705f88SJack F Vogel 112313705f88SJack F Vogel eec |= IXGBE_EEC_CS; /* Pull CS high */ 112413705f88SJack F Vogel eec &= ~IXGBE_EEC_SK; /* Lower SCK */ 112513705f88SJack F Vogel 112613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 112713705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 112813705f88SJack F Vogel 112913705f88SJack F Vogel usec_delay(1); 113013705f88SJack F Vogel 113113705f88SJack F Vogel /* Stop requesting EEPROM access */ 113213705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 113313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 113413705f88SJack F Vogel 113513705f88SJack F Vogel ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 1136d8602bb9SJack F Vogel 1137d8602bb9SJack F Vogel /* Delay before attempt to obtain semaphore again to allow FW access */ 1138d8602bb9SJack F Vogel msec_delay(hw->eeprom.semaphore_delay); 113913705f88SJack F Vogel } 114013705f88SJack F Vogel 114113705f88SJack F Vogel /** 11422969bf0eSJack F Vogel * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum 114313705f88SJack F Vogel * @hw: pointer to hardware structure 114413705f88SJack F Vogel **/ 11452969bf0eSJack F Vogel u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) 114613705f88SJack F Vogel { 114713705f88SJack F Vogel u16 i; 114813705f88SJack F Vogel u16 j; 114913705f88SJack F Vogel u16 checksum = 0; 115013705f88SJack F Vogel u16 length = 0; 115113705f88SJack F Vogel u16 pointer = 0; 115213705f88SJack F Vogel u16 word = 0; 115313705f88SJack F Vogel 11542969bf0eSJack F Vogel DEBUGFUNC("ixgbe_calc_eeprom_checksum_generic"); 11552969bf0eSJack F Vogel 115613705f88SJack F Vogel /* Include 0x0-0x3F in the checksum */ 115713705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 11589ca4041bSJack F Vogel if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) { 115913705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 116013705f88SJack F Vogel break; 116113705f88SJack F Vogel } 116213705f88SJack F Vogel checksum += word; 116313705f88SJack F Vogel } 116413705f88SJack F Vogel 116513705f88SJack F Vogel /* Include all data from pointers except for the fw pointer */ 116613705f88SJack F Vogel for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 11679ca4041bSJack F Vogel hw->eeprom.ops.read(hw, i, &pointer); 116813705f88SJack F Vogel 116913705f88SJack F Vogel /* Make sure the pointer seems valid */ 117013705f88SJack F Vogel if (pointer != 0xFFFF && pointer != 0) { 11719ca4041bSJack F Vogel hw->eeprom.ops.read(hw, pointer, &length); 117213705f88SJack F Vogel 117313705f88SJack F Vogel if (length != 0xFFFF && length != 0) { 117413705f88SJack F Vogel for (j = pointer+1; j <= pointer+length; j++) { 11759ca4041bSJack F Vogel hw->eeprom.ops.read(hw, j, &word); 117613705f88SJack F Vogel checksum += word; 117713705f88SJack F Vogel } 117813705f88SJack F Vogel } 117913705f88SJack F Vogel } 118013705f88SJack F Vogel } 118113705f88SJack F Vogel 118213705f88SJack F Vogel checksum = (u16)IXGBE_EEPROM_SUM - checksum; 118313705f88SJack F Vogel 118413705f88SJack F Vogel return checksum; 118513705f88SJack F Vogel } 118613705f88SJack F Vogel 118713705f88SJack F Vogel /** 118813705f88SJack F Vogel * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum 118913705f88SJack F Vogel * @hw: pointer to hardware structure 119013705f88SJack F Vogel * @checksum_val: calculated checksum 119113705f88SJack F Vogel * 119213705f88SJack F Vogel * Performs checksum calculation and validates the EEPROM checksum. If the 119313705f88SJack F Vogel * caller does not need checksum_val, the value can be NULL. 119413705f88SJack F Vogel **/ 119513705f88SJack F Vogel s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, 119613705f88SJack F Vogel u16 *checksum_val) 119713705f88SJack F Vogel { 119813705f88SJack F Vogel s32 status; 119913705f88SJack F Vogel u16 checksum; 120013705f88SJack F Vogel u16 read_checksum = 0; 120113705f88SJack F Vogel 12022969bf0eSJack F Vogel DEBUGFUNC("ixgbe_validate_eeprom_checksum_generic"); 12032969bf0eSJack F Vogel 120413705f88SJack F Vogel /* 120513705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 120613705f88SJack F Vogel * not continue or we could be in for a very long wait while every 120713705f88SJack F Vogel * EEPROM read fails 120813705f88SJack F Vogel */ 12099ca4041bSJack F Vogel status = hw->eeprom.ops.read(hw, 0, &checksum); 121013705f88SJack F Vogel 121113705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 12122969bf0eSJack F Vogel checksum = hw->eeprom.ops.calc_checksum(hw); 121313705f88SJack F Vogel 12149ca4041bSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); 121513705f88SJack F Vogel 121613705f88SJack F Vogel /* 121713705f88SJack F Vogel * Verify read checksum from EEPROM is the same as 121813705f88SJack F Vogel * calculated checksum 121913705f88SJack F Vogel */ 12209ca4041bSJack F Vogel if (read_checksum != checksum) 122113705f88SJack F Vogel status = IXGBE_ERR_EEPROM_CHECKSUM; 122213705f88SJack F Vogel 122313705f88SJack F Vogel /* If the user cares, return the calculated checksum */ 12249ca4041bSJack F Vogel if (checksum_val) 122513705f88SJack F Vogel *checksum_val = checksum; 122613705f88SJack F Vogel } else { 122713705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 122813705f88SJack F Vogel } 122913705f88SJack F Vogel 123013705f88SJack F Vogel return status; 123113705f88SJack F Vogel } 123213705f88SJack F Vogel 123313705f88SJack F Vogel /** 12349ca4041bSJack F Vogel * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum 123513705f88SJack F Vogel * @hw: pointer to hardware structure 123613705f88SJack F Vogel **/ 123713705f88SJack F Vogel s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) 123813705f88SJack F Vogel { 123913705f88SJack F Vogel s32 status; 124013705f88SJack F Vogel u16 checksum; 124113705f88SJack F Vogel 12422969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_eeprom_checksum_generic"); 12432969bf0eSJack F Vogel 124413705f88SJack F Vogel /* 124513705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 124613705f88SJack F Vogel * not continue or we could be in for a very long wait while every 124713705f88SJack F Vogel * EEPROM read fails 124813705f88SJack F Vogel */ 12499ca4041bSJack F Vogel status = hw->eeprom.ops.read(hw, 0, &checksum); 125013705f88SJack F Vogel 125113705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 12522969bf0eSJack F Vogel checksum = hw->eeprom.ops.calc_checksum(hw); 12539ca4041bSJack F Vogel status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, 125413705f88SJack F Vogel checksum); 125513705f88SJack F Vogel } else { 125613705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 125713705f88SJack F Vogel } 125813705f88SJack F Vogel 125913705f88SJack F Vogel return status; 126013705f88SJack F Vogel } 126113705f88SJack F Vogel 126213705f88SJack F Vogel /** 126313705f88SJack F Vogel * ixgbe_validate_mac_addr - Validate MAC address 126413705f88SJack F Vogel * @mac_addr: pointer to MAC address. 126513705f88SJack F Vogel * 126613705f88SJack F Vogel * Tests a MAC address to ensure it is a valid Individual Address 126713705f88SJack F Vogel **/ 126813705f88SJack F Vogel s32 ixgbe_validate_mac_addr(u8 *mac_addr) 126913705f88SJack F Vogel { 127013705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 127113705f88SJack F Vogel 12722969bf0eSJack F Vogel DEBUGFUNC("ixgbe_validate_mac_addr"); 12732969bf0eSJack F Vogel 127413705f88SJack F Vogel /* Make sure it is not a multicast address */ 127513705f88SJack F Vogel if (IXGBE_IS_MULTICAST(mac_addr)) { 127613705f88SJack F Vogel DEBUGOUT("MAC address is multicast\n"); 127713705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 127813705f88SJack F Vogel /* Not a broadcast address */ 127913705f88SJack F Vogel } else if (IXGBE_IS_BROADCAST(mac_addr)) { 128013705f88SJack F Vogel DEBUGOUT("MAC address is broadcast\n"); 128113705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 128213705f88SJack F Vogel /* Reject the zero address */ 128313705f88SJack F Vogel } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && 128413705f88SJack F Vogel mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { 128513705f88SJack F Vogel DEBUGOUT("MAC address is all zeros\n"); 128613705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 128713705f88SJack F Vogel } 128813705f88SJack F Vogel return status; 128913705f88SJack F Vogel } 129013705f88SJack F Vogel 129113705f88SJack F Vogel /** 12929ca4041bSJack F Vogel * ixgbe_set_rar_generic - Set Rx address register 129313705f88SJack F Vogel * @hw: pointer to hardware structure 129413705f88SJack F Vogel * @index: Receive address register to write 12959ca4041bSJack F Vogel * @addr: Address to put into receive address register 12969ca4041bSJack F Vogel * @vmdq: VMDq "set" or "pool" index 129713705f88SJack F Vogel * @enable_addr: set flag that address is active 129813705f88SJack F Vogel * 129913705f88SJack F Vogel * Puts an ethernet address into a receive address register. 130013705f88SJack F Vogel **/ 13019ca4041bSJack F Vogel s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, 130213705f88SJack F Vogel u32 enable_addr) 130313705f88SJack F Vogel { 130413705f88SJack F Vogel u32 rar_low, rar_high; 13059ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 130613705f88SJack F Vogel 13072969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_rar_generic"); 13082969bf0eSJack F Vogel 13099ca4041bSJack F Vogel /* setup VMDq pool selection before this RAR gets enabled */ 13109ca4041bSJack F Vogel hw->mac.ops.set_vmdq(hw, index, vmdq); 13119ca4041bSJack F Vogel 13129ca4041bSJack F Vogel /* Make sure we are using a valid rar index range */ 13139ca4041bSJack F Vogel if (index < rar_entries) { 131413705f88SJack F Vogel /* 13159ca4041bSJack F Vogel * HW expects these in little endian so we reverse the byte 13169ca4041bSJack F Vogel * order from network order (big endian) to little endian 131713705f88SJack F Vogel */ 131813705f88SJack F Vogel rar_low = ((u32)addr[0] | 131913705f88SJack F Vogel ((u32)addr[1] << 8) | 132013705f88SJack F Vogel ((u32)addr[2] << 16) | 132113705f88SJack F Vogel ((u32)addr[3] << 24)); 13229ca4041bSJack F Vogel /* 13239ca4041bSJack F Vogel * Some parts put the VMDq setting in the extra RAH bits, 13249ca4041bSJack F Vogel * so save everything except the lower 16 bits that hold part 13259ca4041bSJack F Vogel * of the address and the address valid bit. 13269ca4041bSJack F Vogel */ 13279ca4041bSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 13289ca4041bSJack F Vogel rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); 13299ca4041bSJack F Vogel rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); 133013705f88SJack F Vogel 133113705f88SJack F Vogel if (enable_addr != 0) 133213705f88SJack F Vogel rar_high |= IXGBE_RAH_AV; 133313705f88SJack F Vogel 133413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); 133513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 13369ca4041bSJack F Vogel } else { 13375b7f4cedSJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", index); 13389ca4041bSJack F Vogel } 133913705f88SJack F Vogel 134013705f88SJack F Vogel return IXGBE_SUCCESS; 134113705f88SJack F Vogel } 134213705f88SJack F Vogel 134313705f88SJack F Vogel /** 13445b7f4cedSJack F Vogel * ixgbe_clear_rar_generic - Remove Rx address register 13455b7f4cedSJack F Vogel * @hw: pointer to hardware structure 13465b7f4cedSJack F Vogel * @index: Receive address register to write 13475b7f4cedSJack F Vogel * 13485b7f4cedSJack F Vogel * Clears an ethernet address from a receive address register. 13495b7f4cedSJack F Vogel **/ 13505b7f4cedSJack F Vogel s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) 13515b7f4cedSJack F Vogel { 13525b7f4cedSJack F Vogel u32 rar_high; 13535b7f4cedSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 13545b7f4cedSJack F Vogel 13552969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_rar_generic"); 13562969bf0eSJack F Vogel 13575b7f4cedSJack F Vogel /* Make sure we are using a valid rar index range */ 13585b7f4cedSJack F Vogel if (index < rar_entries) { 13595b7f4cedSJack F Vogel /* 13605b7f4cedSJack F Vogel * Some parts put the VMDq setting in the extra RAH bits, 13615b7f4cedSJack F Vogel * so save everything except the lower 16 bits that hold part 13625b7f4cedSJack F Vogel * of the address and the address valid bit. 13635b7f4cedSJack F Vogel */ 13645b7f4cedSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 13655b7f4cedSJack F Vogel rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); 13665b7f4cedSJack F Vogel 13675b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); 13685b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 13695b7f4cedSJack F Vogel } else { 13705b7f4cedSJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", index); 13715b7f4cedSJack F Vogel } 13725b7f4cedSJack F Vogel 13735b7f4cedSJack F Vogel /* clear VMDq pool/queue selection for this RAR */ 13745b7f4cedSJack F Vogel hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL); 13755b7f4cedSJack F Vogel 13765b7f4cedSJack F Vogel return IXGBE_SUCCESS; 13775b7f4cedSJack F Vogel } 13785b7f4cedSJack F Vogel 13795b7f4cedSJack F Vogel /** 138013705f88SJack F Vogel * ixgbe_init_rx_addrs_generic - Initializes receive address filters. 138113705f88SJack F Vogel * @hw: pointer to hardware structure 138213705f88SJack F Vogel * 138313705f88SJack F Vogel * Places the MAC address in receive address register 0 and clears the rest 13849ca4041bSJack F Vogel * of the receive address registers. Clears the multicast table. Assumes 138513705f88SJack F Vogel * the receiver is in reset when the routine is called. 138613705f88SJack F Vogel **/ 138713705f88SJack F Vogel s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) 138813705f88SJack F Vogel { 138913705f88SJack F Vogel u32 i; 13909ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 139113705f88SJack F Vogel 13922969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_rx_addrs_generic"); 13932969bf0eSJack F Vogel 139413705f88SJack F Vogel /* 139513705f88SJack F Vogel * If the current mac address is valid, assume it is a software override 139613705f88SJack F Vogel * to the permanent address. 139713705f88SJack F Vogel * Otherwise, use the permanent address from the eeprom. 139813705f88SJack F Vogel */ 139913705f88SJack F Vogel if (ixgbe_validate_mac_addr(hw->mac.addr) == 140013705f88SJack F Vogel IXGBE_ERR_INVALID_MAC_ADDR) { 140113705f88SJack F Vogel /* Get the MAC address from the RAR0 for later reference */ 14029ca4041bSJack F Vogel hw->mac.ops.get_mac_addr(hw, hw->mac.addr); 140313705f88SJack F Vogel 140413705f88SJack F Vogel DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ", 140513705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 140613705f88SJack F Vogel hw->mac.addr[2]); 140713705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 140813705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 140913705f88SJack F Vogel } else { 141013705f88SJack F Vogel /* Setup the receive address. */ 141113705f88SJack F Vogel DEBUGOUT("Overriding MAC Address in RAR[0]\n"); 141213705f88SJack F Vogel DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ", 141313705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 141413705f88SJack F Vogel hw->mac.addr[2]); 141513705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 141613705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 141713705f88SJack F Vogel 14189ca4041bSJack F Vogel hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); 141913705f88SJack F Vogel } 14209ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc = 0; 142113705f88SJack F Vogel 142213705f88SJack F Vogel hw->addr_ctrl.rar_used_count = 1; 142313705f88SJack F Vogel 142413705f88SJack F Vogel /* Zero out the other receive addresses. */ 14259ca4041bSJack F Vogel DEBUGOUT1("Clearing RAR[1-%d]\n", rar_entries - 1); 142613705f88SJack F Vogel for (i = 1; i < rar_entries; i++) { 142713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); 142813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); 142913705f88SJack F Vogel } 143013705f88SJack F Vogel 143113705f88SJack F Vogel /* Clear the MTA */ 143213705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 143313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 143413705f88SJack F Vogel 143513705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 14369ca4041bSJack F Vogel for (i = 0; i < hw->mac.mcft_size; i++) 143713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); 143813705f88SJack F Vogel 14395b7f4cedSJack F Vogel ixgbe_init_uta_tables(hw); 14405b7f4cedSJack F Vogel 144113705f88SJack F Vogel return IXGBE_SUCCESS; 144213705f88SJack F Vogel } 144313705f88SJack F Vogel 144413705f88SJack F Vogel /** 14459ca4041bSJack F Vogel * ixgbe_add_uc_addr - Adds a secondary unicast address. 14469ca4041bSJack F Vogel * @hw: pointer to hardware structure 14479ca4041bSJack F Vogel * @addr: new address 14489ca4041bSJack F Vogel * 14499ca4041bSJack F Vogel * Adds it to unused receive address register or goes into promiscuous mode. 14509ca4041bSJack F Vogel **/ 14519ca4041bSJack F Vogel void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) 14529ca4041bSJack F Vogel { 14539ca4041bSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 14549ca4041bSJack F Vogel u32 rar; 14559ca4041bSJack F Vogel 14562969bf0eSJack F Vogel DEBUGFUNC("ixgbe_add_uc_addr"); 14572969bf0eSJack F Vogel 14589ca4041bSJack F Vogel DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", 14599ca4041bSJack F Vogel addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 14609ca4041bSJack F Vogel 14619ca4041bSJack F Vogel /* 14629ca4041bSJack F Vogel * Place this address in the RAR if there is room, 14639ca4041bSJack F Vogel * else put the controller into promiscuous mode 14649ca4041bSJack F Vogel */ 14659ca4041bSJack F Vogel if (hw->addr_ctrl.rar_used_count < rar_entries) { 14660ac6dfecSJack F Vogel rar = hw->addr_ctrl.rar_used_count; 14679ca4041bSJack F Vogel hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 14689ca4041bSJack F Vogel DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar); 14699ca4041bSJack F Vogel hw->addr_ctrl.rar_used_count++; 14709ca4041bSJack F Vogel } else { 14719ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc++; 14729ca4041bSJack F Vogel } 14739ca4041bSJack F Vogel 14749ca4041bSJack F Vogel DEBUGOUT("ixgbe_add_uc_addr Complete\n"); 14759ca4041bSJack F Vogel } 14769ca4041bSJack F Vogel 14779ca4041bSJack F Vogel /** 14789ca4041bSJack F Vogel * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses 14799ca4041bSJack F Vogel * @hw: pointer to hardware structure 14809ca4041bSJack F Vogel * @addr_list: the list of new addresses 14819ca4041bSJack F Vogel * @addr_count: number of addresses 14829ca4041bSJack F Vogel * @next: iterator function to walk the address list 14839ca4041bSJack F Vogel * 14849ca4041bSJack F Vogel * The given list replaces any existing list. Clears the secondary addrs from 14859ca4041bSJack F Vogel * receive address registers. Uses unused receive address registers for the 14869ca4041bSJack F Vogel * first secondary addresses, and falls back to promiscuous mode as needed. 14879ca4041bSJack F Vogel * 14889ca4041bSJack F Vogel * Drivers using secondary unicast addresses must set user_set_promisc when 14899ca4041bSJack F Vogel * manually putting the device into promiscuous mode. 14909ca4041bSJack F Vogel **/ 14919ca4041bSJack F Vogel s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, 14929ca4041bSJack F Vogel u32 addr_count, ixgbe_mc_addr_itr next) 14939ca4041bSJack F Vogel { 14949ca4041bSJack F Vogel u8 *addr; 14959ca4041bSJack F Vogel u32 i; 14969ca4041bSJack F Vogel u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; 14979ca4041bSJack F Vogel u32 uc_addr_in_use; 14989ca4041bSJack F Vogel u32 fctrl; 14999ca4041bSJack F Vogel u32 vmdq; 15009ca4041bSJack F Vogel 15012969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_uc_addr_list_generic"); 15022969bf0eSJack F Vogel 15039ca4041bSJack F Vogel /* 15049ca4041bSJack F Vogel * Clear accounting of old secondary address list, 15059ca4041bSJack F Vogel * don't count RAR[0] 15069ca4041bSJack F Vogel */ 15070ac6dfecSJack F Vogel uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1; 15089ca4041bSJack F Vogel hw->addr_ctrl.rar_used_count -= uc_addr_in_use; 15099ca4041bSJack F Vogel hw->addr_ctrl.overflow_promisc = 0; 15109ca4041bSJack F Vogel 15119ca4041bSJack F Vogel /* Zero out the other receive addresses */ 15122969bf0eSJack F Vogel DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use+1); 15132969bf0eSJack F Vogel for (i = 0; i < uc_addr_in_use; i++) { 15142969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0); 15152969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0); 15169ca4041bSJack F Vogel } 15179ca4041bSJack F Vogel 15189ca4041bSJack F Vogel /* Add the new addresses */ 15199ca4041bSJack F Vogel for (i = 0; i < addr_count; i++) { 15209ca4041bSJack F Vogel DEBUGOUT(" Adding the secondary addresses:\n"); 15219ca4041bSJack F Vogel addr = next(hw, &addr_list, &vmdq); 15229ca4041bSJack F Vogel ixgbe_add_uc_addr(hw, addr, vmdq); 15239ca4041bSJack F Vogel } 15249ca4041bSJack F Vogel 15259ca4041bSJack F Vogel if (hw->addr_ctrl.overflow_promisc) { 15269ca4041bSJack F Vogel /* enable promisc if not already in overflow or set by user */ 15279ca4041bSJack F Vogel if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { 15289ca4041bSJack F Vogel DEBUGOUT(" Entering address overflow promisc mode\n"); 15299ca4041bSJack F Vogel fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 15309ca4041bSJack F Vogel fctrl |= IXGBE_FCTRL_UPE; 15319ca4041bSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 15329ca4041bSJack F Vogel } 15339ca4041bSJack F Vogel } else { 15349ca4041bSJack F Vogel /* only disable if set by overflow, not by user */ 15359ca4041bSJack F Vogel if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { 15369ca4041bSJack F Vogel DEBUGOUT(" Leaving address overflow promisc mode\n"); 15379ca4041bSJack F Vogel fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 15389ca4041bSJack F Vogel fctrl &= ~IXGBE_FCTRL_UPE; 15399ca4041bSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 15409ca4041bSJack F Vogel } 15419ca4041bSJack F Vogel } 15429ca4041bSJack F Vogel 15439ca4041bSJack F Vogel DEBUGOUT("ixgbe_update_uc_addr_list_generic Complete\n"); 15449ca4041bSJack F Vogel return IXGBE_SUCCESS; 15459ca4041bSJack F Vogel } 15469ca4041bSJack F Vogel 15479ca4041bSJack F Vogel /** 154813705f88SJack F Vogel * ixgbe_mta_vector - Determines bit-vector in multicast table to set 154913705f88SJack F Vogel * @hw: pointer to hardware structure 155013705f88SJack F Vogel * @mc_addr: the multicast address 155113705f88SJack F Vogel * 155213705f88SJack F Vogel * Extracts the 12 bits, from a multicast address, to determine which 155313705f88SJack F Vogel * bit-vector to set in the multicast table. The hardware uses 12 bits, from 155413705f88SJack F Vogel * incoming rx multicast addresses, to determine the bit-vector to check in 155513705f88SJack F Vogel * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set 15569ca4041bSJack F Vogel * by the MO field of the MCSTCTRL. The MO field is set during initialization 155713705f88SJack F Vogel * to mc_filter_type. 155813705f88SJack F Vogel **/ 155913705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) 156013705f88SJack F Vogel { 156113705f88SJack F Vogel u32 vector = 0; 156213705f88SJack F Vogel 15632969bf0eSJack F Vogel DEBUGFUNC("ixgbe_mta_vector"); 15642969bf0eSJack F Vogel 156513705f88SJack F Vogel switch (hw->mac.mc_filter_type) { 156613705f88SJack F Vogel case 0: /* use bits [47:36] of the address */ 156713705f88SJack F Vogel vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); 156813705f88SJack F Vogel break; 156913705f88SJack F Vogel case 1: /* use bits [46:35] of the address */ 157013705f88SJack F Vogel vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); 157113705f88SJack F Vogel break; 157213705f88SJack F Vogel case 2: /* use bits [45:34] of the address */ 157313705f88SJack F Vogel vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); 157413705f88SJack F Vogel break; 157513705f88SJack F Vogel case 3: /* use bits [43:32] of the address */ 157613705f88SJack F Vogel vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); 157713705f88SJack F Vogel break; 157813705f88SJack F Vogel default: /* Invalid mc_filter_type */ 157913705f88SJack F Vogel DEBUGOUT("MC filter type param set incorrectly\n"); 158013705f88SJack F Vogel ASSERT(0); 158113705f88SJack F Vogel break; 158213705f88SJack F Vogel } 158313705f88SJack F Vogel 158413705f88SJack F Vogel /* vector can only be 12-bits or boundary will be exceeded */ 158513705f88SJack F Vogel vector &= 0xFFF; 158613705f88SJack F Vogel return vector; 158713705f88SJack F Vogel } 158813705f88SJack F Vogel 158913705f88SJack F Vogel /** 159013705f88SJack F Vogel * ixgbe_set_mta - Set bit-vector in multicast table 159113705f88SJack F Vogel * @hw: pointer to hardware structure 159213705f88SJack F Vogel * @hash_value: Multicast address hash value 159313705f88SJack F Vogel * 159413705f88SJack F Vogel * Sets the bit-vector in the multicast table. 159513705f88SJack F Vogel **/ 159613705f88SJack F Vogel void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) 159713705f88SJack F Vogel { 159813705f88SJack F Vogel u32 vector; 159913705f88SJack F Vogel u32 vector_bit; 160013705f88SJack F Vogel u32 vector_reg; 160113705f88SJack F Vogel u32 mta_reg; 160213705f88SJack F Vogel 16032969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_mta"); 16042969bf0eSJack F Vogel 160513705f88SJack F Vogel hw->addr_ctrl.mta_in_use++; 160613705f88SJack F Vogel 160713705f88SJack F Vogel vector = ixgbe_mta_vector(hw, mc_addr); 160813705f88SJack F Vogel DEBUGOUT1(" bit-vector = 0x%03X\n", vector); 160913705f88SJack F Vogel 161013705f88SJack F Vogel /* 161113705f88SJack F Vogel * The MTA is a register array of 128 32-bit registers. It is treated 161213705f88SJack F Vogel * like an array of 4096 bits. We want to set bit 161313705f88SJack F Vogel * BitArray[vector_value]. So we figure out what register the bit is 161413705f88SJack F Vogel * in, read it, OR in the new bit, then write back the new value. The 161513705f88SJack F Vogel * register is determined by the upper 7 bits of the vector value and 161613705f88SJack F Vogel * the bit within that register are determined by the lower 5 bits of 161713705f88SJack F Vogel * the value. 161813705f88SJack F Vogel */ 161913705f88SJack F Vogel vector_reg = (vector >> 5) & 0x7F; 162013705f88SJack F Vogel vector_bit = vector & 0x1F; 162113705f88SJack F Vogel mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg)); 162213705f88SJack F Vogel mta_reg |= (1 << vector_bit); 162313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); 162413705f88SJack F Vogel } 162513705f88SJack F Vogel 162613705f88SJack F Vogel /** 162713705f88SJack F Vogel * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses 162813705f88SJack F Vogel * @hw: pointer to hardware structure 162913705f88SJack F Vogel * @mc_addr_list: the list of new multicast addresses 163013705f88SJack F Vogel * @mc_addr_count: number of addresses 16319ca4041bSJack F Vogel * @next: iterator function to walk the multicast address list 163213705f88SJack F Vogel * 163313705f88SJack F Vogel * The given list replaces any existing list. Clears the MC addrs from receive 16349ca4041bSJack F Vogel * address registers and the multicast table. Uses unused receive address 163513705f88SJack F Vogel * registers for the first multicast addresses, and hashes the rest into the 163613705f88SJack F Vogel * multicast table. 163713705f88SJack F Vogel **/ 163813705f88SJack F Vogel s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, 16399ca4041bSJack F Vogel u32 mc_addr_count, ixgbe_mc_addr_itr next) 164013705f88SJack F Vogel { 164113705f88SJack F Vogel u32 i; 16429ca4041bSJack F Vogel u32 vmdq; 164313705f88SJack F Vogel 16442969bf0eSJack F Vogel DEBUGFUNC("ixgbe_update_mc_addr_list_generic"); 16452969bf0eSJack F Vogel 164613705f88SJack F Vogel /* 164713705f88SJack F Vogel * Set the new number of MC addresses that we are being requested to 164813705f88SJack F Vogel * use. 164913705f88SJack F Vogel */ 165013705f88SJack F Vogel hw->addr_ctrl.num_mc_addrs = mc_addr_count; 165113705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 165213705f88SJack F Vogel 165313705f88SJack F Vogel /* Clear the MTA */ 165413705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 16559ca4041bSJack F Vogel for (i = 0; i < hw->mac.mcft_size; i++) 165613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); 165713705f88SJack F Vogel 165813705f88SJack F Vogel /* Add the new addresses */ 165913705f88SJack F Vogel for (i = 0; i < mc_addr_count; i++) { 166013705f88SJack F Vogel DEBUGOUT(" Adding the multicast addresses:\n"); 16610ac6dfecSJack F Vogel ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); 166213705f88SJack F Vogel } 166313705f88SJack F Vogel 166413705f88SJack F Vogel /* Enable mta */ 166513705f88SJack F Vogel if (hw->addr_ctrl.mta_in_use > 0) 166613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, 166713705f88SJack F Vogel IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); 166813705f88SJack F Vogel 166913705f88SJack F Vogel DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n"); 167013705f88SJack F Vogel return IXGBE_SUCCESS; 167113705f88SJack F Vogel } 167213705f88SJack F Vogel 167313705f88SJack F Vogel /** 167413705f88SJack F Vogel * ixgbe_enable_mc_generic - Enable multicast address in RAR 167513705f88SJack F Vogel * @hw: pointer to hardware structure 167613705f88SJack F Vogel * 167713705f88SJack F Vogel * Enables multicast address in RAR and the use of the multicast hash table. 167813705f88SJack F Vogel **/ 167913705f88SJack F Vogel s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) 168013705f88SJack F Vogel { 168113705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 168213705f88SJack F Vogel 16832969bf0eSJack F Vogel DEBUGFUNC("ixgbe_enable_mc_generic"); 16842969bf0eSJack F Vogel 168513705f88SJack F Vogel if (a->mta_in_use > 0) 168613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | 168713705f88SJack F Vogel hw->mac.mc_filter_type); 168813705f88SJack F Vogel 168913705f88SJack F Vogel return IXGBE_SUCCESS; 169013705f88SJack F Vogel } 169113705f88SJack F Vogel 169213705f88SJack F Vogel /** 16939ca4041bSJack F Vogel * ixgbe_disable_mc_generic - Disable multicast address in RAR 169413705f88SJack F Vogel * @hw: pointer to hardware structure 169513705f88SJack F Vogel * 169613705f88SJack F Vogel * Disables multicast address in RAR and the use of the multicast hash table. 169713705f88SJack F Vogel **/ 169813705f88SJack F Vogel s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) 169913705f88SJack F Vogel { 170013705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 170113705f88SJack F Vogel 17022969bf0eSJack F Vogel DEBUGFUNC("ixgbe_disable_mc_generic"); 17032969bf0eSJack F Vogel 170413705f88SJack F Vogel if (a->mta_in_use > 0) 170513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 170613705f88SJack F Vogel 170713705f88SJack F Vogel return IXGBE_SUCCESS; 170813705f88SJack F Vogel } 170913705f88SJack F Vogel 17101b6e0dbaSJack F Vogel /** 17110ac6dfecSJack F Vogel * ixgbe_fc_enable_generic - Enable flow control 17121b6e0dbaSJack F Vogel * @hw: pointer to hardware structure 17130ac6dfecSJack F Vogel * @packetbuf_num: packet buffer number (0-7) 17141b6e0dbaSJack F Vogel * 17150ac6dfecSJack F Vogel * Enable flow control according to the current settings. 17161b6e0dbaSJack F Vogel **/ 17170ac6dfecSJack F Vogel s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) 17181b6e0dbaSJack F Vogel { 17191b6e0dbaSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 17200ac6dfecSJack F Vogel u32 mflcn_reg, fccfg_reg; 17210ac6dfecSJack F Vogel u32 reg; 1722d8602bb9SJack F Vogel u32 rx_pba_size; 17231b6e0dbaSJack F Vogel 17240ac6dfecSJack F Vogel DEBUGFUNC("ixgbe_fc_enable_generic"); 17251b6e0dbaSJack F Vogel 17260ac6dfecSJack F Vogel /* Negotiate the fc mode to use */ 17270ac6dfecSJack F Vogel ret_val = ixgbe_fc_autoneg(hw); 17280ac6dfecSJack F Vogel if (ret_val) 17290ac6dfecSJack F Vogel goto out; 17300ac6dfecSJack F Vogel 17310ac6dfecSJack F Vogel /* Disable any previous flow control settings */ 17320ac6dfecSJack F Vogel mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); 17330ac6dfecSJack F Vogel mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE); 17340ac6dfecSJack F Vogel 17350ac6dfecSJack F Vogel fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); 17360ac6dfecSJack F Vogel fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); 17371b6e0dbaSJack F Vogel 17381b6e0dbaSJack F Vogel /* 17391b6e0dbaSJack F Vogel * The possible values of fc.current_mode are: 17401b6e0dbaSJack F Vogel * 0: Flow control is completely disabled 17411b6e0dbaSJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames, 17421b6e0dbaSJack F Vogel * but not send pause frames). 17431b6e0dbaSJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but 17441b6e0dbaSJack F Vogel * we do not support receiving pause frames). 17451b6e0dbaSJack F Vogel * 3: Both Rx and Tx flow control (symmetric) are enabled. 17461b6e0dbaSJack F Vogel * other: Invalid. 17471b6e0dbaSJack F Vogel */ 17481b6e0dbaSJack F Vogel switch (hw->fc.current_mode) { 17491b6e0dbaSJack F Vogel case ixgbe_fc_none: 17500ac6dfecSJack F Vogel /* Flow control is disabled by software override or autoneg. 17510ac6dfecSJack F Vogel * The code below will actually disable it in the HW. 17520ac6dfecSJack F Vogel */ 17531b6e0dbaSJack F Vogel break; 17541b6e0dbaSJack F Vogel case ixgbe_fc_rx_pause: 17551b6e0dbaSJack F Vogel /* 17561b6e0dbaSJack F Vogel * Rx Flow control is enabled and Tx Flow control is 17571b6e0dbaSJack F Vogel * disabled by software override. Since there really 17581b6e0dbaSJack F Vogel * isn't a way to advertise that we are capable of RX 17591b6e0dbaSJack F Vogel * Pause ONLY, we will advertise that we support both 17601b6e0dbaSJack F Vogel * symmetric and asymmetric Rx PAUSE. Later, we will 17611b6e0dbaSJack F Vogel * disable the adapter's ability to send PAUSE frames. 17621b6e0dbaSJack F Vogel */ 17630ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_RFCE; 17641b6e0dbaSJack F Vogel break; 17651b6e0dbaSJack F Vogel case ixgbe_fc_tx_pause: 17661b6e0dbaSJack F Vogel /* 17671b6e0dbaSJack F Vogel * Tx Flow control is enabled, and Rx Flow control is 17681b6e0dbaSJack F Vogel * disabled by software override. 17691b6e0dbaSJack F Vogel */ 17700ac6dfecSJack F Vogel fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; 17711b6e0dbaSJack F Vogel break; 17721b6e0dbaSJack F Vogel case ixgbe_fc_full: 17731b6e0dbaSJack F Vogel /* Flow control (both Rx and Tx) is enabled by SW override. */ 17740ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_RFCE; 17750ac6dfecSJack F Vogel fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; 17761b6e0dbaSJack F Vogel break; 17771b6e0dbaSJack F Vogel default: 17781b6e0dbaSJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 17792969bf0eSJack F Vogel ret_val = IXGBE_ERR_CONFIG; 17801b6e0dbaSJack F Vogel goto out; 17811b6e0dbaSJack F Vogel break; 17821b6e0dbaSJack F Vogel } 17831b6e0dbaSJack F Vogel 17840ac6dfecSJack F Vogel /* Set 802.3x based flow control settings. */ 17850ac6dfecSJack F Vogel mflcn_reg |= IXGBE_MFLCN_DPF; 17860ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); 17870ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); 17881b6e0dbaSJack F Vogel 1789d8602bb9SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_MTQC); 1790d8602bb9SJack F Vogel /* Thresholds are different for link flow control when in DCB mode */ 1791d8602bb9SJack F Vogel if (reg & IXGBE_MTQC_RT_ENA) { 1792d8602bb9SJack F Vogel rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); 1793d8602bb9SJack F Vogel 1794d8602bb9SJack F Vogel /* Always disable XON for LFC when in DCB mode */ 1795d8602bb9SJack F Vogel reg = (rx_pba_size >> 5) & 0xFFE0; 1796d8602bb9SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg); 1797d8602bb9SJack F Vogel 1798d8602bb9SJack F Vogel reg = (rx_pba_size >> 2) & 0xFFE0; 1799d8602bb9SJack F Vogel if (hw->fc.current_mode & ixgbe_fc_tx_pause) 1800d8602bb9SJack F Vogel reg |= IXGBE_FCRTH_FCEN; 1801d8602bb9SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg); 1802d8602bb9SJack F Vogel } else { 1803d8602bb9SJack F Vogel /* Set up and enable Rx high/low water mark thresholds, 1804d8602bb9SJack F Vogel * enable XON. */ 18050ac6dfecSJack F Vogel if (hw->fc.current_mode & ixgbe_fc_tx_pause) { 18060ac6dfecSJack F Vogel if (hw->fc.send_xon) { 1807d8602bb9SJack F Vogel IXGBE_WRITE_REG(hw, 1808d8602bb9SJack F Vogel IXGBE_FCRTL_82599(packetbuf_num), 1809d8602bb9SJack F Vogel (hw->fc.low_water | 1810d8602bb9SJack F Vogel IXGBE_FCRTL_XONE)); 18110ac6dfecSJack F Vogel } else { 1812d8602bb9SJack F Vogel IXGBE_WRITE_REG(hw, 1813d8602bb9SJack F Vogel IXGBE_FCRTL_82599(packetbuf_num), 18140ac6dfecSJack F Vogel hw->fc.low_water); 18151b6e0dbaSJack F Vogel } 18161b6e0dbaSJack F Vogel 18170ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), 18180ac6dfecSJack F Vogel (hw->fc.high_water | IXGBE_FCRTH_FCEN)); 18190ac6dfecSJack F Vogel } 1820d8602bb9SJack F Vogel } 18210ac6dfecSJack F Vogel 18220ac6dfecSJack F Vogel /* Configure pause time (2 TCs per register) */ 1823d8602bb9SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); 18240ac6dfecSJack F Vogel if ((packetbuf_num & 1) == 0) 18250ac6dfecSJack F Vogel reg = (reg & 0xFFFF0000) | hw->fc.pause_time; 18260ac6dfecSJack F Vogel else 18270ac6dfecSJack F Vogel reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16); 18280ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg); 18290ac6dfecSJack F Vogel 18300ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); 18310ac6dfecSJack F Vogel 18320ac6dfecSJack F Vogel out: 18330ac6dfecSJack F Vogel return ret_val; 18340ac6dfecSJack F Vogel } 18350ac6dfecSJack F Vogel 18360ac6dfecSJack F Vogel /** 18370ac6dfecSJack F Vogel * ixgbe_fc_autoneg - Configure flow control 18380ac6dfecSJack F Vogel * @hw: pointer to hardware structure 18390ac6dfecSJack F Vogel * 18400ac6dfecSJack F Vogel * Compares our advertised flow control capabilities to those advertised by 18410ac6dfecSJack F Vogel * our link partner, and determines the proper flow control mode to use. 18420ac6dfecSJack F Vogel **/ 18430ac6dfecSJack F Vogel s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) 18440ac6dfecSJack F Vogel { 18450ac6dfecSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 18460ac6dfecSJack F Vogel ixgbe_link_speed speed; 18470ac6dfecSJack F Vogel u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; 18482969bf0eSJack F Vogel u32 links2, anlp1_reg, autoc_reg, links; 18490ac6dfecSJack F Vogel bool link_up; 18500ac6dfecSJack F Vogel 18510ac6dfecSJack F Vogel DEBUGFUNC("ixgbe_fc_autoneg"); 18520ac6dfecSJack F Vogel 18530ac6dfecSJack F Vogel /* 18540ac6dfecSJack F Vogel * AN should have completed when the cable was plugged in. 18550ac6dfecSJack F Vogel * Look for reasons to bail out. Bail out if: 18560ac6dfecSJack F Vogel * - FC autoneg is disabled, or if 18572969bf0eSJack F Vogel * - link is not up. 18580ac6dfecSJack F Vogel * 18592969bf0eSJack F Vogel * Since we're being called from an LSC, link is already known to be up. 18600ac6dfecSJack F Vogel * So use link_up_wait_to_complete=FALSE. 18610ac6dfecSJack F Vogel */ 18620ac6dfecSJack F Vogel hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 18630ac6dfecSJack F Vogel 18642969bf0eSJack F Vogel if (hw->fc.disable_fc_autoneg || (!link_up)) { 18652969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 18662969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 18672969bf0eSJack F Vogel goto out; 18682969bf0eSJack F Vogel } 18692969bf0eSJack F Vogel 18702969bf0eSJack F Vogel /* 18712969bf0eSJack F Vogel * On backplane, bail out if 18722969bf0eSJack F Vogel * - backplane autoneg was not completed, or if 18732969bf0eSJack F Vogel * - we are 82599 and link partner is not AN enabled 18742969bf0eSJack F Vogel */ 18752969bf0eSJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) { 18762969bf0eSJack F Vogel links = IXGBE_READ_REG(hw, IXGBE_LINKS); 18772969bf0eSJack F Vogel if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { 18782969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 18792969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 18802969bf0eSJack F Vogel goto out; 18812969bf0eSJack F Vogel } 18822969bf0eSJack F Vogel 18832969bf0eSJack F Vogel if (hw->mac.type == ixgbe_mac_82599EB) { 18842969bf0eSJack F Vogel links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); 18852969bf0eSJack F Vogel if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { 18862969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 18872969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 18882969bf0eSJack F Vogel goto out; 18892969bf0eSJack F Vogel } 18902969bf0eSJack F Vogel } 18912969bf0eSJack F Vogel } 18922969bf0eSJack F Vogel 18932969bf0eSJack F Vogel /* 18942969bf0eSJack F Vogel * On multispeed fiber at 1g, bail out if 18952969bf0eSJack F Vogel * - link is up but AN did not complete, or if 18962969bf0eSJack F Vogel * - link is up and AN completed but timed out 18972969bf0eSJack F Vogel */ 18982969bf0eSJack F Vogel if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) { 18992969bf0eSJack F Vogel linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); 19002969bf0eSJack F Vogel if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || 19010ac6dfecSJack F Vogel ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { 19020ac6dfecSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 19030ac6dfecSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 19042969bf0eSJack F Vogel goto out; 19052969bf0eSJack F Vogel } 19062969bf0eSJack F Vogel } 19072969bf0eSJack F Vogel 19082969bf0eSJack F Vogel /* 19092969bf0eSJack F Vogel * Bail out on 19102969bf0eSJack F Vogel * - copper or CX4 adapters 19112969bf0eSJack F Vogel * - fiber adapters running at 10gig 19122969bf0eSJack F Vogel */ 19132969bf0eSJack F Vogel if ((hw->phy.media_type == ixgbe_media_type_copper) || 19142969bf0eSJack F Vogel (hw->phy.media_type == ixgbe_media_type_cx4) || 19152969bf0eSJack F Vogel ((hw->phy.media_type == ixgbe_media_type_fiber) && 19162969bf0eSJack F Vogel (speed == IXGBE_LINK_SPEED_10GB_FULL))) { 19172969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 19182969bf0eSJack F Vogel hw->fc.current_mode = hw->fc.requested_mode; 19191b6e0dbaSJack F Vogel goto out; 19201b6e0dbaSJack F Vogel } 19211b6e0dbaSJack F Vogel 19221b6e0dbaSJack F Vogel /* 19231b6e0dbaSJack F Vogel * Read the AN advertisement and LP ability registers and resolve 19241b6e0dbaSJack F Vogel * local flow control settings accordingly 19251b6e0dbaSJack F Vogel */ 19262969bf0eSJack F Vogel if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && 19272969bf0eSJack F Vogel (hw->phy.media_type != ixgbe_media_type_backplane)) { 19281b6e0dbaSJack F Vogel pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); 19291b6e0dbaSJack F Vogel pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); 19301b6e0dbaSJack F Vogel if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && 19311b6e0dbaSJack F Vogel (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) { 19321b6e0dbaSJack F Vogel /* 19331b6e0dbaSJack F Vogel * Now we need to check if the user selected Rx ONLY 19341b6e0dbaSJack F Vogel * of pause frames. In this case, we had to advertise 19351b6e0dbaSJack F Vogel * FULL flow control because we could not advertise RX 19361b6e0dbaSJack F Vogel * ONLY. Hence, we must now check to see if we need to 19371b6e0dbaSJack F Vogel * turn OFF the TRANSMISSION of PAUSE frames. 19381b6e0dbaSJack F Vogel */ 19391b6e0dbaSJack F Vogel if (hw->fc.requested_mode == ixgbe_fc_full) { 19401b6e0dbaSJack F Vogel hw->fc.current_mode = ixgbe_fc_full; 19411b6e0dbaSJack F Vogel DEBUGOUT("Flow Control = FULL.\n"); 19421b6e0dbaSJack F Vogel } else { 19431b6e0dbaSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 19442969bf0eSJack F Vogel DEBUGOUT("Flow Control=RX PAUSE frames only\n"); 19451b6e0dbaSJack F Vogel } 19461b6e0dbaSJack F Vogel } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && 19471b6e0dbaSJack F Vogel (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && 19481b6e0dbaSJack F Vogel (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && 19491b6e0dbaSJack F Vogel (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { 19501b6e0dbaSJack F Vogel hw->fc.current_mode = ixgbe_fc_tx_pause; 19511b6e0dbaSJack F Vogel DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); 19521b6e0dbaSJack F Vogel } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && 19531b6e0dbaSJack F Vogel (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && 19541b6e0dbaSJack F Vogel !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && 19551b6e0dbaSJack F Vogel (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { 19561b6e0dbaSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 19571b6e0dbaSJack F Vogel DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); 19581b6e0dbaSJack F Vogel } else { 19591b6e0dbaSJack F Vogel hw->fc.current_mode = ixgbe_fc_none; 19601b6e0dbaSJack F Vogel DEBUGOUT("Flow Control = NONE.\n"); 19611b6e0dbaSJack F Vogel } 19622969bf0eSJack F Vogel } 19631b6e0dbaSJack F Vogel 19642969bf0eSJack F Vogel if (hw->phy.media_type == ixgbe_media_type_backplane) { 19652969bf0eSJack F Vogel /* 19662969bf0eSJack F Vogel * Read the 10g AN autoc and LP ability registers and resolve 19672969bf0eSJack F Vogel * local flow control settings accordingly 19682969bf0eSJack F Vogel */ 19692969bf0eSJack F Vogel autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 19702969bf0eSJack F Vogel anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); 19712969bf0eSJack F Vogel 19722969bf0eSJack F Vogel if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && 19732969bf0eSJack F Vogel (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) { 19742969bf0eSJack F Vogel /* 19752969bf0eSJack F Vogel * Now we need to check if the user selected Rx ONLY 19762969bf0eSJack F Vogel * of pause frames. In this case, we had to advertise 19772969bf0eSJack F Vogel * FULL flow control because we could not advertise RX 19782969bf0eSJack F Vogel * ONLY. Hence, we must now check to see if we need to 19792969bf0eSJack F Vogel * turn OFF the TRANSMISSION of PAUSE frames. 19802969bf0eSJack F Vogel */ 19812969bf0eSJack F Vogel if (hw->fc.requested_mode == ixgbe_fc_full) { 19822969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_full; 19832969bf0eSJack F Vogel DEBUGOUT("Flow Control = FULL.\n"); 19842969bf0eSJack F Vogel } else { 19852969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 19862969bf0eSJack F Vogel DEBUGOUT("Flow Control=RX PAUSE frames only\n"); 19872969bf0eSJack F Vogel } 19882969bf0eSJack F Vogel } else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && 19892969bf0eSJack F Vogel (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && 19902969bf0eSJack F Vogel (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && 19912969bf0eSJack F Vogel (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { 19922969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_tx_pause; 19932969bf0eSJack F Vogel DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); 19942969bf0eSJack F Vogel } else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && 19952969bf0eSJack F Vogel (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && 19962969bf0eSJack F Vogel !(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && 19972969bf0eSJack F Vogel (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { 19982969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_rx_pause; 19992969bf0eSJack F Vogel DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); 20002969bf0eSJack F Vogel } else { 20012969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_none; 20022969bf0eSJack F Vogel DEBUGOUT("Flow Control = NONE.\n"); 20032969bf0eSJack F Vogel } 20042969bf0eSJack F Vogel } 20050ac6dfecSJack F Vogel /* Record that current_mode is the result of a successful autoneg */ 20060ac6dfecSJack F Vogel hw->fc.fc_was_autonegged = TRUE; 20070ac6dfecSJack F Vogel 20081b6e0dbaSJack F Vogel out: 20091b6e0dbaSJack F Vogel return ret_val; 20101b6e0dbaSJack F Vogel } 20111b6e0dbaSJack F Vogel 20120ac6dfecSJack F Vogel /** 20130ac6dfecSJack F Vogel * ixgbe_setup_fc - Set up flow control 20140ac6dfecSJack F Vogel * @hw: pointer to hardware structure 20150ac6dfecSJack F Vogel * 20160ac6dfecSJack F Vogel * Called at init time to set up flow control. 20170ac6dfecSJack F Vogel **/ 20180ac6dfecSJack F Vogel s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) 20190ac6dfecSJack F Vogel { 20200ac6dfecSJack F Vogel s32 ret_val = IXGBE_SUCCESS; 20210ac6dfecSJack F Vogel u32 reg; 20220ac6dfecSJack F Vogel 20232969bf0eSJack F Vogel DEBUGFUNC("ixgbe_setup_fc"); 20242969bf0eSJack F Vogel 20250ac6dfecSJack F Vogel 20260ac6dfecSJack F Vogel /* Validate the packetbuf configuration */ 20270ac6dfecSJack F Vogel if (packetbuf_num < 0 || packetbuf_num > 7) { 20280ac6dfecSJack F Vogel DEBUGOUT1("Invalid packet buffer number [%d], expected range is" 20290ac6dfecSJack F Vogel " 0-7\n", packetbuf_num); 20300ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 20310ac6dfecSJack F Vogel goto out; 20320ac6dfecSJack F Vogel } 20330ac6dfecSJack F Vogel 20340ac6dfecSJack F Vogel /* 20350ac6dfecSJack F Vogel * Validate the water mark configuration. Zero water marks are invalid 20360ac6dfecSJack F Vogel * because it causes the controller to just blast out fc packets. 20370ac6dfecSJack F Vogel */ 20380ac6dfecSJack F Vogel if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { 20390ac6dfecSJack F Vogel DEBUGOUT("Invalid water mark configuration\n"); 20400ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 20410ac6dfecSJack F Vogel goto out; 20420ac6dfecSJack F Vogel } 20430ac6dfecSJack F Vogel 20440ac6dfecSJack F Vogel /* 20450ac6dfecSJack F Vogel * Validate the requested mode. Strict IEEE mode does not allow 20460ac6dfecSJack F Vogel * ixgbe_fc_rx_pause because it will cause us to fail at UNH. 20470ac6dfecSJack F Vogel */ 20480ac6dfecSJack F Vogel if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { 20490ac6dfecSJack F Vogel DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); 20500ac6dfecSJack F Vogel ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; 20510ac6dfecSJack F Vogel goto out; 20520ac6dfecSJack F Vogel } 20530ac6dfecSJack F Vogel 20540ac6dfecSJack F Vogel /* 20550ac6dfecSJack F Vogel * 10gig parts do not have a word in the EEPROM to determine the 20560ac6dfecSJack F Vogel * default flow control setting, so we explicitly set it to full. 20570ac6dfecSJack F Vogel */ 20580ac6dfecSJack F Vogel if (hw->fc.requested_mode == ixgbe_fc_default) 20590ac6dfecSJack F Vogel hw->fc.requested_mode = ixgbe_fc_full; 20600ac6dfecSJack F Vogel 20610ac6dfecSJack F Vogel /* 20620ac6dfecSJack F Vogel * Set up the 1G flow control advertisement registers so the HW will be 20630ac6dfecSJack F Vogel * able to do fc autoneg once the cable is plugged in. If we end up 20640ac6dfecSJack F Vogel * using 10g instead, this is harmless. 20650ac6dfecSJack F Vogel */ 20660ac6dfecSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); 20670ac6dfecSJack F Vogel 20680ac6dfecSJack F Vogel /* 20690ac6dfecSJack F Vogel * The possible values of fc.requested_mode are: 20700ac6dfecSJack F Vogel * 0: Flow control is completely disabled 20710ac6dfecSJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames, 20720ac6dfecSJack F Vogel * but not send pause frames). 20730ac6dfecSJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but 20740ac6dfecSJack F Vogel * we do not support receiving pause frames). 20750ac6dfecSJack F Vogel * 3: Both Rx and Tx flow control (symmetric) are enabled. 20760ac6dfecSJack F Vogel * other: Invalid. 20770ac6dfecSJack F Vogel */ 20780ac6dfecSJack F Vogel switch (hw->fc.requested_mode) { 20790ac6dfecSJack F Vogel case ixgbe_fc_none: 20800ac6dfecSJack F Vogel /* Flow control completely disabled by software override. */ 20810ac6dfecSJack F Vogel reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 20820ac6dfecSJack F Vogel break; 20830ac6dfecSJack F Vogel case ixgbe_fc_rx_pause: 20840ac6dfecSJack F Vogel /* 20850ac6dfecSJack F Vogel * Rx Flow control is enabled and Tx Flow control is 20860ac6dfecSJack F Vogel * disabled by software override. Since there really 20870ac6dfecSJack F Vogel * isn't a way to advertise that we are capable of RX 20880ac6dfecSJack F Vogel * Pause ONLY, we will advertise that we support both 20890ac6dfecSJack F Vogel * symmetric and asymmetric Rx PAUSE. Later, we will 20900ac6dfecSJack F Vogel * disable the adapter's ability to send PAUSE frames. 20910ac6dfecSJack F Vogel */ 20920ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 20930ac6dfecSJack F Vogel break; 20940ac6dfecSJack F Vogel case ixgbe_fc_tx_pause: 20950ac6dfecSJack F Vogel /* 20960ac6dfecSJack F Vogel * Tx Flow control is enabled, and Rx Flow control is 20970ac6dfecSJack F Vogel * disabled by software override. 20980ac6dfecSJack F Vogel */ 20990ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_ASM_PAUSE); 21000ac6dfecSJack F Vogel reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); 21010ac6dfecSJack F Vogel break; 21020ac6dfecSJack F Vogel case ixgbe_fc_full: 21030ac6dfecSJack F Vogel /* Flow control (both Rx and Tx) is enabled by SW override. */ 21040ac6dfecSJack F Vogel reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); 21050ac6dfecSJack F Vogel break; 21060ac6dfecSJack F Vogel default: 21070ac6dfecSJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 21082969bf0eSJack F Vogel ret_val = IXGBE_ERR_CONFIG; 21090ac6dfecSJack F Vogel goto out; 21100ac6dfecSJack F Vogel break; 21110ac6dfecSJack F Vogel } 21120ac6dfecSJack F Vogel 21130ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); 21140ac6dfecSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); 21150ac6dfecSJack F Vogel 21160ac6dfecSJack F Vogel /* Disable AN timeout */ 21170ac6dfecSJack F Vogel if (hw->fc.strict_ieee) 21180ac6dfecSJack F Vogel reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; 21190ac6dfecSJack F Vogel 21200ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); 21210ac6dfecSJack F Vogel DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg); 21220ac6dfecSJack F Vogel 21232969bf0eSJack F Vogel /* 21242969bf0eSJack F Vogel * Set up the 10G flow control advertisement registers so the HW 21252969bf0eSJack F Vogel * can do fc autoneg once the cable is plugged in. If we end up 21262969bf0eSJack F Vogel * using 1g instead, this is harmless. 21272969bf0eSJack F Vogel */ 21282969bf0eSJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 21292969bf0eSJack F Vogel 21302969bf0eSJack F Vogel /* 21312969bf0eSJack F Vogel * The possible values of fc.requested_mode are: 21322969bf0eSJack F Vogel * 0: Flow control is completely disabled 21332969bf0eSJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames, 21342969bf0eSJack F Vogel * but not send pause frames). 21352969bf0eSJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but 21362969bf0eSJack F Vogel * we do not support receiving pause frames). 21372969bf0eSJack F Vogel * 3: Both Rx and Tx flow control (symmetric) are enabled. 21382969bf0eSJack F Vogel * other: Invalid. 21392969bf0eSJack F Vogel */ 21402969bf0eSJack F Vogel switch (hw->fc.requested_mode) { 21412969bf0eSJack F Vogel case ixgbe_fc_none: 21422969bf0eSJack F Vogel /* Flow control completely disabled by software override. */ 21432969bf0eSJack F Vogel reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); 21442969bf0eSJack F Vogel break; 21452969bf0eSJack F Vogel case ixgbe_fc_rx_pause: 21462969bf0eSJack F Vogel /* 21472969bf0eSJack F Vogel * Rx Flow control is enabled and Tx Flow control is 21482969bf0eSJack F Vogel * disabled by software override. Since there really 21492969bf0eSJack F Vogel * isn't a way to advertise that we are capable of RX 21502969bf0eSJack F Vogel * Pause ONLY, we will advertise that we support both 21512969bf0eSJack F Vogel * symmetric and asymmetric Rx PAUSE. Later, we will 21522969bf0eSJack F Vogel * disable the adapter's ability to send PAUSE frames. 21532969bf0eSJack F Vogel */ 21542969bf0eSJack F Vogel reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); 21552969bf0eSJack F Vogel break; 21562969bf0eSJack F Vogel case ixgbe_fc_tx_pause: 21572969bf0eSJack F Vogel /* 21582969bf0eSJack F Vogel * Tx Flow control is enabled, and Rx Flow control is 21592969bf0eSJack F Vogel * disabled by software override. 21602969bf0eSJack F Vogel */ 21612969bf0eSJack F Vogel reg |= (IXGBE_AUTOC_ASM_PAUSE); 21622969bf0eSJack F Vogel reg &= ~(IXGBE_AUTOC_SYM_PAUSE); 21632969bf0eSJack F Vogel break; 21642969bf0eSJack F Vogel case ixgbe_fc_full: 21652969bf0eSJack F Vogel /* Flow control (both Rx and Tx) is enabled by SW override. */ 21662969bf0eSJack F Vogel reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); 21672969bf0eSJack F Vogel break; 21682969bf0eSJack F Vogel default: 21692969bf0eSJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 21702969bf0eSJack F Vogel ret_val = IXGBE_ERR_CONFIG; 21712969bf0eSJack F Vogel goto out; 21722969bf0eSJack F Vogel break; 21732969bf0eSJack F Vogel } 21742969bf0eSJack F Vogel /* 21752969bf0eSJack F Vogel * AUTOC restart handles negotiation of 1G and 10G. There is 21762969bf0eSJack F Vogel * no need to set the PCS1GCTL register. 21772969bf0eSJack F Vogel */ 21782969bf0eSJack F Vogel reg |= IXGBE_AUTOC_AN_RESTART; 21792969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg); 21802969bf0eSJack F Vogel DEBUGOUT1("Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); 21812969bf0eSJack F Vogel 21820ac6dfecSJack F Vogel out: 21830ac6dfecSJack F Vogel return ret_val; 21840ac6dfecSJack F Vogel } 21851b6e0dbaSJack F Vogel 218613705f88SJack F Vogel /** 218713705f88SJack F Vogel * ixgbe_disable_pcie_master - Disable PCI-express master access 218813705f88SJack F Vogel * @hw: pointer to hardware structure 218913705f88SJack F Vogel * 219013705f88SJack F Vogel * Disables PCI-Express master access and verifies there are no pending 219113705f88SJack F Vogel * requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable 219213705f88SJack F Vogel * bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS 219313705f88SJack F Vogel * is returned signifying master requests disabled. 219413705f88SJack F Vogel **/ 219513705f88SJack F Vogel s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) 219613705f88SJack F Vogel { 21975b7f4cedSJack F Vogel u32 i; 21985b7f4cedSJack F Vogel u32 reg_val; 21995b7f4cedSJack F Vogel u32 number_of_queues; 2200c0014855SJack F Vogel s32 status = IXGBE_SUCCESS; 220113705f88SJack F Vogel 22022969bf0eSJack F Vogel DEBUGFUNC("ixgbe_disable_pcie_master"); 22032969bf0eSJack F Vogel 2204c0014855SJack F Vogel /* Just jump out if bus mastering is already disabled */ 2205c0014855SJack F Vogel if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) 2206c0014855SJack F Vogel goto out; 2207c0014855SJack F Vogel 22085b7f4cedSJack F Vogel /* Disable the receive unit by stopping each queue */ 22095b7f4cedSJack F Vogel number_of_queues = hw->mac.max_rx_queues; 22105b7f4cedSJack F Vogel for (i = 0; i < number_of_queues; i++) { 22115b7f4cedSJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); 22125b7f4cedSJack F Vogel if (reg_val & IXGBE_RXDCTL_ENABLE) { 22135b7f4cedSJack F Vogel reg_val &= ~IXGBE_RXDCTL_ENABLE; 22145b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val); 22155b7f4cedSJack F Vogel } 22165b7f4cedSJack F Vogel } 22175b7f4cedSJack F Vogel 22185b7f4cedSJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL); 22195b7f4cedSJack F Vogel reg_val |= IXGBE_CTRL_GIO_DIS; 22205b7f4cedSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val); 222113705f88SJack F Vogel 222213705f88SJack F Vogel for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 2223c0014855SJack F Vogel if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) 2224c0014855SJack F Vogel goto out; 222513705f88SJack F Vogel usec_delay(100); 222613705f88SJack F Vogel } 222713705f88SJack F Vogel 2228c0014855SJack F Vogel DEBUGOUT("GIO Master Disable bit didn't clear - requesting resets\n"); 2229c0014855SJack F Vogel status = IXGBE_ERR_MASTER_REQUESTS_PENDING; 2230c0014855SJack F Vogel 2231c0014855SJack F Vogel /* 2232c0014855SJack F Vogel * The GIO Master Disable bit didn't clear. There are multiple reasons 2233c0014855SJack F Vogel * for this listed in the datasheet 5.2.5.3.2 Master Disable, and they 2234c0014855SJack F Vogel * all require a double reset to recover from. Before proceeding, we 2235c0014855SJack F Vogel * first wait a little more to try to ensure that, at a minimum, the 2236c0014855SJack F Vogel * PCIe block has no transactions pending. 2237c0014855SJack F Vogel */ 2238c0014855SJack F Vogel for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 2239c0014855SJack F Vogel if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) & 2240c0014855SJack F Vogel IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) 2241c0014855SJack F Vogel break; 2242c0014855SJack F Vogel usec_delay(100); 2243c0014855SJack F Vogel } 2244c0014855SJack F Vogel 2245c0014855SJack F Vogel if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT) 2246c0014855SJack F Vogel DEBUGOUT("PCIe transaction pending bit also did not clear.\n"); 2247c0014855SJack F Vogel 2248c0014855SJack F Vogel /* 2249c0014855SJack F Vogel * Two consecutive resets are required via CTRL.RST per datasheet 2250c0014855SJack F Vogel * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine 2251c0014855SJack F Vogel * of this need. The first reset prevents new master requests from 2252c0014855SJack F Vogel * being issued by our device. We then must wait 1usec for any 2253c0014855SJack F Vogel * remaining completions from the PCIe bus to trickle in, and then reset 2254c0014855SJack F Vogel * again to clear out any effects they may have had on our device. 2255c0014855SJack F Vogel */ 2256c0014855SJack F Vogel hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; 2257c0014855SJack F Vogel 2258c0014855SJack F Vogel out: 225913705f88SJack F Vogel return status; 226013705f88SJack F Vogel } 226113705f88SJack F Vogel 226213705f88SJack F Vogel 226313705f88SJack F Vogel /** 22649ca4041bSJack F Vogel * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore 226513705f88SJack F Vogel * @hw: pointer to hardware structure 22669ca4041bSJack F Vogel * @mask: Mask to specify which semaphore to acquire 226713705f88SJack F Vogel * 22689ca4041bSJack F Vogel * Acquires the SWFW semaphore thought the GSSR register for the specified 226913705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 227013705f88SJack F Vogel **/ 227113705f88SJack F Vogel s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) 227213705f88SJack F Vogel { 227313705f88SJack F Vogel u32 gssr; 227413705f88SJack F Vogel u32 swmask = mask; 227513705f88SJack F Vogel u32 fwmask = mask << 5; 227613705f88SJack F Vogel s32 timeout = 200; 227713705f88SJack F Vogel 22782969bf0eSJack F Vogel DEBUGFUNC("ixgbe_acquire_swfw_sync"); 22792969bf0eSJack F Vogel 228013705f88SJack F Vogel while (timeout) { 22810ac6dfecSJack F Vogel /* 22820ac6dfecSJack F Vogel * SW EEPROM semaphore bit is used for access to all 22830ac6dfecSJack F Vogel * SW_FW_SYNC/GSSR bits (not just EEPROM) 22840ac6dfecSJack F Vogel */ 228513705f88SJack F Vogel if (ixgbe_get_eeprom_semaphore(hw)) 22862969bf0eSJack F Vogel return IXGBE_ERR_SWFW_SYNC; 228713705f88SJack F Vogel 228813705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 228913705f88SJack F Vogel if (!(gssr & (fwmask | swmask))) 229013705f88SJack F Vogel break; 229113705f88SJack F Vogel 229213705f88SJack F Vogel /* 229313705f88SJack F Vogel * Firmware currently using resource (fwmask) or other software 229413705f88SJack F Vogel * thread currently using resource (swmask) 229513705f88SJack F Vogel */ 229613705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 229713705f88SJack F Vogel msec_delay(5); 229813705f88SJack F Vogel timeout--; 229913705f88SJack F Vogel } 230013705f88SJack F Vogel 230113705f88SJack F Vogel if (!timeout) { 23020ac6dfecSJack F Vogel DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); 23032969bf0eSJack F Vogel return IXGBE_ERR_SWFW_SYNC; 230413705f88SJack F Vogel } 230513705f88SJack F Vogel 230613705f88SJack F Vogel gssr |= swmask; 230713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 230813705f88SJack F Vogel 230913705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 231013705f88SJack F Vogel return IXGBE_SUCCESS; 231113705f88SJack F Vogel } 231213705f88SJack F Vogel 231313705f88SJack F Vogel /** 231413705f88SJack F Vogel * ixgbe_release_swfw_sync - Release SWFW semaphore 231513705f88SJack F Vogel * @hw: pointer to hardware structure 23169ca4041bSJack F Vogel * @mask: Mask to specify which semaphore to release 231713705f88SJack F Vogel * 23189ca4041bSJack F Vogel * Releases the SWFW semaphore thought the GSSR register for the specified 231913705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 232013705f88SJack F Vogel **/ 232113705f88SJack F Vogel void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) 232213705f88SJack F Vogel { 232313705f88SJack F Vogel u32 gssr; 232413705f88SJack F Vogel u32 swmask = mask; 232513705f88SJack F Vogel 23262969bf0eSJack F Vogel DEBUGFUNC("ixgbe_release_swfw_sync"); 23272969bf0eSJack F Vogel 232813705f88SJack F Vogel ixgbe_get_eeprom_semaphore(hw); 232913705f88SJack F Vogel 233013705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 233113705f88SJack F Vogel gssr &= ~swmask; 233213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 233313705f88SJack F Vogel 233413705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 23350ac6dfecSJack F Vogel } 23360ac6dfecSJack F Vogel 23370ac6dfecSJack F Vogel /** 23380ac6dfecSJack F Vogel * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit 23390ac6dfecSJack F Vogel * @hw: pointer to hardware structure 23400ac6dfecSJack F Vogel * @regval: register value to write to RXCTRL 23410ac6dfecSJack F Vogel * 23420ac6dfecSJack F Vogel * Enables the Rx DMA unit 23430ac6dfecSJack F Vogel **/ 23440ac6dfecSJack F Vogel s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) 23450ac6dfecSJack F Vogel { 23462969bf0eSJack F Vogel DEBUGFUNC("ixgbe_enable_rx_dma_generic"); 23472969bf0eSJack F Vogel 23480ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); 23490ac6dfecSJack F Vogel 23500ac6dfecSJack F Vogel return IXGBE_SUCCESS; 23510ac6dfecSJack F Vogel } 23520ac6dfecSJack F Vogel 23530ac6dfecSJack F Vogel /** 23540ac6dfecSJack F Vogel * ixgbe_blink_led_start_generic - Blink LED based on index. 23550ac6dfecSJack F Vogel * @hw: pointer to hardware structure 23560ac6dfecSJack F Vogel * @index: led number to blink 23570ac6dfecSJack F Vogel **/ 23580ac6dfecSJack F Vogel s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) 23590ac6dfecSJack F Vogel { 23600ac6dfecSJack F Vogel ixgbe_link_speed speed = 0; 23610ac6dfecSJack F Vogel bool link_up = 0; 23620ac6dfecSJack F Vogel u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 23630ac6dfecSJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 23640ac6dfecSJack F Vogel 23652969bf0eSJack F Vogel DEBUGFUNC("ixgbe_blink_led_start_generic"); 23662969bf0eSJack F Vogel 23670ac6dfecSJack F Vogel /* 23680ac6dfecSJack F Vogel * Link must be up to auto-blink the LEDs; 23690ac6dfecSJack F Vogel * Force it if link is down. 23700ac6dfecSJack F Vogel */ 23710ac6dfecSJack F Vogel hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); 23720ac6dfecSJack F Vogel 23730ac6dfecSJack F Vogel if (!link_up) { 2374d8602bb9SJack F Vogel 2375d8602bb9SJack F Vogel autoc_reg |= IXGBE_AUTOC_AN_RESTART; 23760ac6dfecSJack F Vogel autoc_reg |= IXGBE_AUTOC_FLU; 23770ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 23780ac6dfecSJack F Vogel msec_delay(10); 23790ac6dfecSJack F Vogel } 23800ac6dfecSJack F Vogel 23810ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 23820ac6dfecSJack F Vogel led_reg |= IXGBE_LED_BLINK(index); 23830ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 23840ac6dfecSJack F Vogel IXGBE_WRITE_FLUSH(hw); 23850ac6dfecSJack F Vogel 23860ac6dfecSJack F Vogel return IXGBE_SUCCESS; 23870ac6dfecSJack F Vogel } 23880ac6dfecSJack F Vogel 23890ac6dfecSJack F Vogel /** 23900ac6dfecSJack F Vogel * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. 23910ac6dfecSJack F Vogel * @hw: pointer to hardware structure 23920ac6dfecSJack F Vogel * @index: led number to stop blinking 23930ac6dfecSJack F Vogel **/ 23940ac6dfecSJack F Vogel s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) 23950ac6dfecSJack F Vogel { 23960ac6dfecSJack F Vogel u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 23970ac6dfecSJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 23980ac6dfecSJack F Vogel 23992969bf0eSJack F Vogel DEBUGFUNC("ixgbe_blink_led_stop_generic"); 24002969bf0eSJack F Vogel 2401d8602bb9SJack F Vogel 24020ac6dfecSJack F Vogel autoc_reg &= ~IXGBE_AUTOC_FLU; 24030ac6dfecSJack F Vogel autoc_reg |= IXGBE_AUTOC_AN_RESTART; 24040ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 24050ac6dfecSJack F Vogel 24060ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 24070ac6dfecSJack F Vogel led_reg &= ~IXGBE_LED_BLINK(index); 24080ac6dfecSJack F Vogel led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 24090ac6dfecSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 24100ac6dfecSJack F Vogel IXGBE_WRITE_FLUSH(hw); 24110ac6dfecSJack F Vogel 24120ac6dfecSJack F Vogel return IXGBE_SUCCESS; 241313705f88SJack F Vogel } 241413705f88SJack F Vogel 24152969bf0eSJack F Vogel /** 24162969bf0eSJack F Vogel * ixgbe_get_san_mac_addr_offset - Get SAN MAC address offset from the EEPROM 24172969bf0eSJack F Vogel * @hw: pointer to hardware structure 24182969bf0eSJack F Vogel * @san_mac_offset: SAN MAC address offset 24192969bf0eSJack F Vogel * 24202969bf0eSJack F Vogel * This function will read the EEPROM location for the SAN MAC address 24212969bf0eSJack F Vogel * pointer, and returns the value at that location. This is used in both 24222969bf0eSJack F Vogel * get and set mac_addr routines. 24232969bf0eSJack F Vogel **/ 24242969bf0eSJack F Vogel static s32 ixgbe_get_san_mac_addr_offset(struct ixgbe_hw *hw, 24252969bf0eSJack F Vogel u16 *san_mac_offset) 24262969bf0eSJack F Vogel { 24272969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_san_mac_addr_offset"); 24282969bf0eSJack F Vogel 24292969bf0eSJack F Vogel /* 24302969bf0eSJack F Vogel * First read the EEPROM pointer to see if the MAC addresses are 24312969bf0eSJack F Vogel * available. 24322969bf0eSJack F Vogel */ 24332969bf0eSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset); 24342969bf0eSJack F Vogel 24352969bf0eSJack F Vogel return IXGBE_SUCCESS; 24362969bf0eSJack F Vogel } 24372969bf0eSJack F Vogel 24382969bf0eSJack F Vogel /** 24392969bf0eSJack F Vogel * ixgbe_get_san_mac_addr_generic - SAN MAC address retrieval from the EEPROM 24402969bf0eSJack F Vogel * @hw: pointer to hardware structure 24412969bf0eSJack F Vogel * @san_mac_addr: SAN MAC address 24422969bf0eSJack F Vogel * 24432969bf0eSJack F Vogel * Reads the SAN MAC address from the EEPROM, if it's available. This is 24442969bf0eSJack F Vogel * per-port, so set_lan_id() must be called before reading the addresses. 24452969bf0eSJack F Vogel * set_lan_id() is called by identify_sfp(), but this cannot be relied 24462969bf0eSJack F Vogel * upon for non-SFP connections, so we must call it here. 24472969bf0eSJack F Vogel **/ 24482969bf0eSJack F Vogel s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) 24492969bf0eSJack F Vogel { 24502969bf0eSJack F Vogel u16 san_mac_data, san_mac_offset; 24512969bf0eSJack F Vogel u8 i; 24522969bf0eSJack F Vogel 24532969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_san_mac_addr_generic"); 24542969bf0eSJack F Vogel 24552969bf0eSJack F Vogel /* 24562969bf0eSJack F Vogel * First read the EEPROM pointer to see if the MAC addresses are 24572969bf0eSJack F Vogel * available. If they're not, no point in calling set_lan_id() here. 24582969bf0eSJack F Vogel */ 24592969bf0eSJack F Vogel ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); 24602969bf0eSJack F Vogel 24612969bf0eSJack F Vogel if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { 24622969bf0eSJack F Vogel /* 24632969bf0eSJack F Vogel * No addresses available in this EEPROM. It's not an 24642969bf0eSJack F Vogel * error though, so just wipe the local address and return. 24652969bf0eSJack F Vogel */ 24662969bf0eSJack F Vogel for (i = 0; i < 6; i++) 24672969bf0eSJack F Vogel san_mac_addr[i] = 0xFF; 24682969bf0eSJack F Vogel 24692969bf0eSJack F Vogel goto san_mac_addr_out; 24702969bf0eSJack F Vogel } 24712969bf0eSJack F Vogel 24722969bf0eSJack F Vogel /* make sure we know which port we need to program */ 24732969bf0eSJack F Vogel hw->mac.ops.set_lan_id(hw); 24742969bf0eSJack F Vogel /* apply the port offset to the address offset */ 24752969bf0eSJack F Vogel (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : 24762969bf0eSJack F Vogel (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); 24772969bf0eSJack F Vogel for (i = 0; i < 3; i++) { 24782969bf0eSJack F Vogel hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data); 24792969bf0eSJack F Vogel san_mac_addr[i * 2] = (u8)(san_mac_data); 24802969bf0eSJack F Vogel san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8); 24812969bf0eSJack F Vogel san_mac_offset++; 24822969bf0eSJack F Vogel } 24832969bf0eSJack F Vogel 24842969bf0eSJack F Vogel san_mac_addr_out: 24852969bf0eSJack F Vogel return IXGBE_SUCCESS; 24862969bf0eSJack F Vogel } 24872969bf0eSJack F Vogel 24882969bf0eSJack F Vogel /** 24892969bf0eSJack F Vogel * ixgbe_set_san_mac_addr_generic - Write the SAN MAC address to the EEPROM 24902969bf0eSJack F Vogel * @hw: pointer to hardware structure 24912969bf0eSJack F Vogel * @san_mac_addr: SAN MAC address 24922969bf0eSJack F Vogel * 24932969bf0eSJack F Vogel * Write a SAN MAC address to the EEPROM. 24942969bf0eSJack F Vogel **/ 24952969bf0eSJack F Vogel s32 ixgbe_set_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) 24962969bf0eSJack F Vogel { 24972969bf0eSJack F Vogel s32 status = IXGBE_SUCCESS; 24982969bf0eSJack F Vogel u16 san_mac_data, san_mac_offset; 24992969bf0eSJack F Vogel u8 i; 25002969bf0eSJack F Vogel 25012969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_san_mac_addr_generic"); 25022969bf0eSJack F Vogel 25032969bf0eSJack F Vogel /* Look for SAN mac address pointer. If not defined, return */ 25042969bf0eSJack F Vogel ixgbe_get_san_mac_addr_offset(hw, &san_mac_offset); 25052969bf0eSJack F Vogel 25062969bf0eSJack F Vogel if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) { 25072969bf0eSJack F Vogel status = IXGBE_ERR_NO_SAN_ADDR_PTR; 25082969bf0eSJack F Vogel goto san_mac_addr_out; 25092969bf0eSJack F Vogel } 25102969bf0eSJack F Vogel 25112969bf0eSJack F Vogel /* Make sure we know which port we need to write */ 25122969bf0eSJack F Vogel hw->mac.ops.set_lan_id(hw); 25132969bf0eSJack F Vogel /* Apply the port offset to the address offset */ 25142969bf0eSJack F Vogel (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) : 25152969bf0eSJack F Vogel (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET); 25162969bf0eSJack F Vogel 25172969bf0eSJack F Vogel for (i = 0; i < 3; i++) { 25182969bf0eSJack F Vogel san_mac_data = (u16)((u16)(san_mac_addr[i * 2 + 1]) << 8); 25192969bf0eSJack F Vogel san_mac_data |= (u16)(san_mac_addr[i * 2]); 25202969bf0eSJack F Vogel hw->eeprom.ops.write(hw, san_mac_offset, san_mac_data); 25212969bf0eSJack F Vogel san_mac_offset++; 25222969bf0eSJack F Vogel } 25232969bf0eSJack F Vogel 25242969bf0eSJack F Vogel san_mac_addr_out: 25252969bf0eSJack F Vogel return status; 25262969bf0eSJack F Vogel } 25272969bf0eSJack F Vogel 25282969bf0eSJack F Vogel /** 25292969bf0eSJack F Vogel * ixgbe_get_pcie_msix_count_generic - Gets MSI-X vector count 25302969bf0eSJack F Vogel * @hw: pointer to hardware structure 25312969bf0eSJack F Vogel * 25322969bf0eSJack F Vogel * Read PCIe configuration space, and get the MSI-X vector count from 25332969bf0eSJack F Vogel * the capabilities table. 25342969bf0eSJack F Vogel **/ 25352969bf0eSJack F Vogel u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) 25362969bf0eSJack F Vogel { 25372969bf0eSJack F Vogel u32 msix_count = 64; 25382969bf0eSJack F Vogel 25392969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_pcie_msix_count_generic"); 25402969bf0eSJack F Vogel if (hw->mac.msix_vectors_from_pcie) { 25412969bf0eSJack F Vogel msix_count = IXGBE_READ_PCIE_WORD(hw, 25422969bf0eSJack F Vogel IXGBE_PCIE_MSIX_82599_CAPS); 25432969bf0eSJack F Vogel msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; 25442969bf0eSJack F Vogel 25452969bf0eSJack F Vogel /* MSI-X count is zero-based in HW, so increment to give 25462969bf0eSJack F Vogel * proper value */ 25472969bf0eSJack F Vogel msix_count++; 25482969bf0eSJack F Vogel } 25492969bf0eSJack F Vogel 25502969bf0eSJack F Vogel return msix_count; 25512969bf0eSJack F Vogel } 25522969bf0eSJack F Vogel 25532969bf0eSJack F Vogel /** 25542969bf0eSJack F Vogel * ixgbe_insert_mac_addr_generic - Find a RAR for this mac address 25552969bf0eSJack F Vogel * @hw: pointer to hardware structure 25562969bf0eSJack F Vogel * @addr: Address to put into receive address register 25572969bf0eSJack F Vogel * @vmdq: VMDq pool to assign 25582969bf0eSJack F Vogel * 25592969bf0eSJack F Vogel * Puts an ethernet address into a receive address register, or 25602969bf0eSJack F Vogel * finds the rar that it is aleady in; adds to the pool list 25612969bf0eSJack F Vogel **/ 25622969bf0eSJack F Vogel s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) 25632969bf0eSJack F Vogel { 25642969bf0eSJack F Vogel static const u32 NO_EMPTY_RAR_FOUND = 0xFFFFFFFF; 25652969bf0eSJack F Vogel u32 first_empty_rar = NO_EMPTY_RAR_FOUND; 25662969bf0eSJack F Vogel u32 rar; 25672969bf0eSJack F Vogel u32 rar_low, rar_high; 25682969bf0eSJack F Vogel u32 addr_low, addr_high; 25692969bf0eSJack F Vogel 25702969bf0eSJack F Vogel DEBUGFUNC("ixgbe_insert_mac_addr_generic"); 25712969bf0eSJack F Vogel 25722969bf0eSJack F Vogel /* swap bytes for HW little endian */ 25732969bf0eSJack F Vogel addr_low = addr[0] | (addr[1] << 8) 25742969bf0eSJack F Vogel | (addr[2] << 16) 25752969bf0eSJack F Vogel | (addr[3] << 24); 25762969bf0eSJack F Vogel addr_high = addr[4] | (addr[5] << 8); 25772969bf0eSJack F Vogel 25782969bf0eSJack F Vogel /* 25792969bf0eSJack F Vogel * Either find the mac_id in rar or find the first empty space. 25802969bf0eSJack F Vogel * rar_highwater points to just after the highest currently used 25812969bf0eSJack F Vogel * rar in order to shorten the search. It grows when we add a new 25822969bf0eSJack F Vogel * rar to the top. 25832969bf0eSJack F Vogel */ 25842969bf0eSJack F Vogel for (rar = 0; rar < hw->mac.rar_highwater; rar++) { 25852969bf0eSJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); 25862969bf0eSJack F Vogel 25872969bf0eSJack F Vogel if (((IXGBE_RAH_AV & rar_high) == 0) 25882969bf0eSJack F Vogel && first_empty_rar == NO_EMPTY_RAR_FOUND) { 25892969bf0eSJack F Vogel first_empty_rar = rar; 25902969bf0eSJack F Vogel } else if ((rar_high & 0xFFFF) == addr_high) { 25912969bf0eSJack F Vogel rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(rar)); 25922969bf0eSJack F Vogel if (rar_low == addr_low) 25932969bf0eSJack F Vogel break; /* found it already in the rars */ 25942969bf0eSJack F Vogel } 25952969bf0eSJack F Vogel } 25962969bf0eSJack F Vogel 25972969bf0eSJack F Vogel if (rar < hw->mac.rar_highwater) { 25982969bf0eSJack F Vogel /* already there so just add to the pool bits */ 25992969bf0eSJack F Vogel ixgbe_set_vmdq(hw, rar, vmdq); 26002969bf0eSJack F Vogel } else if (first_empty_rar != NO_EMPTY_RAR_FOUND) { 26012969bf0eSJack F Vogel /* stick it into first empty RAR slot we found */ 26022969bf0eSJack F Vogel rar = first_empty_rar; 26032969bf0eSJack F Vogel ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 26042969bf0eSJack F Vogel } else if (rar == hw->mac.rar_highwater) { 26052969bf0eSJack F Vogel /* add it to the top of the list and inc the highwater mark */ 26062969bf0eSJack F Vogel ixgbe_set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); 26072969bf0eSJack F Vogel hw->mac.rar_highwater++; 26082969bf0eSJack F Vogel } else if (rar >= hw->mac.num_rar_entries) { 26092969bf0eSJack F Vogel return IXGBE_ERR_INVALID_MAC_ADDR; 26102969bf0eSJack F Vogel } 26112969bf0eSJack F Vogel 26122969bf0eSJack F Vogel /* 26132969bf0eSJack F Vogel * If we found rar[0], make sure the default pool bit (we use pool 0) 26142969bf0eSJack F Vogel * remains cleared to be sure default pool packets will get delivered 26152969bf0eSJack F Vogel */ 26162969bf0eSJack F Vogel if (rar == 0) 26172969bf0eSJack F Vogel ixgbe_clear_vmdq(hw, rar, 0); 26182969bf0eSJack F Vogel 26192969bf0eSJack F Vogel return rar; 26202969bf0eSJack F Vogel } 26212969bf0eSJack F Vogel 26222969bf0eSJack F Vogel /** 26232969bf0eSJack F Vogel * ixgbe_clear_vmdq_generic - Disassociate a VMDq pool index from a rx address 26242969bf0eSJack F Vogel * @hw: pointer to hardware struct 26252969bf0eSJack F Vogel * @rar: receive address register index to disassociate 26262969bf0eSJack F Vogel * @vmdq: VMDq pool index to remove from the rar 26272969bf0eSJack F Vogel **/ 26282969bf0eSJack F Vogel s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) 26292969bf0eSJack F Vogel { 26302969bf0eSJack F Vogel u32 mpsar_lo, mpsar_hi; 26312969bf0eSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 26322969bf0eSJack F Vogel 26332969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_vmdq_generic"); 26342969bf0eSJack F Vogel 26352969bf0eSJack F Vogel if (rar < rar_entries) { 26362969bf0eSJack F Vogel mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); 26372969bf0eSJack F Vogel mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); 26382969bf0eSJack F Vogel 26392969bf0eSJack F Vogel if (!mpsar_lo && !mpsar_hi) 26402969bf0eSJack F Vogel goto done; 26412969bf0eSJack F Vogel 26422969bf0eSJack F Vogel if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { 26432969bf0eSJack F Vogel if (mpsar_lo) { 26442969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); 26452969bf0eSJack F Vogel mpsar_lo = 0; 26462969bf0eSJack F Vogel } 26472969bf0eSJack F Vogel if (mpsar_hi) { 26482969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); 26492969bf0eSJack F Vogel mpsar_hi = 0; 26502969bf0eSJack F Vogel } 26512969bf0eSJack F Vogel } else if (vmdq < 32) { 26522969bf0eSJack F Vogel mpsar_lo &= ~(1 << vmdq); 26532969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); 26542969bf0eSJack F Vogel } else { 26552969bf0eSJack F Vogel mpsar_hi &= ~(1 << (vmdq - 32)); 26562969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); 26572969bf0eSJack F Vogel } 26582969bf0eSJack F Vogel 26592969bf0eSJack F Vogel /* was that the last pool using this rar? */ 26602969bf0eSJack F Vogel if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) 26612969bf0eSJack F Vogel hw->mac.ops.clear_rar(hw, rar); 26622969bf0eSJack F Vogel } else { 26632969bf0eSJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", rar); 26642969bf0eSJack F Vogel } 26652969bf0eSJack F Vogel 26662969bf0eSJack F Vogel done: 26672969bf0eSJack F Vogel return IXGBE_SUCCESS; 26682969bf0eSJack F Vogel } 26692969bf0eSJack F Vogel 26702969bf0eSJack F Vogel /** 26712969bf0eSJack F Vogel * ixgbe_set_vmdq_generic - Associate a VMDq pool index with a rx address 26722969bf0eSJack F Vogel * @hw: pointer to hardware struct 26732969bf0eSJack F Vogel * @rar: receive address register index to associate with a VMDq index 26742969bf0eSJack F Vogel * @vmdq: VMDq pool index 26752969bf0eSJack F Vogel **/ 26762969bf0eSJack F Vogel s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) 26772969bf0eSJack F Vogel { 26782969bf0eSJack F Vogel u32 mpsar; 26792969bf0eSJack F Vogel u32 rar_entries = hw->mac.num_rar_entries; 26802969bf0eSJack F Vogel 26812969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_vmdq_generic"); 26822969bf0eSJack F Vogel 26832969bf0eSJack F Vogel if (rar < rar_entries) { 26842969bf0eSJack F Vogel if (vmdq < 32) { 26852969bf0eSJack F Vogel mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); 26862969bf0eSJack F Vogel mpsar |= 1 << vmdq; 26872969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); 26882969bf0eSJack F Vogel } else { 26892969bf0eSJack F Vogel mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); 26902969bf0eSJack F Vogel mpsar |= 1 << (vmdq - 32); 26912969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); 26922969bf0eSJack F Vogel } 26932969bf0eSJack F Vogel } else { 26942969bf0eSJack F Vogel DEBUGOUT1("RAR index %d is out of range.\n", rar); 26952969bf0eSJack F Vogel } 26962969bf0eSJack F Vogel return IXGBE_SUCCESS; 26972969bf0eSJack F Vogel } 26982969bf0eSJack F Vogel 26992969bf0eSJack F Vogel /** 27002969bf0eSJack F Vogel * ixgbe_init_uta_tables_generic - Initialize the Unicast Table Array 27012969bf0eSJack F Vogel * @hw: pointer to hardware structure 27022969bf0eSJack F Vogel **/ 27032969bf0eSJack F Vogel s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) 27042969bf0eSJack F Vogel { 27052969bf0eSJack F Vogel int i; 27062969bf0eSJack F Vogel 27072969bf0eSJack F Vogel DEBUGFUNC("ixgbe_init_uta_tables_generic"); 27082969bf0eSJack F Vogel DEBUGOUT(" Clearing UTA\n"); 27092969bf0eSJack F Vogel 27102969bf0eSJack F Vogel for (i = 0; i < 128; i++) 27112969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); 27122969bf0eSJack F Vogel 27132969bf0eSJack F Vogel return IXGBE_SUCCESS; 27142969bf0eSJack F Vogel } 27152969bf0eSJack F Vogel 27162969bf0eSJack F Vogel /** 27172969bf0eSJack F Vogel * ixgbe_find_vlvf_slot - find the vlanid or the first empty slot 27182969bf0eSJack F Vogel * @hw: pointer to hardware structure 27192969bf0eSJack F Vogel * @vlan: VLAN id to write to VLAN filter 27202969bf0eSJack F Vogel * 27212969bf0eSJack F Vogel * return the VLVF index where this VLAN id should be placed 27222969bf0eSJack F Vogel * 27232969bf0eSJack F Vogel **/ 27242969bf0eSJack F Vogel s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) 27252969bf0eSJack F Vogel { 27262969bf0eSJack F Vogel u32 bits = 0; 27272969bf0eSJack F Vogel u32 first_empty_slot = 0; 27282969bf0eSJack F Vogel s32 regindex; 27292969bf0eSJack F Vogel 2730c0014855SJack F Vogel /* short cut the special case */ 2731c0014855SJack F Vogel if (vlan == 0) 2732c0014855SJack F Vogel return 0; 2733c0014855SJack F Vogel 27342969bf0eSJack F Vogel /* 27352969bf0eSJack F Vogel * Search for the vlan id in the VLVF entries. Save off the first empty 27362969bf0eSJack F Vogel * slot found along the way 27372969bf0eSJack F Vogel */ 27382969bf0eSJack F Vogel for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) { 27392969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex)); 27402969bf0eSJack F Vogel if (!bits && !(first_empty_slot)) 27412969bf0eSJack F Vogel first_empty_slot = regindex; 27422969bf0eSJack F Vogel else if ((bits & 0x0FFF) == vlan) 27432969bf0eSJack F Vogel break; 27442969bf0eSJack F Vogel } 27452969bf0eSJack F Vogel 27462969bf0eSJack F Vogel /* 27472969bf0eSJack F Vogel * If regindex is less than IXGBE_VLVF_ENTRIES, then we found the vlan 27482969bf0eSJack F Vogel * in the VLVF. Else use the first empty VLVF register for this 27492969bf0eSJack F Vogel * vlan id. 27502969bf0eSJack F Vogel */ 27512969bf0eSJack F Vogel if (regindex >= IXGBE_VLVF_ENTRIES) { 27522969bf0eSJack F Vogel if (first_empty_slot) 27532969bf0eSJack F Vogel regindex = first_empty_slot; 27542969bf0eSJack F Vogel else { 27552969bf0eSJack F Vogel DEBUGOUT("No space in VLVF.\n"); 2756c0014855SJack F Vogel regindex = IXGBE_ERR_NO_SPACE; 27572969bf0eSJack F Vogel } 27582969bf0eSJack F Vogel } 27592969bf0eSJack F Vogel 27602969bf0eSJack F Vogel return regindex; 27612969bf0eSJack F Vogel } 27622969bf0eSJack F Vogel 27632969bf0eSJack F Vogel /** 27642969bf0eSJack F Vogel * ixgbe_set_vfta_generic - Set VLAN filter table 27652969bf0eSJack F Vogel * @hw: pointer to hardware structure 27662969bf0eSJack F Vogel * @vlan: VLAN id to write to VLAN filter 27672969bf0eSJack F Vogel * @vind: VMDq output index that maps queue to VLAN id in VFVFB 27682969bf0eSJack F Vogel * @vlan_on: boolean flag to turn on/off VLAN in VFVF 27692969bf0eSJack F Vogel * 27702969bf0eSJack F Vogel * Turn on/off specified VLAN in the VLAN filter table. 27712969bf0eSJack F Vogel **/ 27722969bf0eSJack F Vogel s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, 27732969bf0eSJack F Vogel bool vlan_on) 27742969bf0eSJack F Vogel { 27752969bf0eSJack F Vogel s32 regindex; 27762969bf0eSJack F Vogel u32 bitindex; 2777c0014855SJack F Vogel u32 vfta; 27782969bf0eSJack F Vogel u32 bits; 27792969bf0eSJack F Vogel u32 vt; 2780c0014855SJack F Vogel u32 targetbit; 2781c0014855SJack F Vogel bool vfta_changed = FALSE; 27822969bf0eSJack F Vogel 27832969bf0eSJack F Vogel DEBUGFUNC("ixgbe_set_vfta_generic"); 27842969bf0eSJack F Vogel 27852969bf0eSJack F Vogel if (vlan > 4095) 27862969bf0eSJack F Vogel return IXGBE_ERR_PARAM; 27872969bf0eSJack F Vogel 27882969bf0eSJack F Vogel /* 27892969bf0eSJack F Vogel * this is a 2 part operation - first the VFTA, then the 27902969bf0eSJack F Vogel * VLVF and VLVFB if VT Mode is set 2791c0014855SJack F Vogel * We don't write the VFTA until we know the VLVF part succeeded. 27922969bf0eSJack F Vogel */ 27932969bf0eSJack F Vogel 27942969bf0eSJack F Vogel /* Part 1 27952969bf0eSJack F Vogel * The VFTA is a bitstring made up of 128 32-bit registers 27962969bf0eSJack F Vogel * that enable the particular VLAN id, much like the MTA: 27972969bf0eSJack F Vogel * bits[11-5]: which register 27982969bf0eSJack F Vogel * bits[4-0]: which bit in the register 27992969bf0eSJack F Vogel */ 28002969bf0eSJack F Vogel regindex = (vlan >> 5) & 0x7F; 28012969bf0eSJack F Vogel bitindex = vlan & 0x1F; 2802c0014855SJack F Vogel targetbit = (1 << bitindex); 2803c0014855SJack F Vogel vfta = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); 28042969bf0eSJack F Vogel 2805c0014855SJack F Vogel if (vlan_on) { 2806c0014855SJack F Vogel if (!(vfta & targetbit)) { 2807c0014855SJack F Vogel vfta |= targetbit; 2808c0014855SJack F Vogel vfta_changed = TRUE; 2809c0014855SJack F Vogel } 2810c0014855SJack F Vogel } else { 2811c0014855SJack F Vogel if ((vfta & targetbit)) { 2812c0014855SJack F Vogel vfta &= ~targetbit; 2813c0014855SJack F Vogel vfta_changed = TRUE; 2814c0014855SJack F Vogel } 2815c0014855SJack F Vogel } 28162969bf0eSJack F Vogel 28172969bf0eSJack F Vogel /* Part 2 28182969bf0eSJack F Vogel * If VT Mode is set 28192969bf0eSJack F Vogel * Either vlan_on 28202969bf0eSJack F Vogel * make sure the vlan is in VLVF 28212969bf0eSJack F Vogel * set the vind bit in the matching VLVFB 28222969bf0eSJack F Vogel * Or !vlan_on 28232969bf0eSJack F Vogel * clear the pool bit and possibly the vind 28242969bf0eSJack F Vogel */ 28252969bf0eSJack F Vogel vt = IXGBE_READ_REG(hw, IXGBE_VT_CTL); 28262969bf0eSJack F Vogel if (vt & IXGBE_VT_CTL_VT_ENABLE) { 2827c0014855SJack F Vogel s32 vlvf_index; 2828c0014855SJack F Vogel 2829c0014855SJack F Vogel vlvf_index = ixgbe_find_vlvf_slot(hw, vlan); 2830c0014855SJack F Vogel if (vlvf_index < 0) 2831c0014855SJack F Vogel return vlvf_index; 28322969bf0eSJack F Vogel 28332969bf0eSJack F Vogel if (vlan_on) { 28342969bf0eSJack F Vogel /* set the pool bit */ 28352969bf0eSJack F Vogel if (vind < 32) { 28362969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 2837c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2)); 28382969bf0eSJack F Vogel bits |= (1 << vind); 28392969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 2840c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2), 28412969bf0eSJack F Vogel bits); 28422969bf0eSJack F Vogel } else { 28432969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 2844c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1)); 2845c0014855SJack F Vogel bits |= (1 << (vind-32)); 28462969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 2847c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1), 28482969bf0eSJack F Vogel bits); 28492969bf0eSJack F Vogel } 28502969bf0eSJack F Vogel } else { 28512969bf0eSJack F Vogel /* clear the pool bit */ 28522969bf0eSJack F Vogel if (vind < 32) { 28532969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 2854c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2)); 28552969bf0eSJack F Vogel bits &= ~(1 << vind); 28562969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 2857c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2), 28582969bf0eSJack F Vogel bits); 28592969bf0eSJack F Vogel bits |= IXGBE_READ_REG(hw, 2860c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1)); 28612969bf0eSJack F Vogel } else { 28622969bf0eSJack F Vogel bits = IXGBE_READ_REG(hw, 2863c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1)); 2864c0014855SJack F Vogel bits &= ~(1 << (vind-32)); 28652969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, 2866c0014855SJack F Vogel IXGBE_VLVFB((vlvf_index*2)+1), 28672969bf0eSJack F Vogel bits); 28682969bf0eSJack F Vogel bits |= IXGBE_READ_REG(hw, 2869c0014855SJack F Vogel IXGBE_VLVFB(vlvf_index*2)); 28702969bf0eSJack F Vogel } 28712969bf0eSJack F Vogel } 28722969bf0eSJack F Vogel 2873c0014855SJack F Vogel /* 2874c0014855SJack F Vogel * If there are still bits set in the VLVFB registers 2875c0014855SJack F Vogel * for the VLAN ID indicated we need to see if the 2876c0014855SJack F Vogel * caller is requesting that we clear the VFTA entry bit. 2877c0014855SJack F Vogel * If the caller has requested that we clear the VFTA 2878c0014855SJack F Vogel * entry bit but there are still pools/VFs using this VLAN 2879c0014855SJack F Vogel * ID entry then ignore the request. We're not worried 2880c0014855SJack F Vogel * about the case where we're turning the VFTA VLAN ID 2881c0014855SJack F Vogel * entry bit on, only when requested to turn it off as 2882c0014855SJack F Vogel * there may be multiple pools and/or VFs using the 2883c0014855SJack F Vogel * VLAN ID entry. In that case we cannot clear the 2884c0014855SJack F Vogel * VFTA bit until all pools/VFs using that VLAN ID have also 2885c0014855SJack F Vogel * been cleared. This will be indicated by "bits" being 2886c0014855SJack F Vogel * zero. 2887c0014855SJack F Vogel */ 2888c0014855SJack F Vogel if (bits) { 2889c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 28902969bf0eSJack F Vogel (IXGBE_VLVF_VIEN | vlan)); 2891c0014855SJack F Vogel if (!vlan_on) { 2892c0014855SJack F Vogel /* someone wants to clear the vfta entry 2893c0014855SJack F Vogel * but some pools/VFs are still using it. 2894c0014855SJack F Vogel * Ignore it. */ 2895c0014855SJack F Vogel vfta_changed = FALSE; 28962969bf0eSJack F Vogel } 2897c0014855SJack F Vogel } 2898c0014855SJack F Vogel else 2899c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(vlvf_index), 0); 2900c0014855SJack F Vogel } 2901c0014855SJack F Vogel 2902c0014855SJack F Vogel if (vfta_changed) 2903c0014855SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), vfta); 2904c0014855SJack F Vogel 29052969bf0eSJack F Vogel return IXGBE_SUCCESS; 29062969bf0eSJack F Vogel } 29072969bf0eSJack F Vogel 29082969bf0eSJack F Vogel /** 29092969bf0eSJack F Vogel * ixgbe_clear_vfta_generic - Clear VLAN filter table 29102969bf0eSJack F Vogel * @hw: pointer to hardware structure 29112969bf0eSJack F Vogel * 29122969bf0eSJack F Vogel * Clears the VLAN filer table, and the VMDq index associated with the filter 29132969bf0eSJack F Vogel **/ 29142969bf0eSJack F Vogel s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) 29152969bf0eSJack F Vogel { 29162969bf0eSJack F Vogel u32 offset; 29172969bf0eSJack F Vogel 29182969bf0eSJack F Vogel DEBUGFUNC("ixgbe_clear_vfta_generic"); 29192969bf0eSJack F Vogel 29202969bf0eSJack F Vogel for (offset = 0; offset < hw->mac.vft_size; offset++) 29212969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); 29222969bf0eSJack F Vogel 29232969bf0eSJack F Vogel for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { 29242969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); 29252969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset*2), 0); 29262969bf0eSJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset*2)+1), 0); 29272969bf0eSJack F Vogel } 29282969bf0eSJack F Vogel 29292969bf0eSJack F Vogel return IXGBE_SUCCESS; 29302969bf0eSJack F Vogel } 29312969bf0eSJack F Vogel 29322969bf0eSJack F Vogel /** 29332969bf0eSJack F Vogel * ixgbe_check_mac_link_generic - Determine link and speed status 29342969bf0eSJack F Vogel * @hw: pointer to hardware structure 29352969bf0eSJack F Vogel * @speed: pointer to link speed 29362969bf0eSJack F Vogel * @link_up: TRUE when link is up 29372969bf0eSJack F Vogel * @link_up_wait_to_complete: bool used to wait for link up or not 29382969bf0eSJack F Vogel * 29392969bf0eSJack F Vogel * Reads the links register to determine if link is up and the current speed 29402969bf0eSJack F Vogel **/ 29412969bf0eSJack F Vogel s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, 29422969bf0eSJack F Vogel bool *link_up, bool link_up_wait_to_complete) 29432969bf0eSJack F Vogel { 2944c0014855SJack F Vogel u32 links_reg, links_orig; 29452969bf0eSJack F Vogel u32 i; 29462969bf0eSJack F Vogel 29472969bf0eSJack F Vogel DEBUGFUNC("ixgbe_check_mac_link_generic"); 29482969bf0eSJack F Vogel 2949c0014855SJack F Vogel /* clear the old state */ 2950c0014855SJack F Vogel links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); 2951c0014855SJack F Vogel 29522969bf0eSJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); 2953c0014855SJack F Vogel 2954c0014855SJack F Vogel if (links_orig != links_reg) { 2955c0014855SJack F Vogel DEBUGOUT2("LINKS changed from %08X to %08X\n", 2956c0014855SJack F Vogel links_orig, links_reg); 2957c0014855SJack F Vogel } 2958c0014855SJack F Vogel 29592969bf0eSJack F Vogel if (link_up_wait_to_complete) { 29602969bf0eSJack F Vogel for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { 29612969bf0eSJack F Vogel if (links_reg & IXGBE_LINKS_UP) { 29622969bf0eSJack F Vogel *link_up = TRUE; 29632969bf0eSJack F Vogel break; 29642969bf0eSJack F Vogel } else { 29652969bf0eSJack F Vogel *link_up = FALSE; 29662969bf0eSJack F Vogel } 29672969bf0eSJack F Vogel msec_delay(100); 29682969bf0eSJack F Vogel links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); 29692969bf0eSJack F Vogel } 29702969bf0eSJack F Vogel } else { 29712969bf0eSJack F Vogel if (links_reg & IXGBE_LINKS_UP) 29722969bf0eSJack F Vogel *link_up = TRUE; 29732969bf0eSJack F Vogel else 29742969bf0eSJack F Vogel *link_up = FALSE; 29752969bf0eSJack F Vogel } 29762969bf0eSJack F Vogel 29772969bf0eSJack F Vogel if ((links_reg & IXGBE_LINKS_SPEED_82599) == 29782969bf0eSJack F Vogel IXGBE_LINKS_SPEED_10G_82599) 29792969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_10GB_FULL; 29802969bf0eSJack F Vogel else if ((links_reg & IXGBE_LINKS_SPEED_82599) == 29812969bf0eSJack F Vogel IXGBE_LINKS_SPEED_1G_82599) 29822969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_1GB_FULL; 29832969bf0eSJack F Vogel else 29842969bf0eSJack F Vogel *speed = IXGBE_LINK_SPEED_100_FULL; 29852969bf0eSJack F Vogel 29862969bf0eSJack F Vogel /* if link is down, zero out the current_mode */ 29872969bf0eSJack F Vogel if (*link_up == FALSE) { 29882969bf0eSJack F Vogel hw->fc.current_mode = ixgbe_fc_none; 29892969bf0eSJack F Vogel hw->fc.fc_was_autonegged = FALSE; 29902969bf0eSJack F Vogel } 29912969bf0eSJack F Vogel 29922969bf0eSJack F Vogel return IXGBE_SUCCESS; 29932969bf0eSJack F Vogel } 29942969bf0eSJack F Vogel 29952969bf0eSJack F Vogel /** 29962969bf0eSJack F Vogel * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from 29972969bf0eSJack F Vogel * the EEPROM 29982969bf0eSJack F Vogel * @hw: pointer to hardware structure 29992969bf0eSJack F Vogel * @wwnn_prefix: the alternative WWNN prefix 30002969bf0eSJack F Vogel * @wwpn_prefix: the alternative WWPN prefix 30012969bf0eSJack F Vogel * 30022969bf0eSJack F Vogel * This function will read the EEPROM from the alternative SAN MAC address 30032969bf0eSJack F Vogel * block to check the support for the alternative WWNN/WWPN prefix support. 30042969bf0eSJack F Vogel **/ 30052969bf0eSJack F Vogel s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, 30062969bf0eSJack F Vogel u16 *wwpn_prefix) 30072969bf0eSJack F Vogel { 30082969bf0eSJack F Vogel u16 offset, caps; 30092969bf0eSJack F Vogel u16 alt_san_mac_blk_offset; 30102969bf0eSJack F Vogel 30112969bf0eSJack F Vogel DEBUGFUNC("ixgbe_get_wwn_prefix_generic"); 30122969bf0eSJack F Vogel 30132969bf0eSJack F Vogel /* clear output first */ 30142969bf0eSJack F Vogel *wwnn_prefix = 0xFFFF; 30152969bf0eSJack F Vogel *wwpn_prefix = 0xFFFF; 30162969bf0eSJack F Vogel 30172969bf0eSJack F Vogel /* check if alternative SAN MAC is supported */ 30182969bf0eSJack F Vogel hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, 30192969bf0eSJack F Vogel &alt_san_mac_blk_offset); 30202969bf0eSJack F Vogel 30212969bf0eSJack F Vogel if ((alt_san_mac_blk_offset == 0) || 30222969bf0eSJack F Vogel (alt_san_mac_blk_offset == 0xFFFF)) 30232969bf0eSJack F Vogel goto wwn_prefix_out; 30242969bf0eSJack F Vogel 30252969bf0eSJack F Vogel /* check capability in alternative san mac address block */ 30262969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; 30272969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, &caps); 30282969bf0eSJack F Vogel if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) 30292969bf0eSJack F Vogel goto wwn_prefix_out; 30302969bf0eSJack F Vogel 30312969bf0eSJack F Vogel /* get the corresponding prefix for WWNN/WWPN */ 30322969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; 30332969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, wwnn_prefix); 30342969bf0eSJack F Vogel 30352969bf0eSJack F Vogel offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; 30362969bf0eSJack F Vogel hw->eeprom.ops.read(hw, offset, wwpn_prefix); 30372969bf0eSJack F Vogel 30382969bf0eSJack F Vogel wwn_prefix_out: 30392969bf0eSJack F Vogel return IXGBE_SUCCESS; 30402969bf0eSJack F Vogel } 3041