113705f88SJack F Vogel /******************************************************************************* 213705f88SJack F Vogel 313705f88SJack F Vogel Copyright (c) 2001-2007, 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 3213705f88SJack 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_poll_eeprom_eerd_done(struct ixgbe_hw *hw); 3913705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); 4013705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); 4113705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); 4213705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw); 4313705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw); 4413705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, 4513705f88SJack F Vogel u16 count); 4613705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); 4713705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); 4813705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); 4913705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw); 5013705f88SJack F Vogel static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw); 5113705f88SJack F Vogel 5213705f88SJack F Vogel static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); 5313705f88SJack F Vogel static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); 5413705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); 5513705f88SJack F Vogel void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr); 5613705f88SJack F Vogel 5713705f88SJack F Vogel /** 5813705f88SJack F Vogel * ixgbe_assign_func_pointers_generic - Set generic func ptrs 5913705f88SJack F Vogel * @hw: pointer to hardware structure 6013705f88SJack F Vogel * 6113705f88SJack F Vogel * Assigns generic function pointers. Adapter-specific functions can 6213705f88SJack F Vogel * override the assignment of generic function pointers by assigning 6313705f88SJack F Vogel * their own adapter-specific function pointers. 6413705f88SJack F Vogel **/ 6513705f88SJack F Vogel s32 ixgbe_assign_func_pointers_generic(struct ixgbe_hw *hw) 6613705f88SJack F Vogel { 6713705f88SJack F Vogel struct ixgbe_functions *f = &hw->func; 6813705f88SJack F Vogel 6913705f88SJack F Vogel f->ixgbe_func_init_hw = &ixgbe_init_hw_generic; 7013705f88SJack F Vogel f->ixgbe_func_start_hw = &ixgbe_start_hw_generic; 7113705f88SJack F Vogel f->ixgbe_func_clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic; 7213705f88SJack F Vogel f->ixgbe_func_get_mac_addr = &ixgbe_get_mac_addr_generic; 7313705f88SJack F Vogel f->ixgbe_func_stop_adapter = &ixgbe_stop_adapter_generic; 7413705f88SJack F Vogel f->ixgbe_func_get_bus_info = &ixgbe_get_bus_info_generic; 7513705f88SJack F Vogel /* LED */ 7613705f88SJack F Vogel f->ixgbe_func_led_on = &ixgbe_led_on_generic; 7713705f88SJack F Vogel f->ixgbe_func_led_off = &ixgbe_led_off_generic; 7813705f88SJack F Vogel /* EEPROM */ 7913705f88SJack F Vogel f->ixgbe_func_init_eeprom_params = &ixgbe_init_eeprom_params_generic; 8013705f88SJack F Vogel f->ixgbe_func_read_eeprom = &ixgbe_read_eeprom_bit_bang_generic; 8113705f88SJack F Vogel f->ixgbe_func_write_eeprom = &ixgbe_write_eeprom_generic; 8213705f88SJack F Vogel f->ixgbe_func_validate_eeprom_checksum = 8313705f88SJack F Vogel &ixgbe_validate_eeprom_checksum_generic; 8413705f88SJack F Vogel f->ixgbe_func_update_eeprom_checksum = 8513705f88SJack F Vogel &ixgbe_update_eeprom_checksum_generic; 8613705f88SJack F Vogel /* RAR, Multicast, VLAN */ 8713705f88SJack F Vogel f->ixgbe_func_set_rar = &ixgbe_set_rar_generic; 8813705f88SJack F Vogel f->ixgbe_func_init_rx_addrs = &ixgbe_init_rx_addrs_generic; 8913705f88SJack F Vogel f->ixgbe_func_update_mc_addr_list = &ixgbe_update_mc_addr_list_generic; 9013705f88SJack F Vogel f->ixgbe_func_enable_mc = &ixgbe_enable_mc_generic; 9113705f88SJack F Vogel f->ixgbe_func_disable_mc = &ixgbe_disable_mc_generic; 9213705f88SJack F Vogel f->ixgbe_func_clear_vfta = &ixgbe_clear_vfta_generic; 9313705f88SJack F Vogel f->ixgbe_func_set_vfta = &ixgbe_set_vfta_generic; 9413705f88SJack F Vogel f->ixgbe_func_setup_fc = &ixgbe_setup_fc_generic; 9513705f88SJack F Vogel 9613705f88SJack F Vogel return IXGBE_SUCCESS; 9713705f88SJack F Vogel } 9813705f88SJack F Vogel 9913705f88SJack F Vogel /** 10013705f88SJack F Vogel * ixgbe_start_hw_generic - Prepare hardware for TX/RX 10113705f88SJack F Vogel * @hw: pointer to hardware structure 10213705f88SJack F Vogel * 10313705f88SJack F Vogel * Starts the hardware by filling the bus info structure and media type, clears 10413705f88SJack F Vogel * all on chip counters, initializes receive address registers, multicast 10513705f88SJack F Vogel * table, VLAN filter table, calls routine to set up link and flow control 10613705f88SJack F Vogel * settings, and leaves transmit and receive units disabled and uninitialized 10713705f88SJack F Vogel **/ 10813705f88SJack F Vogel s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) 10913705f88SJack F Vogel { 11013705f88SJack F Vogel u32 ctrl_ext; 11113705f88SJack F Vogel 11213705f88SJack F Vogel /* Set the media type */ 11313705f88SJack F Vogel hw->phy.media_type = ixgbe_get_media_type(hw); 11413705f88SJack F Vogel 11513705f88SJack F Vogel /* Set bus info */ 11613705f88SJack F Vogel ixgbe_get_bus_info(hw); 11713705f88SJack F Vogel 11813705f88SJack F Vogel /* Identify the PHY */ 11913705f88SJack F Vogel ixgbe_identify_phy(hw); 12013705f88SJack F Vogel 12113705f88SJack F Vogel /* 12213705f88SJack F Vogel * Store MAC address from RAR0, clear receive address registers, and 12313705f88SJack F Vogel * clear the multicast table 12413705f88SJack F Vogel */ 12513705f88SJack F Vogel ixgbe_init_rx_addrs(hw); 12613705f88SJack F Vogel 12713705f88SJack F Vogel /* Clear the VLAN filter table */ 12813705f88SJack F Vogel ixgbe_clear_vfta(hw); 12913705f88SJack F Vogel 13013705f88SJack F Vogel /* Set up link */ 13113705f88SJack F Vogel ixgbe_setup_link(hw); 13213705f88SJack F Vogel 13313705f88SJack F Vogel /* Clear statistics registers */ 13413705f88SJack F Vogel ixgbe_clear_hw_cntrs(hw); 13513705f88SJack F Vogel 13613705f88SJack F Vogel /* Set up flow control */ 13713705f88SJack F Vogel ixgbe_setup_fc(hw, 0); 13813705f88SJack F Vogel 13913705f88SJack F Vogel /* Set No Snoop Disable */ 14013705f88SJack F Vogel ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); 14113705f88SJack F Vogel ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; 14213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); 14313705f88SJack F Vogel 14413705f88SJack F Vogel /* Clear adapter stopped flag */ 14513705f88SJack F Vogel hw->adapter_stopped = FALSE; 14613705f88SJack F Vogel 14713705f88SJack F Vogel return IXGBE_SUCCESS; 14813705f88SJack F Vogel } 14913705f88SJack F Vogel 15013705f88SJack F Vogel /** 15113705f88SJack F Vogel * ixgbe_init_hw_generic - Generic hardware initialization 15213705f88SJack F Vogel * @hw: pointer to hardware structure 15313705f88SJack F Vogel * 15413705f88SJack F Vogel * Initialize the hardware by reseting the hardware, filling the bus info 15513705f88SJack F Vogel * structure and media type, clears all on chip counters, initializes receive 15613705f88SJack F Vogel * address registers, multicast table, VLAN filter table, calls routine to set 15713705f88SJack F Vogel * up link and flow control settings, and leaves transmit and receive units 15813705f88SJack F Vogel * disabled and uninitialized 15913705f88SJack F Vogel **/ 16013705f88SJack F Vogel s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) 16113705f88SJack F Vogel { 16213705f88SJack F Vogel /* Reset the hardware */ 16313705f88SJack F Vogel ixgbe_reset_hw(hw); 16413705f88SJack F Vogel 16513705f88SJack F Vogel /* Start the HW */ 16613705f88SJack F Vogel ixgbe_start_hw(hw); 16713705f88SJack F Vogel 16813705f88SJack F Vogel return IXGBE_SUCCESS; 16913705f88SJack F Vogel } 17013705f88SJack F Vogel 17113705f88SJack F Vogel /** 17213705f88SJack F Vogel * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters 17313705f88SJack F Vogel * @hw: pointer to hardware structure 17413705f88SJack F Vogel * 17513705f88SJack F Vogel * Clears all hardware statistics counters by reading them from the hardware 17613705f88SJack F Vogel * Statistics counters are clear on read. 17713705f88SJack F Vogel **/ 17813705f88SJack F Vogel s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) 17913705f88SJack F Vogel { 18013705f88SJack F Vogel u16 i = 0; 18113705f88SJack F Vogel 18213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_CRCERRS); 18313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ILLERRC); 18413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ERRBC); 18513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MSPDC); 18613705f88SJack F Vogel for (i = 0; i < 8; i++) 18713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPC(i)); 18813705f88SJack F Vogel 18913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MLFC); 19013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MRFC); 19113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RLEC); 19213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONTXC); 19313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXONRXC); 19413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); 19513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); 19613705f88SJack F Vogel 19713705f88SJack F Vogel for (i = 0; i < 8; i++) { 19813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); 19913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); 20013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); 20113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); 20213705f88SJack F Vogel } 20313705f88SJack F Vogel 20413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC64); 20513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC127); 20613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC255); 20713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC511); 20813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1023); 20913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PRC1522); 21013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPRC); 21113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPRC); 21213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPRC); 21313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GPTC); 21413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCL); 21513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GORCH); 21613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCL); 21713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_GOTCH); 21813705f88SJack F Vogel for (i = 0; i < 8; i++) 21913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RNBC(i)); 22013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RUC); 22113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RFC); 22213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_ROC); 22313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_RJC); 22413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPRC); 22513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPDC); 22613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MNGPTC); 22713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORL); 22813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TORH); 22913705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPR); 23013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_TPT); 23113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC64); 23213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC127); 23313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC255); 23413705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC511); 23513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1023); 23613705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_PTC1522); 23713705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_MPTC); 23813705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_BPTC); 23913705f88SJack F Vogel for (i = 0; i < 16; i++) { 24013705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPRC(i)); 24113705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBRC(i)); 24213705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QPTC(i)); 24313705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_QBTC(i)); 24413705f88SJack F Vogel } 24513705f88SJack F Vogel 24613705f88SJack F Vogel return IXGBE_SUCCESS; 24713705f88SJack F Vogel } 24813705f88SJack F Vogel 24913705f88SJack F Vogel /** 25013705f88SJack F Vogel * ixgbe_get_mac_addr_generic - Generic get MAC address 25113705f88SJack F Vogel * @hw: pointer to hardware structure 25213705f88SJack F Vogel * @mac_addr: Adapter MAC address 25313705f88SJack F Vogel * 25413705f88SJack F Vogel * Reads the adapter's MAC address from first Receive Address Register (RAR0) 25513705f88SJack F Vogel * A reset of the adapter must be performed prior to calling this function 25613705f88SJack F Vogel * in order for the MAC address to have been loaded from the EEPROM into RAR0 25713705f88SJack F Vogel **/ 25813705f88SJack F Vogel s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) 25913705f88SJack F Vogel { 26013705f88SJack F Vogel u32 rar_high; 26113705f88SJack F Vogel u32 rar_low; 26213705f88SJack F Vogel u16 i; 26313705f88SJack F Vogel 26413705f88SJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(0)); 26513705f88SJack F Vogel rar_low = IXGBE_READ_REG(hw, IXGBE_RAL(0)); 26613705f88SJack F Vogel 26713705f88SJack F Vogel for (i = 0; i < 4; i++) 26813705f88SJack F Vogel mac_addr[i] = (u8)(rar_low >> (i*8)); 26913705f88SJack F Vogel 27013705f88SJack F Vogel for (i = 0; i < 2; i++) 27113705f88SJack F Vogel mac_addr[i+4] = (u8)(rar_high >> (i*8)); 27213705f88SJack F Vogel 27313705f88SJack F Vogel return IXGBE_SUCCESS; 27413705f88SJack F Vogel } 27513705f88SJack F Vogel 27613705f88SJack F Vogel /** 27713705f88SJack F Vogel * ixgbe_get_bus_info_generic - Generic set PCI bus info 27813705f88SJack F Vogel * @hw: pointer to hardware structure 27913705f88SJack F Vogel * 28013705f88SJack F Vogel * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure 28113705f88SJack F Vogel **/ 28213705f88SJack F Vogel s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) 28313705f88SJack F Vogel { 28413705f88SJack F Vogel u16 link_status; 28513705f88SJack F Vogel 28613705f88SJack F Vogel hw->bus.type = ixgbe_bus_type_pci_express; 28713705f88SJack F Vogel 28813705f88SJack F Vogel /* Get the negotiated link width and speed from PCI config space */ 28913705f88SJack F Vogel link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); 29013705f88SJack F Vogel 29113705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_WIDTH) { 29213705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_1: 29313705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x1; 29413705f88SJack F Vogel break; 29513705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_2: 29613705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x2; 29713705f88SJack F Vogel break; 29813705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_4: 29913705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x4; 30013705f88SJack F Vogel break; 30113705f88SJack F Vogel case IXGBE_PCI_LINK_WIDTH_8: 30213705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_pcie_x8; 30313705f88SJack F Vogel break; 30413705f88SJack F Vogel default: 30513705f88SJack F Vogel hw->bus.width = ixgbe_bus_width_unknown; 30613705f88SJack F Vogel break; 30713705f88SJack F Vogel } 30813705f88SJack F Vogel 30913705f88SJack F Vogel switch (link_status & IXGBE_PCI_LINK_SPEED) { 31013705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_2500: 31113705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_2500; 31213705f88SJack F Vogel break; 31313705f88SJack F Vogel case IXGBE_PCI_LINK_SPEED_5000: 31413705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_5000; 31513705f88SJack F Vogel break; 31613705f88SJack F Vogel default: 31713705f88SJack F Vogel hw->bus.speed = ixgbe_bus_speed_unknown; 31813705f88SJack F Vogel break; 31913705f88SJack F Vogel } 32013705f88SJack F Vogel 32113705f88SJack F Vogel return IXGBE_SUCCESS; 32213705f88SJack F Vogel } 32313705f88SJack F Vogel 32413705f88SJack F Vogel /** 32513705f88SJack F Vogel * ixgbe_stop_adapter_generic - Generic stop TX/RX units 32613705f88SJack F Vogel * @hw: pointer to hardware structure 32713705f88SJack F Vogel * 32813705f88SJack F Vogel * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, 32913705f88SJack F Vogel * disables transmit and receive units. The adapter_stopped flag is used by 33013705f88SJack F Vogel * the shared code and drivers to determine if the adapter is in a stopped 33113705f88SJack F Vogel * state and should not touch the hardware. 33213705f88SJack F Vogel **/ 33313705f88SJack F Vogel s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) 33413705f88SJack F Vogel { 33513705f88SJack F Vogel u32 number_of_queues; 33613705f88SJack F Vogel u32 reg_val; 33713705f88SJack F Vogel u16 i; 33813705f88SJack F Vogel 33913705f88SJack F Vogel /* 34013705f88SJack F Vogel * Set the adapter_stopped flag so other driver functions stop touching 34113705f88SJack F Vogel * the hardware 34213705f88SJack F Vogel */ 34313705f88SJack F Vogel hw->adapter_stopped = TRUE; 34413705f88SJack F Vogel 34513705f88SJack F Vogel /* Disable the receive unit */ 34613705f88SJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL); 34713705f88SJack F Vogel reg_val &= ~(IXGBE_RXCTRL_RXEN); 34813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val); 34913705f88SJack F Vogel msec_delay(2); 35013705f88SJack F Vogel 35113705f88SJack F Vogel /* Clear interrupt mask to stop from interrupts being generated */ 35213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); 35313705f88SJack F Vogel 35413705f88SJack F Vogel /* Clear any pending interrupts */ 35513705f88SJack F Vogel IXGBE_READ_REG(hw, IXGBE_EICR); 35613705f88SJack F Vogel 35713705f88SJack F Vogel /* Disable the transmit unit. Each queue must be disabled. */ 35813705f88SJack F Vogel number_of_queues = ixgbe_get_num_of_tx_queues(hw); 35913705f88SJack F Vogel for (i = 0; i < number_of_queues; i++) { 36013705f88SJack F Vogel reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); 36113705f88SJack F Vogel if (reg_val & IXGBE_TXDCTL_ENABLE) { 36213705f88SJack F Vogel reg_val &= ~IXGBE_TXDCTL_ENABLE; 36313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), reg_val); 36413705f88SJack F Vogel } 36513705f88SJack F Vogel } 36613705f88SJack F Vogel 36713705f88SJack F Vogel return IXGBE_SUCCESS; 36813705f88SJack F Vogel } 36913705f88SJack F Vogel 37013705f88SJack F Vogel /** 37113705f88SJack F Vogel * ixgbe_led_on_generic - Turns on the software controllable LEDs. 37213705f88SJack F Vogel * @hw: pointer to hardware structure 37313705f88SJack F Vogel * @index: led number to turn on 37413705f88SJack F Vogel **/ 37513705f88SJack F Vogel s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) 37613705f88SJack F Vogel { 37713705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 37813705f88SJack F Vogel 37913705f88SJack F Vogel /* To turn on the LED, set mode to ON. */ 38013705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 38113705f88SJack F Vogel led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); 38213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 38313705f88SJack F Vogel 38413705f88SJack F Vogel return IXGBE_SUCCESS; 38513705f88SJack F Vogel } 38613705f88SJack F Vogel 38713705f88SJack F Vogel /** 38813705f88SJack F Vogel * ixgbe_led_off_generic - Turns off the software controllable LEDs. 38913705f88SJack F Vogel * @hw: pointer to hardware structure 39013705f88SJack F Vogel * @index: led number to turn off 39113705f88SJack F Vogel **/ 39213705f88SJack F Vogel s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) 39313705f88SJack F Vogel { 39413705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 39513705f88SJack F Vogel 39613705f88SJack F Vogel /* To turn off the LED, set mode to OFF. */ 39713705f88SJack F Vogel led_reg &= ~IXGBE_LED_MODE_MASK(index); 39813705f88SJack F Vogel led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); 39913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 40013705f88SJack F Vogel 40113705f88SJack F Vogel return IXGBE_SUCCESS; 40213705f88SJack F Vogel } 40313705f88SJack F Vogel 40413705f88SJack F Vogel 40513705f88SJack F Vogel /** 40613705f88SJack F Vogel * ixgbe_blink_led_start_generic - Blink LED based on index. 40713705f88SJack F Vogel * @hw: pointer to hardware structure 40813705f88SJack F Vogel * @index: led number to blink 40913705f88SJack F Vogel **/ 41013705f88SJack F Vogel s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) 41113705f88SJack F Vogel { 41213705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 41313705f88SJack F Vogel 41413705f88SJack F Vogel led_reg |= IXGBE_LED_BLINK(index); 41513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 41613705f88SJack F Vogel 41713705f88SJack F Vogel return IXGBE_SUCCESS; 41813705f88SJack F Vogel } 41913705f88SJack F Vogel 42013705f88SJack F Vogel /** 42113705f88SJack F Vogel * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. 42213705f88SJack F Vogel * @hw: pointer to hardware structure 42313705f88SJack F Vogel * @index: led number to stop blinking 42413705f88SJack F Vogel **/ 42513705f88SJack F Vogel s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) 42613705f88SJack F Vogel { 42713705f88SJack F Vogel u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 42813705f88SJack F Vogel 42913705f88SJack F Vogel led_reg &= ~IXGBE_LED_BLINK(index); 43013705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 43113705f88SJack F Vogel 43213705f88SJack F Vogel return IXGBE_SUCCESS; 43313705f88SJack F Vogel } 43413705f88SJack F Vogel 43513705f88SJack F Vogel /** 43613705f88SJack F Vogel * ixgbe_init_eeprom_params_generic - Initialize EEPROM params 43713705f88SJack F Vogel * @hw: pointer to hardware structure 43813705f88SJack F Vogel * 43913705f88SJack F Vogel * Initializes the EEPROM parameters ixgbe_eeprom_info within the 44013705f88SJack F Vogel * ixgbe_hw struct in order to set up EEPROM access. 44113705f88SJack F Vogel **/ 44213705f88SJack F Vogel s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) 44313705f88SJack F Vogel { 44413705f88SJack F Vogel struct ixgbe_eeprom_info *eeprom = &hw->eeprom; 44513705f88SJack F Vogel u32 eec; 44613705f88SJack F Vogel u16 eeprom_size; 44713705f88SJack F Vogel 44813705f88SJack F Vogel if (eeprom->type == ixgbe_eeprom_uninitialized) { 44913705f88SJack F Vogel eeprom->type = ixgbe_eeprom_none; 45013705f88SJack F Vogel 45113705f88SJack F Vogel /* 45213705f88SJack F Vogel * Check for EEPROM present first. 45313705f88SJack F Vogel * If not present leave as none 45413705f88SJack F Vogel */ 45513705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 45613705f88SJack F Vogel if (eec & IXGBE_EEC_PRES) { 45713705f88SJack F Vogel eeprom->type = ixgbe_eeprom_spi; 45813705f88SJack F Vogel 45913705f88SJack F Vogel /* 46013705f88SJack F Vogel * SPI EEPROM is assumed here. This code would need to 46113705f88SJack F Vogel * change if a future EEPROM is not SPI. 46213705f88SJack F Vogel */ 46313705f88SJack F Vogel eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> 46413705f88SJack F Vogel IXGBE_EEC_SIZE_SHIFT); 46513705f88SJack F Vogel eeprom->word_size = 1 << (eeprom_size + 46613705f88SJack F Vogel IXGBE_EEPROM_WORD_SIZE_SHIFT); 46713705f88SJack F Vogel } 46813705f88SJack F Vogel 46913705f88SJack F Vogel if (eec & IXGBE_EEC_ADDR_SIZE) 47013705f88SJack F Vogel eeprom->address_bits = 16; 47113705f88SJack F Vogel else 47213705f88SJack F Vogel eeprom->address_bits = 8; 47313705f88SJack F Vogel DEBUGOUT3("Eeprom params: type = %d, size = %d, address bits: " 47413705f88SJack F Vogel "%d\n", eeprom->type, eeprom->word_size, 47513705f88SJack F Vogel eeprom->address_bits); 47613705f88SJack F Vogel } 47713705f88SJack F Vogel 47813705f88SJack F Vogel return IXGBE_SUCCESS; 47913705f88SJack F Vogel } 48013705f88SJack F Vogel 48113705f88SJack F Vogel /** 48213705f88SJack F Vogel * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM 48313705f88SJack F Vogel * @hw: pointer to hardware structure 48413705f88SJack F Vogel * @offset: offset within the EEPROM to be written to 48513705f88SJack F Vogel * @data: 16 bit word to be written to the EEPROM 48613705f88SJack F Vogel * 48713705f88SJack F Vogel * If ixgbe_eeprom_update_checksum is not called after this function, the 48813705f88SJack F Vogel * EEPROM will most likely contain an invalid checksum. 48913705f88SJack F Vogel **/ 49013705f88SJack F Vogel s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) 49113705f88SJack F Vogel { 49213705f88SJack F Vogel s32 status; 49313705f88SJack F Vogel u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI; 49413705f88SJack F Vogel 49513705f88SJack F Vogel /* Prepare the EEPROM for writing */ 49613705f88SJack F Vogel status = ixgbe_acquire_eeprom(hw); 49713705f88SJack F Vogel 49813705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 49913705f88SJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 50013705f88SJack F Vogel ixgbe_release_eeprom(hw); 50113705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 50213705f88SJack F Vogel } 50313705f88SJack F Vogel } 50413705f88SJack F Vogel 50513705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 50613705f88SJack F Vogel ixgbe_standby_eeprom(hw); 50713705f88SJack F Vogel 50813705f88SJack F Vogel /* Send the WRITE ENABLE command (8 bit opcode ) */ 50913705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI, 51013705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 51113705f88SJack F Vogel 51213705f88SJack F Vogel ixgbe_standby_eeprom(hw); 51313705f88SJack F Vogel 51413705f88SJack F Vogel /* 51513705f88SJack F Vogel * Some SPI eeproms use the 8th address bit embedded in the 51613705f88SJack F Vogel * opcode 51713705f88SJack F Vogel */ 51813705f88SJack F Vogel if ((hw->eeprom.address_bits == 8) && (offset >= 128)) 51913705f88SJack F Vogel write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 52013705f88SJack F Vogel 52113705f88SJack F Vogel /* Send the Write command (8-bit opcode + addr) */ 52213705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, write_opcode, 52313705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 52413705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), 52513705f88SJack F Vogel hw->eeprom.address_bits); 52613705f88SJack F Vogel 52713705f88SJack F Vogel /* Send the data */ 52813705f88SJack F Vogel data = (data >> 8) | (data << 8); 52913705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, data, 16); 53013705f88SJack F Vogel ixgbe_standby_eeprom(hw); 53113705f88SJack F Vogel 53213705f88SJack F Vogel msec_delay(10); 53313705f88SJack F Vogel 53413705f88SJack F Vogel /* Done with writing - release the EEPROM */ 53513705f88SJack F Vogel ixgbe_release_eeprom(hw); 53613705f88SJack F Vogel } 53713705f88SJack F Vogel 53813705f88SJack F Vogel return status; 53913705f88SJack F Vogel } 54013705f88SJack F Vogel 54113705f88SJack F Vogel /** 54213705f88SJack F Vogel * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang 54313705f88SJack F Vogel * @hw: pointer to hardware structure 54413705f88SJack F Vogel * @offset: offset within the EEPROM to be read 54513705f88SJack F Vogel * @data: read 16 bit value from EEPROM 54613705f88SJack F Vogel * 54713705f88SJack F Vogel * Reads 16 bit value from EEPROM through bit-bang method 54813705f88SJack F Vogel **/ 54913705f88SJack F Vogel s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, 55013705f88SJack F Vogel u16 *data) 55113705f88SJack F Vogel { 55213705f88SJack F Vogel s32 status; 55313705f88SJack F Vogel u16 word_in; 55413705f88SJack F Vogel u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; 55513705f88SJack F Vogel 55613705f88SJack F Vogel /* Prepare the EEPROM for reading */ 55713705f88SJack F Vogel status = ixgbe_acquire_eeprom(hw); 55813705f88SJack F Vogel 55913705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 56013705f88SJack F Vogel if (ixgbe_ready_eeprom(hw) != IXGBE_SUCCESS) { 56113705f88SJack F Vogel ixgbe_release_eeprom(hw); 56213705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 56313705f88SJack F Vogel } 56413705f88SJack F Vogel } 56513705f88SJack F Vogel 56613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 56713705f88SJack F Vogel ixgbe_standby_eeprom(hw); 56813705f88SJack F Vogel 56913705f88SJack F Vogel /* 57013705f88SJack F Vogel * Some SPI eeproms use the 8th address bit embedded in the 57113705f88SJack F Vogel * opcode 57213705f88SJack F Vogel */ 57313705f88SJack F Vogel if ((hw->eeprom.address_bits == 8) && (offset >= 128)) 57413705f88SJack F Vogel read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; 57513705f88SJack F Vogel 57613705f88SJack F Vogel /* Send the READ command (opcode + addr) */ 57713705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, read_opcode, 57813705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 57913705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), 58013705f88SJack F Vogel hw->eeprom.address_bits); 58113705f88SJack F Vogel 58213705f88SJack F Vogel /* Read the data. */ 58313705f88SJack F Vogel word_in = ixgbe_shift_in_eeprom_bits(hw, 16); 58413705f88SJack F Vogel *data = (word_in >> 8) | (word_in << 8); 58513705f88SJack F Vogel 58613705f88SJack F Vogel /* End this read operation */ 58713705f88SJack F Vogel ixgbe_release_eeprom(hw); 58813705f88SJack F Vogel } 58913705f88SJack F Vogel 59013705f88SJack F Vogel return status; 59113705f88SJack F Vogel } 59213705f88SJack F Vogel 59313705f88SJack F Vogel /** 59413705f88SJack F Vogel * ixgbe_read_eeprom_generic - Read EEPROM word using EERD 59513705f88SJack F Vogel * @hw: pointer to hardware structure 59613705f88SJack F Vogel * @offset: offset of word in the EEPROM to read 59713705f88SJack F Vogel * @data: word read from the EEPROM 59813705f88SJack F Vogel * 59913705f88SJack F Vogel * Reads a 16 bit word from the EEPROM using the EERD register. 60013705f88SJack F Vogel **/ 60113705f88SJack F Vogel s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) 60213705f88SJack F Vogel { 60313705f88SJack F Vogel u32 eerd; 60413705f88SJack F Vogel s32 status; 60513705f88SJack F Vogel 60613705f88SJack F Vogel eerd = (offset << IXGBE_EEPROM_READ_ADDR_SHIFT) + 60713705f88SJack F Vogel IXGBE_EEPROM_READ_REG_START; 60813705f88SJack F Vogel 60913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd); 61013705f88SJack F Vogel status = ixgbe_poll_eeprom_eerd_done(hw); 61113705f88SJack F Vogel 61213705f88SJack F Vogel if (status == IXGBE_SUCCESS) 61313705f88SJack F Vogel *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >> 61413705f88SJack F Vogel IXGBE_EEPROM_READ_REG_DATA); 61513705f88SJack F Vogel else 61613705f88SJack F Vogel DEBUGOUT("Eeprom read timed out\n"); 61713705f88SJack F Vogel 61813705f88SJack F Vogel return status; 61913705f88SJack F Vogel } 62013705f88SJack F Vogel 62113705f88SJack F Vogel /** 62213705f88SJack F Vogel * ixgbe_poll_eeprom_eerd_done - Poll EERD status 62313705f88SJack F Vogel * @hw: pointer to hardware structure 62413705f88SJack F Vogel * 62513705f88SJack F Vogel * Polls the status bit (bit 1) of the EERD to determine when the read is done. 62613705f88SJack F Vogel **/ 62713705f88SJack F Vogel static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw) 62813705f88SJack F Vogel { 62913705f88SJack F Vogel u32 i; 63013705f88SJack F Vogel u32 reg; 63113705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 63213705f88SJack F Vogel 63313705f88SJack F Vogel for (i = 0; i < IXGBE_EERD_ATTEMPTS; i++) { 63413705f88SJack F Vogel reg = IXGBE_READ_REG(hw, IXGBE_EERD); 63513705f88SJack F Vogel if (reg & IXGBE_EEPROM_READ_REG_DONE) { 63613705f88SJack F Vogel status = IXGBE_SUCCESS; 63713705f88SJack F Vogel break; 63813705f88SJack F Vogel } 63913705f88SJack F Vogel usec_delay(5); 64013705f88SJack F Vogel } 64113705f88SJack F Vogel return status; 64213705f88SJack F Vogel } 64313705f88SJack F Vogel 64413705f88SJack F Vogel /** 64513705f88SJack F Vogel * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang 64613705f88SJack F Vogel * @hw: pointer to hardware structure 64713705f88SJack F Vogel * 64813705f88SJack F Vogel * Prepares EEPROM for access using bit-bang method. This function should 64913705f88SJack F Vogel * be called before issuing a command to the EEPROM. 65013705f88SJack F Vogel **/ 65113705f88SJack F Vogel static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) 65213705f88SJack F Vogel { 65313705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 65413705f88SJack F Vogel u32 eec; 65513705f88SJack F Vogel u32 i; 65613705f88SJack F Vogel 65713705f88SJack F Vogel if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != IXGBE_SUCCESS) 65813705f88SJack F Vogel status = IXGBE_ERR_SWFW_SYNC; 65913705f88SJack F Vogel 66013705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 66113705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 66213705f88SJack F Vogel 66313705f88SJack F Vogel /* Request EEPROM Access */ 66413705f88SJack F Vogel eec |= IXGBE_EEC_REQ; 66513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 66613705f88SJack F Vogel 66713705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { 66813705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 66913705f88SJack F Vogel if (eec & IXGBE_EEC_GNT) 67013705f88SJack F Vogel break; 67113705f88SJack F Vogel usec_delay(5); 67213705f88SJack F Vogel } 67313705f88SJack F Vogel 67413705f88SJack F Vogel /* Release if grant not aquired */ 67513705f88SJack F Vogel if (!(eec & IXGBE_EEC_GNT)) { 67613705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 67713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 67813705f88SJack F Vogel DEBUGOUT("Could not acquire EEPROM grant\n"); 67913705f88SJack F Vogel 68013705f88SJack F Vogel ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 68113705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 68213705f88SJack F Vogel } 68313705f88SJack F Vogel } 68413705f88SJack F Vogel 68513705f88SJack F Vogel /* Setup EEPROM for Read/Write */ 68613705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 68713705f88SJack F Vogel /* Clear CS and SK */ 68813705f88SJack F Vogel eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); 68913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 69013705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 69113705f88SJack F Vogel usec_delay(1); 69213705f88SJack F Vogel } 69313705f88SJack F Vogel return status; 69413705f88SJack F Vogel } 69513705f88SJack F Vogel 69613705f88SJack F Vogel /** 69713705f88SJack F Vogel * ixgbe_get_eeprom_semaphore - Get hardware semaphore 69813705f88SJack F Vogel * @hw: pointer to hardware structure 69913705f88SJack F Vogel * 70013705f88SJack F Vogel * Sets the hardware semaphores so EEPROM access can occur for bit-bang method 70113705f88SJack F Vogel **/ 70213705f88SJack F Vogel static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) 70313705f88SJack F Vogel { 70413705f88SJack F Vogel s32 status = IXGBE_ERR_EEPROM; 70513705f88SJack F Vogel u32 timeout; 70613705f88SJack F Vogel u32 i; 70713705f88SJack F Vogel u32 swsm; 70813705f88SJack F Vogel 70913705f88SJack F Vogel /* Set timeout value based on size of EEPROM */ 71013705f88SJack F Vogel timeout = hw->eeprom.word_size + 1; 71113705f88SJack F Vogel 71213705f88SJack F Vogel /* Get SMBI software semaphore between device drivers first */ 71313705f88SJack F Vogel for (i = 0; i < timeout; i++) { 71413705f88SJack F Vogel /* 71513705f88SJack F Vogel * If the SMBI bit is 0 when we read it, then the bit will be 71613705f88SJack F Vogel * set and we have the semaphore 71713705f88SJack F Vogel */ 71813705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 71913705f88SJack F Vogel if (!(swsm & IXGBE_SWSM_SMBI)) { 72013705f88SJack F Vogel status = IXGBE_SUCCESS; 72113705f88SJack F Vogel break; 72213705f88SJack F Vogel } 72313705f88SJack F Vogel msec_delay(1); 72413705f88SJack F Vogel } 72513705f88SJack F Vogel 72613705f88SJack F Vogel /* Now get the semaphore between SW/FW through the SWESMBI bit */ 72713705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 72813705f88SJack F Vogel for (i = 0; i < timeout; i++) { 72913705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 73013705f88SJack F Vogel 73113705f88SJack F Vogel /* Set the SW EEPROM semaphore bit to request access */ 73213705f88SJack F Vogel swsm |= IXGBE_SWSM_SWESMBI; 73313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 73413705f88SJack F Vogel 73513705f88SJack F Vogel /* 73613705f88SJack F Vogel * If we set the bit successfully then we got the 73713705f88SJack F Vogel * semaphore. 73813705f88SJack F Vogel */ 73913705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 74013705f88SJack F Vogel if (swsm & IXGBE_SWSM_SWESMBI) 74113705f88SJack F Vogel break; 74213705f88SJack F Vogel 74313705f88SJack F Vogel usec_delay(50); 74413705f88SJack F Vogel } 74513705f88SJack F Vogel 74613705f88SJack F Vogel /* 74713705f88SJack F Vogel * Release semaphores and return error if SW EEPROM semaphore 74813705f88SJack F Vogel * was not granted because we don't have access to the EEPROM 74913705f88SJack F Vogel */ 75013705f88SJack F Vogel if (i >= timeout) { 75113705f88SJack F Vogel DEBUGOUT("Driver can't access the Eeprom - Semaphore " 75213705f88SJack F Vogel "not granted.\n"); 75313705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 75413705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 75513705f88SJack F Vogel } 75613705f88SJack F Vogel } 75713705f88SJack F Vogel 75813705f88SJack F Vogel return status; 75913705f88SJack F Vogel } 76013705f88SJack F Vogel 76113705f88SJack F Vogel /** 76213705f88SJack F Vogel * ixgbe_release_eeprom_semaphore - Release hardware semaphore 76313705f88SJack F Vogel * @hw: pointer to hardware structure 76413705f88SJack F Vogel * 76513705f88SJack F Vogel * This function clears hardware semaphore bits. 76613705f88SJack F Vogel **/ 76713705f88SJack F Vogel static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) 76813705f88SJack F Vogel { 76913705f88SJack F Vogel u32 swsm; 77013705f88SJack F Vogel 77113705f88SJack F Vogel swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); 77213705f88SJack F Vogel 77313705f88SJack F Vogel /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ 77413705f88SJack F Vogel swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI); 77513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); 77613705f88SJack F Vogel } 77713705f88SJack F Vogel 77813705f88SJack F Vogel /** 77913705f88SJack F Vogel * ixgbe_ready_eeprom - Polls for EEPROM ready 78013705f88SJack F Vogel * @hw: pointer to hardware structure 78113705f88SJack F Vogel **/ 78213705f88SJack F Vogel static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) 78313705f88SJack F Vogel { 78413705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 78513705f88SJack F Vogel u16 i; 78613705f88SJack F Vogel u8 spi_stat_reg; 78713705f88SJack F Vogel 78813705f88SJack F Vogel /* 78913705f88SJack F Vogel * Read "Status Register" repeatedly until the LSB is cleared. The 79013705f88SJack F Vogel * EEPROM will signal that the command has been completed by clearing 79113705f88SJack F Vogel * bit 0 of the internal status register. If it's not cleared within 79213705f88SJack F Vogel * 5 milliseconds, then error out. 79313705f88SJack F Vogel */ 79413705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) { 79513705f88SJack F Vogel ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI, 79613705f88SJack F Vogel IXGBE_EEPROM_OPCODE_BITS); 79713705f88SJack F Vogel spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8); 79813705f88SJack F Vogel if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI)) 79913705f88SJack F Vogel break; 80013705f88SJack F Vogel 80113705f88SJack F Vogel usec_delay(5); 80213705f88SJack F Vogel ixgbe_standby_eeprom(hw); 80313705f88SJack F Vogel }; 80413705f88SJack F Vogel 80513705f88SJack F Vogel /* 80613705f88SJack F Vogel * On some parts, SPI write time could vary from 0-20mSec on 3.3V 80713705f88SJack F Vogel * devices (and only 0-5mSec on 5V devices) 80813705f88SJack F Vogel */ 80913705f88SJack F Vogel if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { 81013705f88SJack F Vogel DEBUGOUT("SPI EEPROM Status error\n"); 81113705f88SJack F Vogel status = IXGBE_ERR_EEPROM; 81213705f88SJack F Vogel } 81313705f88SJack F Vogel 81413705f88SJack F Vogel return status; 81513705f88SJack F Vogel } 81613705f88SJack F Vogel 81713705f88SJack F Vogel /** 81813705f88SJack F Vogel * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state 81913705f88SJack F Vogel * @hw: pointer to hardware structure 82013705f88SJack F Vogel **/ 82113705f88SJack F Vogel static void ixgbe_standby_eeprom(struct ixgbe_hw *hw) 82213705f88SJack F Vogel { 82313705f88SJack F Vogel u32 eec; 82413705f88SJack F Vogel 82513705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 82613705f88SJack F Vogel 82713705f88SJack F Vogel /* Toggle CS to flush commands */ 82813705f88SJack F Vogel eec |= IXGBE_EEC_CS; 82913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 83013705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 83113705f88SJack F Vogel usec_delay(1); 83213705f88SJack F Vogel eec &= ~IXGBE_EEC_CS; 83313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 83413705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 83513705f88SJack F Vogel usec_delay(1); 83613705f88SJack F Vogel } 83713705f88SJack F Vogel 83813705f88SJack F Vogel /** 83913705f88SJack F Vogel * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM. 84013705f88SJack F Vogel * @hw: pointer to hardware structure 84113705f88SJack F Vogel * @data: data to send to the EEPROM 84213705f88SJack F Vogel * @count: number of bits to shift out 84313705f88SJack F Vogel **/ 84413705f88SJack F Vogel static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, 84513705f88SJack F Vogel u16 count) 84613705f88SJack F Vogel { 84713705f88SJack F Vogel u32 eec; 84813705f88SJack F Vogel u32 mask; 84913705f88SJack F Vogel u32 i; 85013705f88SJack F Vogel 85113705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 85213705f88SJack F Vogel 85313705f88SJack F Vogel /* 85413705f88SJack F Vogel * Mask is used to shift "count" bits of "data" out to the EEPROM 85513705f88SJack F Vogel * one bit at a time. Determine the starting bit based on count 85613705f88SJack F Vogel */ 85713705f88SJack F Vogel mask = 0x01 << (count - 1); 85813705f88SJack F Vogel 85913705f88SJack F Vogel for (i = 0; i < count; i++) { 86013705f88SJack F Vogel /* 86113705f88SJack F Vogel * A "1" is shifted out to the EEPROM by setting bit "DI" to a 86213705f88SJack F Vogel * "1", and then raising and then lowering the clock (the SK 86313705f88SJack F Vogel * bit controls the clock input to the EEPROM). A "0" is 86413705f88SJack F Vogel * shifted out to the EEPROM by setting "DI" to "0" and then 86513705f88SJack F Vogel * raising and then lowering the clock. 86613705f88SJack F Vogel */ 86713705f88SJack F Vogel if (data & mask) 86813705f88SJack F Vogel eec |= IXGBE_EEC_DI; 86913705f88SJack F Vogel else 87013705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 87113705f88SJack F Vogel 87213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 87313705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 87413705f88SJack F Vogel 87513705f88SJack F Vogel usec_delay(1); 87613705f88SJack F Vogel 87713705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 87813705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 87913705f88SJack F Vogel 88013705f88SJack F Vogel /* 88113705f88SJack F Vogel * Shift mask to signify next bit of data to shift in to the 88213705f88SJack F Vogel * EEPROM 88313705f88SJack F Vogel */ 88413705f88SJack F Vogel mask = mask >> 1; 88513705f88SJack F Vogel }; 88613705f88SJack F Vogel 88713705f88SJack F Vogel /* We leave the "DI" bit set to "0" when we leave this routine. */ 88813705f88SJack F Vogel eec &= ~IXGBE_EEC_DI; 88913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 89013705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 89113705f88SJack F Vogel } 89213705f88SJack F Vogel 89313705f88SJack F Vogel /** 89413705f88SJack F Vogel * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM 89513705f88SJack F Vogel * @hw: pointer to hardware structure 89613705f88SJack F Vogel **/ 89713705f88SJack F Vogel static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) 89813705f88SJack F Vogel { 89913705f88SJack F Vogel u32 eec; 90013705f88SJack F Vogel u32 i; 90113705f88SJack F Vogel u16 data = 0; 90213705f88SJack F Vogel 90313705f88SJack F Vogel /* 90413705f88SJack F Vogel * In order to read a register from the EEPROM, we need to shift 90513705f88SJack F Vogel * 'count' bits in from the EEPROM. Bits are "shifted in" by raising 90613705f88SJack F Vogel * the clock input to the EEPROM (setting the SK bit), and then reading 90713705f88SJack F Vogel * the value of the "DO" bit. During this "shifting in" process the 90813705f88SJack F Vogel * "DI" bit should always be clear. 90913705f88SJack F Vogel */ 91013705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 91113705f88SJack F Vogel 91213705f88SJack F Vogel eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); 91313705f88SJack F Vogel 91413705f88SJack F Vogel for (i = 0; i < count; i++) { 91513705f88SJack F Vogel data = data << 1; 91613705f88SJack F Vogel ixgbe_raise_eeprom_clk(hw, &eec); 91713705f88SJack F Vogel 91813705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 91913705f88SJack F Vogel 92013705f88SJack F Vogel eec &= ~(IXGBE_EEC_DI); 92113705f88SJack F Vogel if (eec & IXGBE_EEC_DO) 92213705f88SJack F Vogel data |= 1; 92313705f88SJack F Vogel 92413705f88SJack F Vogel ixgbe_lower_eeprom_clk(hw, &eec); 92513705f88SJack F Vogel } 92613705f88SJack F Vogel 92713705f88SJack F Vogel return data; 92813705f88SJack F Vogel } 92913705f88SJack F Vogel 93013705f88SJack F Vogel /** 93113705f88SJack F Vogel * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input. 93213705f88SJack F Vogel * @hw: pointer to hardware structure 93313705f88SJack F Vogel * @eec: EEC register's current value 93413705f88SJack F Vogel **/ 93513705f88SJack F Vogel static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 93613705f88SJack F Vogel { 93713705f88SJack F Vogel /* 93813705f88SJack F Vogel * Raise the clock input to the EEPROM 93913705f88SJack F Vogel * (setting the SK bit), then delay 94013705f88SJack F Vogel */ 94113705f88SJack F Vogel *eec = *eec | IXGBE_EEC_SK; 94213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 94313705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 94413705f88SJack F Vogel usec_delay(1); 94513705f88SJack F Vogel } 94613705f88SJack F Vogel 94713705f88SJack F Vogel /** 94813705f88SJack F Vogel * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input. 94913705f88SJack F Vogel * @hw: pointer to hardware structure 95013705f88SJack F Vogel * @eecd: EECD's current value 95113705f88SJack F Vogel **/ 95213705f88SJack F Vogel static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) 95313705f88SJack F Vogel { 95413705f88SJack F Vogel /* 95513705f88SJack F Vogel * Lower the clock input to the EEPROM (clearing the SK bit), then 95613705f88SJack F Vogel * delay 95713705f88SJack F Vogel */ 95813705f88SJack F Vogel *eec = *eec & ~IXGBE_EEC_SK; 95913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); 96013705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 96113705f88SJack F Vogel usec_delay(1); 96213705f88SJack F Vogel } 96313705f88SJack F Vogel 96413705f88SJack F Vogel /** 96513705f88SJack F Vogel * ixgbe_release_eeprom - Release EEPROM, release semaphores 96613705f88SJack F Vogel * @hw: pointer to hardware structure 96713705f88SJack F Vogel **/ 96813705f88SJack F Vogel static void ixgbe_release_eeprom(struct ixgbe_hw *hw) 96913705f88SJack F Vogel { 97013705f88SJack F Vogel u32 eec; 97113705f88SJack F Vogel 97213705f88SJack F Vogel eec = IXGBE_READ_REG(hw, IXGBE_EEC); 97313705f88SJack F Vogel 97413705f88SJack F Vogel eec |= IXGBE_EEC_CS; /* Pull CS high */ 97513705f88SJack F Vogel eec &= ~IXGBE_EEC_SK; /* Lower SCK */ 97613705f88SJack F Vogel 97713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 97813705f88SJack F Vogel IXGBE_WRITE_FLUSH(hw); 97913705f88SJack F Vogel 98013705f88SJack F Vogel usec_delay(1); 98113705f88SJack F Vogel 98213705f88SJack F Vogel /* Stop requesting EEPROM access */ 98313705f88SJack F Vogel eec &= ~IXGBE_EEC_REQ; 98413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); 98513705f88SJack F Vogel 98613705f88SJack F Vogel ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 98713705f88SJack F Vogel } 98813705f88SJack F Vogel 98913705f88SJack F Vogel /** 99013705f88SJack F Vogel * ixgbe_calc_eeprom_checksum - Calculates and returns the checksum 99113705f88SJack F Vogel * @hw: pointer to hardware structure 99213705f88SJack F Vogel **/ 99313705f88SJack F Vogel static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) 99413705f88SJack F Vogel { 99513705f88SJack F Vogel u16 i; 99613705f88SJack F Vogel u16 j; 99713705f88SJack F Vogel u16 checksum = 0; 99813705f88SJack F Vogel u16 length = 0; 99913705f88SJack F Vogel u16 pointer = 0; 100013705f88SJack F Vogel u16 word = 0; 100113705f88SJack F Vogel 100213705f88SJack F Vogel /* Include 0x0-0x3F in the checksum */ 100313705f88SJack F Vogel for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 100413705f88SJack F Vogel if (ixgbe_read_eeprom(hw, i, &word) != IXGBE_SUCCESS) { 100513705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 100613705f88SJack F Vogel break; 100713705f88SJack F Vogel } 100813705f88SJack F Vogel checksum += word; 100913705f88SJack F Vogel } 101013705f88SJack F Vogel 101113705f88SJack F Vogel /* Include all data from pointers except for the fw pointer */ 101213705f88SJack F Vogel for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 101313705f88SJack F Vogel ixgbe_read_eeprom(hw, i, &pointer); 101413705f88SJack F Vogel 101513705f88SJack F Vogel /* Make sure the pointer seems valid */ 101613705f88SJack F Vogel if (pointer != 0xFFFF && pointer != 0) { 101713705f88SJack F Vogel ixgbe_read_eeprom(hw, pointer, &length); 101813705f88SJack F Vogel 101913705f88SJack F Vogel if (length != 0xFFFF && length != 0) { 102013705f88SJack F Vogel for (j = pointer+1; j <= pointer+length; j++) { 102113705f88SJack F Vogel ixgbe_read_eeprom(hw, j, &word); 102213705f88SJack F Vogel checksum += word; 102313705f88SJack F Vogel } 102413705f88SJack F Vogel } 102513705f88SJack F Vogel } 102613705f88SJack F Vogel } 102713705f88SJack F Vogel 102813705f88SJack F Vogel checksum = (u16)IXGBE_EEPROM_SUM - checksum; 102913705f88SJack F Vogel 103013705f88SJack F Vogel return checksum; 103113705f88SJack F Vogel } 103213705f88SJack F Vogel 103313705f88SJack F Vogel /** 103413705f88SJack F Vogel * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum 103513705f88SJack F Vogel * @hw: pointer to hardware structure 103613705f88SJack F Vogel * @checksum_val: calculated checksum 103713705f88SJack F Vogel * 103813705f88SJack F Vogel * Performs checksum calculation and validates the EEPROM checksum. If the 103913705f88SJack F Vogel * caller does not need checksum_val, the value can be NULL. 104013705f88SJack F Vogel **/ 104113705f88SJack F Vogel s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, 104213705f88SJack F Vogel u16 *checksum_val) 104313705f88SJack F Vogel { 104413705f88SJack F Vogel s32 status; 104513705f88SJack F Vogel u16 checksum; 104613705f88SJack F Vogel u16 read_checksum = 0; 104713705f88SJack F Vogel 104813705f88SJack F Vogel /* 104913705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 105013705f88SJack F Vogel * not continue or we could be in for a very long wait while every 105113705f88SJack F Vogel * EEPROM read fails 105213705f88SJack F Vogel */ 105313705f88SJack F Vogel status = ixgbe_read_eeprom(hw, 0, &checksum); 105413705f88SJack F Vogel 105513705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 105613705f88SJack F Vogel checksum = ixgbe_calc_eeprom_checksum(hw); 105713705f88SJack F Vogel 105813705f88SJack F Vogel ixgbe_read_eeprom(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); 105913705f88SJack F Vogel 106013705f88SJack F Vogel /* 106113705f88SJack F Vogel * Verify read checksum from EEPROM is the same as 106213705f88SJack F Vogel * calculated checksum 106313705f88SJack F Vogel */ 106413705f88SJack F Vogel if (read_checksum != checksum) { 106513705f88SJack F Vogel status = IXGBE_ERR_EEPROM_CHECKSUM; 106613705f88SJack F Vogel } 106713705f88SJack F Vogel 106813705f88SJack F Vogel /* If the user cares, return the calculated checksum */ 106913705f88SJack F Vogel if (checksum_val) { 107013705f88SJack F Vogel *checksum_val = checksum; 107113705f88SJack F Vogel } 107213705f88SJack F Vogel } else { 107313705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 107413705f88SJack F Vogel } 107513705f88SJack F Vogel 107613705f88SJack F Vogel return status; 107713705f88SJack F Vogel } 107813705f88SJack F Vogel 107913705f88SJack F Vogel /** 108013705f88SJack F Vogel * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksm 108113705f88SJack F Vogel * @hw: pointer to hardware structure 108213705f88SJack F Vogel **/ 108313705f88SJack F Vogel s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) 108413705f88SJack F Vogel { 108513705f88SJack F Vogel s32 status; 108613705f88SJack F Vogel u16 checksum; 108713705f88SJack F Vogel 108813705f88SJack F Vogel /* 108913705f88SJack F Vogel * Read the first word from the EEPROM. If this times out or fails, do 109013705f88SJack F Vogel * not continue or we could be in for a very long wait while every 109113705f88SJack F Vogel * EEPROM read fails 109213705f88SJack F Vogel */ 109313705f88SJack F Vogel status = ixgbe_read_eeprom(hw, 0, &checksum); 109413705f88SJack F Vogel 109513705f88SJack F Vogel if (status == IXGBE_SUCCESS) { 109613705f88SJack F Vogel checksum = ixgbe_calc_eeprom_checksum(hw); 109713705f88SJack F Vogel status = ixgbe_write_eeprom(hw, IXGBE_EEPROM_CHECKSUM, 109813705f88SJack F Vogel checksum); 109913705f88SJack F Vogel } else { 110013705f88SJack F Vogel DEBUGOUT("EEPROM read failed\n"); 110113705f88SJack F Vogel } 110213705f88SJack F Vogel 110313705f88SJack F Vogel return status; 110413705f88SJack F Vogel } 110513705f88SJack F Vogel 110613705f88SJack F Vogel /** 110713705f88SJack F Vogel * ixgbe_validate_mac_addr - Validate MAC address 110813705f88SJack F Vogel * @mac_addr: pointer to MAC address. 110913705f88SJack F Vogel * 111013705f88SJack F Vogel * Tests a MAC address to ensure it is a valid Individual Address 111113705f88SJack F Vogel **/ 111213705f88SJack F Vogel s32 ixgbe_validate_mac_addr(u8 *mac_addr) 111313705f88SJack F Vogel { 111413705f88SJack F Vogel s32 status = IXGBE_SUCCESS; 111513705f88SJack F Vogel 111613705f88SJack F Vogel /* Make sure it is not a multicast address */ 111713705f88SJack F Vogel if (IXGBE_IS_MULTICAST(mac_addr)) { 111813705f88SJack F Vogel DEBUGOUT("MAC address is multicast\n"); 111913705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 112013705f88SJack F Vogel /* Not a broadcast address */ 112113705f88SJack F Vogel } else if (IXGBE_IS_BROADCAST(mac_addr)) { 112213705f88SJack F Vogel DEBUGOUT("MAC address is broadcast\n"); 112313705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 112413705f88SJack F Vogel /* Reject the zero address */ 112513705f88SJack F Vogel } else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && 112613705f88SJack F Vogel mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) { 112713705f88SJack F Vogel DEBUGOUT("MAC address is all zeros\n"); 112813705f88SJack F Vogel status = IXGBE_ERR_INVALID_MAC_ADDR; 112913705f88SJack F Vogel } 113013705f88SJack F Vogel return status; 113113705f88SJack F Vogel } 113213705f88SJack F Vogel 113313705f88SJack F Vogel /** 113413705f88SJack F Vogel * ixgbe_set_rar_generic - Set RX address register 113513705f88SJack F Vogel * @hw: pointer to hardware structure 113613705f88SJack F Vogel * @addr: Address to put into receive address register 113713705f88SJack F Vogel * @index: Receive address register to write 113813705f88SJack F Vogel * @vind: Vind to set RAR to 113913705f88SJack F Vogel * @enable_addr: set flag that address is active 114013705f88SJack F Vogel * 114113705f88SJack F Vogel * Puts an ethernet address into a receive address register. 114213705f88SJack F Vogel **/ 114313705f88SJack F Vogel s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind, 114413705f88SJack F Vogel u32 enable_addr) 114513705f88SJack F Vogel { 114613705f88SJack F Vogel u32 rar_low, rar_high; 114713705f88SJack F Vogel 114813705f88SJack F Vogel /* 114913705f88SJack F Vogel * HW expects these in little endian so we reverse the byte order from 115013705f88SJack F Vogel * network order (big endian) to little endian 115113705f88SJack F Vogel */ 115213705f88SJack F Vogel rar_low = ((u32)addr[0] | 115313705f88SJack F Vogel ((u32)addr[1] << 8) | 115413705f88SJack F Vogel ((u32)addr[2] << 16) | 115513705f88SJack F Vogel ((u32)addr[3] << 24)); 115613705f88SJack F Vogel 115713705f88SJack F Vogel rar_high = ((u32)addr[4] | 115813705f88SJack F Vogel ((u32)addr[5] << 8) | 115913705f88SJack F Vogel ((vind << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK)); 116013705f88SJack F Vogel 116113705f88SJack F Vogel if (enable_addr != 0) 116213705f88SJack F Vogel rar_high |= IXGBE_RAH_AV; 116313705f88SJack F Vogel 116413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); 116513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 116613705f88SJack F Vogel 116713705f88SJack F Vogel return IXGBE_SUCCESS; 116813705f88SJack F Vogel } 116913705f88SJack F Vogel 117013705f88SJack F Vogel /** 117113705f88SJack F Vogel * ixgbe_enable_rar - Enable RX address register 117213705f88SJack F Vogel * @hw: pointer to hardware structure 117313705f88SJack F Vogel * @index: index into the RAR table 117413705f88SJack F Vogel * 117513705f88SJack F Vogel * Enables the select receive address register. 117613705f88SJack F Vogel **/ 117713705f88SJack F Vogel static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index) 117813705f88SJack F Vogel { 117913705f88SJack F Vogel u32 rar_high; 118013705f88SJack F Vogel 118113705f88SJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 118213705f88SJack F Vogel rar_high |= IXGBE_RAH_AV; 118313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 118413705f88SJack F Vogel } 118513705f88SJack F Vogel 118613705f88SJack F Vogel /** 118713705f88SJack F Vogel * ixgbe_disable_rar - Disable RX address register 118813705f88SJack F Vogel * @hw: pointer to hardware structure 118913705f88SJack F Vogel * @index: index into the RAR table 119013705f88SJack F Vogel * 119113705f88SJack F Vogel * Disables the select receive address register. 119213705f88SJack F Vogel **/ 119313705f88SJack F Vogel static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index) 119413705f88SJack F Vogel { 119513705f88SJack F Vogel u32 rar_high; 119613705f88SJack F Vogel 119713705f88SJack F Vogel rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); 119813705f88SJack F Vogel rar_high &= (~IXGBE_RAH_AV); 119913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); 120013705f88SJack F Vogel } 120113705f88SJack F Vogel 120213705f88SJack F Vogel /** 120313705f88SJack F Vogel * ixgbe_init_rx_addrs_generic - Initializes receive address filters. 120413705f88SJack F Vogel * @hw: pointer to hardware structure 120513705f88SJack F Vogel * 120613705f88SJack F Vogel * Places the MAC address in receive address register 0 and clears the rest 120713705f88SJack F Vogel * of the receive addresss registers. Clears the multicast table. Assumes 120813705f88SJack F Vogel * the receiver is in reset when the routine is called. 120913705f88SJack F Vogel **/ 121013705f88SJack F Vogel s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) 121113705f88SJack F Vogel { 121213705f88SJack F Vogel u32 i; 121313705f88SJack F Vogel u32 rar_entries = ixgbe_get_num_rx_addrs(hw); 121413705f88SJack F Vogel 121513705f88SJack F Vogel /* 121613705f88SJack F Vogel * If the current mac address is valid, assume it is a software override 121713705f88SJack F Vogel * to the permanent address. 121813705f88SJack F Vogel * Otherwise, use the permanent address from the eeprom. 121913705f88SJack F Vogel */ 122013705f88SJack F Vogel if (ixgbe_validate_mac_addr(hw->mac.addr) == 122113705f88SJack F Vogel IXGBE_ERR_INVALID_MAC_ADDR) { 122213705f88SJack F Vogel /* Get the MAC address from the RAR0 for later reference */ 122313705f88SJack F Vogel ixgbe_get_mac_addr(hw, hw->mac.addr); 122413705f88SJack F Vogel 122513705f88SJack F Vogel DEBUGOUT3(" Keeping Current RAR0 Addr =%.2X %.2X %.2X ", 122613705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 122713705f88SJack F Vogel hw->mac.addr[2]); 122813705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 122913705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 123013705f88SJack F Vogel } else { 123113705f88SJack F Vogel /* Setup the receive address. */ 123213705f88SJack F Vogel DEBUGOUT("Overriding MAC Address in RAR[0]\n"); 123313705f88SJack F Vogel DEBUGOUT3(" New MAC Addr =%.2X %.2X %.2X ", 123413705f88SJack F Vogel hw->mac.addr[0], hw->mac.addr[1], 123513705f88SJack F Vogel hw->mac.addr[2]); 123613705f88SJack F Vogel DEBUGOUT3("%.2X %.2X %.2X\n", hw->mac.addr[3], 123713705f88SJack F Vogel hw->mac.addr[4], hw->mac.addr[5]); 123813705f88SJack F Vogel 123913705f88SJack F Vogel ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); 124013705f88SJack F Vogel } 124113705f88SJack F Vogel 124213705f88SJack F Vogel hw->addr_ctrl.rar_used_count = 1; 124313705f88SJack F Vogel 124413705f88SJack F Vogel /* Zero out the other receive addresses. */ 124513705f88SJack F Vogel DEBUGOUT("Clearing RAR[1-15]\n"); 124613705f88SJack F Vogel for (i = 1; i < rar_entries; i++) { 124713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); 124813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); 124913705f88SJack F Vogel } 125013705f88SJack F Vogel 125113705f88SJack F Vogel /* Clear the MTA */ 125213705f88SJack F Vogel hw->addr_ctrl.mc_addr_in_rar_count = 0; 125313705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 125413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 125513705f88SJack F Vogel 125613705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 125713705f88SJack F Vogel for (i = 0; i < IXGBE_MC_TBL_SIZE; i++) 125813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); 125913705f88SJack F Vogel 126013705f88SJack F Vogel return IXGBE_SUCCESS; 126113705f88SJack F Vogel } 126213705f88SJack F Vogel 126313705f88SJack F Vogel /** 126413705f88SJack F Vogel * ixgbe_mta_vector - Determines bit-vector in multicast table to set 126513705f88SJack F Vogel * @hw: pointer to hardware structure 126613705f88SJack F Vogel * @mc_addr: the multicast address 126713705f88SJack F Vogel * 126813705f88SJack F Vogel * Extracts the 12 bits, from a multicast address, to determine which 126913705f88SJack F Vogel * bit-vector to set in the multicast table. The hardware uses 12 bits, from 127013705f88SJack F Vogel * incoming rx multicast addresses, to determine the bit-vector to check in 127113705f88SJack F Vogel * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set 127213705f88SJack F Vogel * by the MO field of the MCSTCTRL. The MO field is set during initalization 127313705f88SJack F Vogel * to mc_filter_type. 127413705f88SJack F Vogel **/ 127513705f88SJack F Vogel static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) 127613705f88SJack F Vogel { 127713705f88SJack F Vogel u32 vector = 0; 127813705f88SJack F Vogel 127913705f88SJack F Vogel switch (hw->mac.mc_filter_type) { 128013705f88SJack F Vogel case 0: /* use bits [47:36] of the address */ 128113705f88SJack F Vogel vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); 128213705f88SJack F Vogel break; 128313705f88SJack F Vogel case 1: /* use bits [46:35] of the address */ 128413705f88SJack F Vogel vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); 128513705f88SJack F Vogel break; 128613705f88SJack F Vogel case 2: /* use bits [45:34] of the address */ 128713705f88SJack F Vogel vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); 128813705f88SJack F Vogel break; 128913705f88SJack F Vogel case 3: /* use bits [43:32] of the address */ 129013705f88SJack F Vogel vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); 129113705f88SJack F Vogel break; 129213705f88SJack F Vogel default: /* Invalid mc_filter_type */ 129313705f88SJack F Vogel DEBUGOUT("MC filter type param set incorrectly\n"); 129413705f88SJack F Vogel ASSERT(0); 129513705f88SJack F Vogel break; 129613705f88SJack F Vogel } 129713705f88SJack F Vogel 129813705f88SJack F Vogel /* vector can only be 12-bits or boundary will be exceeded */ 129913705f88SJack F Vogel vector &= 0xFFF; 130013705f88SJack F Vogel return vector; 130113705f88SJack F Vogel } 130213705f88SJack F Vogel 130313705f88SJack F Vogel /** 130413705f88SJack F Vogel * ixgbe_set_mta - Set bit-vector in multicast table 130513705f88SJack F Vogel * @hw: pointer to hardware structure 130613705f88SJack F Vogel * @hash_value: Multicast address hash value 130713705f88SJack F Vogel * 130813705f88SJack F Vogel * Sets the bit-vector in the multicast table. 130913705f88SJack F Vogel **/ 131013705f88SJack F Vogel void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) 131113705f88SJack F Vogel { 131213705f88SJack F Vogel u32 vector; 131313705f88SJack F Vogel u32 vector_bit; 131413705f88SJack F Vogel u32 vector_reg; 131513705f88SJack F Vogel u32 mta_reg; 131613705f88SJack F Vogel 131713705f88SJack F Vogel hw->addr_ctrl.mta_in_use++; 131813705f88SJack F Vogel 131913705f88SJack F Vogel vector = ixgbe_mta_vector(hw, mc_addr); 132013705f88SJack F Vogel DEBUGOUT1(" bit-vector = 0x%03X\n", vector); 132113705f88SJack F Vogel 132213705f88SJack F Vogel /* 132313705f88SJack F Vogel * The MTA is a register array of 128 32-bit registers. It is treated 132413705f88SJack F Vogel * like an array of 4096 bits. We want to set bit 132513705f88SJack F Vogel * BitArray[vector_value]. So we figure out what register the bit is 132613705f88SJack F Vogel * in, read it, OR in the new bit, then write back the new value. The 132713705f88SJack F Vogel * register is determined by the upper 7 bits of the vector value and 132813705f88SJack F Vogel * the bit within that register are determined by the lower 5 bits of 132913705f88SJack F Vogel * the value. 133013705f88SJack F Vogel */ 133113705f88SJack F Vogel vector_reg = (vector >> 5) & 0x7F; 133213705f88SJack F Vogel vector_bit = vector & 0x1F; 133313705f88SJack F Vogel mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg)); 133413705f88SJack F Vogel mta_reg |= (1 << vector_bit); 133513705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); 133613705f88SJack F Vogel } 133713705f88SJack F Vogel 133813705f88SJack F Vogel /** 133913705f88SJack F Vogel * ixgbe_add_mc_addr - Adds a multicast address. 134013705f88SJack F Vogel * @hw: pointer to hardware structure 134113705f88SJack F Vogel * @mc_addr: new multicast address 134213705f88SJack F Vogel * 134313705f88SJack F Vogel * Adds it to unused receive address register or to the multicast table. 134413705f88SJack F Vogel **/ 134513705f88SJack F Vogel void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) 134613705f88SJack F Vogel { 134713705f88SJack F Vogel u32 rar_entries = ixgbe_get_num_rx_addrs(hw); 134813705f88SJack F Vogel 134913705f88SJack F Vogel DEBUGOUT6(" MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n", 135013705f88SJack F Vogel mc_addr[0], mc_addr[1], mc_addr[2], 135113705f88SJack F Vogel mc_addr[3], mc_addr[4], mc_addr[5]); 135213705f88SJack F Vogel 135313705f88SJack F Vogel /* 135413705f88SJack F Vogel * Place this multicast address in the RAR if there is room, 135513705f88SJack F Vogel * else put it in the MTA 135613705f88SJack F Vogel */ 135713705f88SJack F Vogel if (hw->addr_ctrl.rar_used_count < rar_entries) { 135813705f88SJack F Vogel ixgbe_set_rar(hw, hw->addr_ctrl.rar_used_count, 135913705f88SJack F Vogel mc_addr, 0, IXGBE_RAH_AV); 136013705f88SJack F Vogel DEBUGOUT1("Added a multicast address to RAR[%d]\n", 136113705f88SJack F Vogel hw->addr_ctrl.rar_used_count); 136213705f88SJack F Vogel hw->addr_ctrl.rar_used_count++; 136313705f88SJack F Vogel hw->addr_ctrl.mc_addr_in_rar_count++; 136413705f88SJack F Vogel } else { 136513705f88SJack F Vogel ixgbe_set_mta(hw, mc_addr); 136613705f88SJack F Vogel } 136713705f88SJack F Vogel 136813705f88SJack F Vogel DEBUGOUT("ixgbe_add_mc_addr Complete\n"); 136913705f88SJack F Vogel } 137013705f88SJack F Vogel 137113705f88SJack F Vogel /** 137213705f88SJack F Vogel * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses 137313705f88SJack F Vogel * @hw: pointer to hardware structure 137413705f88SJack F Vogel * @mc_addr_list: the list of new multicast addresses 137513705f88SJack F Vogel * @mc_addr_count: number of addresses 137613705f88SJack F Vogel * @pad: number of bytes between addresses in the list 137713705f88SJack F Vogel * 137813705f88SJack F Vogel * The given list replaces any existing list. Clears the MC addrs from receive 137913705f88SJack F Vogel * address registers and the multicast table. Uses unsed receive address 138013705f88SJack F Vogel * registers for the first multicast addresses, and hashes the rest into the 138113705f88SJack F Vogel * multicast table. 138213705f88SJack F Vogel **/ 138313705f88SJack F Vogel s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, 138413705f88SJack F Vogel u32 mc_addr_count, u32 pad) 138513705f88SJack F Vogel { 138613705f88SJack F Vogel u32 i; 138713705f88SJack F Vogel u32 rar_entries = ixgbe_get_num_rx_addrs(hw); 138813705f88SJack F Vogel 138913705f88SJack F Vogel /* 139013705f88SJack F Vogel * Set the new number of MC addresses that we are being requested to 139113705f88SJack F Vogel * use. 139213705f88SJack F Vogel */ 139313705f88SJack F Vogel hw->addr_ctrl.num_mc_addrs = mc_addr_count; 139413705f88SJack F Vogel hw->addr_ctrl.rar_used_count -= hw->addr_ctrl.mc_addr_in_rar_count; 139513705f88SJack F Vogel hw->addr_ctrl.mc_addr_in_rar_count = 0; 139613705f88SJack F Vogel hw->addr_ctrl.mta_in_use = 0; 139713705f88SJack F Vogel 139813705f88SJack F Vogel /* Zero out the other receive addresses. */ 139913705f88SJack F Vogel DEBUGOUT("Clearing RAR[1-15]\n"); 140013705f88SJack F Vogel for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) { 140113705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); 140213705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); 140313705f88SJack F Vogel } 140413705f88SJack F Vogel 140513705f88SJack F Vogel /* Clear the MTA */ 140613705f88SJack F Vogel DEBUGOUT(" Clearing MTA\n"); 140713705f88SJack F Vogel for (i = 0; i < IXGBE_MC_TBL_SIZE; i++) 140813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); 140913705f88SJack F Vogel 141013705f88SJack F Vogel /* Add the new addresses */ 141113705f88SJack F Vogel for (i = 0; i < mc_addr_count; i++) { 141213705f88SJack F Vogel DEBUGOUT(" Adding the multicast addresses:\n"); 141313705f88SJack F Vogel ixgbe_add_mc_addr(hw, mc_addr_list + 141413705f88SJack F Vogel (i * (IXGBE_ETH_LENGTH_OF_ADDRESS + pad))); 141513705f88SJack F Vogel } 141613705f88SJack F Vogel 141713705f88SJack F Vogel /* Enable mta */ 141813705f88SJack F Vogel if (hw->addr_ctrl.mta_in_use > 0) 141913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, 142013705f88SJack F Vogel IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); 142113705f88SJack F Vogel 142213705f88SJack F Vogel DEBUGOUT("ixgbe_update_mc_addr_list_generic Complete\n"); 142313705f88SJack F Vogel return IXGBE_SUCCESS; 142413705f88SJack F Vogel } 142513705f88SJack F Vogel 142613705f88SJack F Vogel /** 142713705f88SJack F Vogel * ixgbe_enable_mc_generic - Enable multicast address in RAR 142813705f88SJack F Vogel * @hw: pointer to hardware structure 142913705f88SJack F Vogel * 143013705f88SJack F Vogel * Enables multicast address in RAR and the use of the multicast hash table. 143113705f88SJack F Vogel **/ 143213705f88SJack F Vogel s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) 143313705f88SJack F Vogel { 143413705f88SJack F Vogel u32 i; 143513705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 143613705f88SJack F Vogel 143713705f88SJack F Vogel if (a->mc_addr_in_rar_count > 0) 143813705f88SJack F Vogel for (i = (a->rar_used_count - a->mc_addr_in_rar_count); 143913705f88SJack F Vogel i < a->rar_used_count; i++) 144013705f88SJack F Vogel ixgbe_enable_rar(hw, i); 144113705f88SJack F Vogel 144213705f88SJack F Vogel if (a->mta_in_use > 0) 144313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | 144413705f88SJack F Vogel hw->mac.mc_filter_type); 144513705f88SJack F Vogel 144613705f88SJack F Vogel return IXGBE_SUCCESS; 144713705f88SJack F Vogel } 144813705f88SJack F Vogel 144913705f88SJack F Vogel /** 145013705f88SJack F Vogel * ixgbe_disable_mc_generic - Disable mutlicast address in RAR 145113705f88SJack F Vogel * @hw: pointer to hardware structure 145213705f88SJack F Vogel * 145313705f88SJack F Vogel * Disables multicast address in RAR and the use of the multicast hash table. 145413705f88SJack F Vogel **/ 145513705f88SJack F Vogel s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) 145613705f88SJack F Vogel { 145713705f88SJack F Vogel u32 i; 145813705f88SJack F Vogel struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; 145913705f88SJack F Vogel 146013705f88SJack F Vogel if (a->mc_addr_in_rar_count > 0) 146113705f88SJack F Vogel for (i = (a->rar_used_count - a->mc_addr_in_rar_count); 146213705f88SJack F Vogel i < a->rar_used_count; i++) 146313705f88SJack F Vogel ixgbe_disable_rar(hw, i); 146413705f88SJack F Vogel 146513705f88SJack F Vogel if (a->mta_in_use > 0) 146613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); 146713705f88SJack F Vogel 146813705f88SJack F Vogel return IXGBE_SUCCESS; 146913705f88SJack F Vogel } 147013705f88SJack F Vogel 147113705f88SJack F Vogel /** 147213705f88SJack F Vogel * ixgbe_clear_vfta_generic - Clear VLAN filter table 147313705f88SJack F Vogel * @hw: pointer to hardware structure 147413705f88SJack F Vogel * 147513705f88SJack F Vogel * Clears the VLAN filer table, and the VMDq index associated with the filter 147613705f88SJack F Vogel **/ 147713705f88SJack F Vogel s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) 147813705f88SJack F Vogel { 147913705f88SJack F Vogel u32 offset; 148013705f88SJack F Vogel u32 vlanbyte; 148113705f88SJack F Vogel 148213705f88SJack F Vogel for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++) 148313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); 148413705f88SJack F Vogel 148513705f88SJack F Vogel for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) 148613705f88SJack F Vogel for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++) 148713705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), 148813705f88SJack F Vogel 0); 148913705f88SJack F Vogel 149013705f88SJack F Vogel return IXGBE_SUCCESS; 149113705f88SJack F Vogel } 149213705f88SJack F Vogel 149313705f88SJack F Vogel /** 149413705f88SJack F Vogel * ixgbe_set_vfta_generic - Set VLAN filter table 149513705f88SJack F Vogel * @hw: pointer to hardware structure 149613705f88SJack F Vogel * @vlan: VLAN id to write to VLAN filter 149713705f88SJack F Vogel * @vind: VMDq output index that maps queue to VLAN id in VFTA 149813705f88SJack F Vogel * @vlan_on: boolean flag to turn on/off VLAN in VFTA 149913705f88SJack F Vogel * 150013705f88SJack F Vogel * Turn on/off specified VLAN in the VLAN filter table. 150113705f88SJack F Vogel **/ 150213705f88SJack F Vogel s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, 150313705f88SJack F Vogel bool vlan_on) 150413705f88SJack F Vogel { 150513705f88SJack F Vogel u32 VftaIndex; 150613705f88SJack F Vogel u32 BitOffset; 150713705f88SJack F Vogel u32 VftaReg; 150813705f88SJack F Vogel u32 VftaByte; 150913705f88SJack F Vogel 151013705f88SJack F Vogel /* Determine 32-bit word position in array */ 151113705f88SJack F Vogel VftaIndex = (vlan >> 5) & 0x7F; /* upper seven bits */ 151213705f88SJack F Vogel 151313705f88SJack F Vogel /* Determine the location of the (VMD) queue index */ 151413705f88SJack F Vogel VftaByte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */ 151513705f88SJack F Vogel BitOffset = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */ 151613705f88SJack F Vogel 151713705f88SJack F Vogel /* Set the nibble for VMD queue index */ 151813705f88SJack F Vogel VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex)); 151913705f88SJack F Vogel VftaReg &= (~(0x0F << BitOffset)); 152013705f88SJack F Vogel VftaReg |= (vind << BitOffset); 152113705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex), VftaReg); 152213705f88SJack F Vogel 152313705f88SJack F Vogel /* Determine the location of the bit for this VLAN id */ 152413705f88SJack F Vogel BitOffset = vlan & 0x1F; /* lower five bits */ 152513705f88SJack F Vogel 152613705f88SJack F Vogel VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTA(VftaIndex)); 152713705f88SJack F Vogel if (vlan_on) 152813705f88SJack F Vogel /* Turn on this VLAN id */ 152913705f88SJack F Vogel VftaReg |= (1 << BitOffset); 153013705f88SJack F Vogel else 153113705f88SJack F Vogel /* Turn off this VLAN id */ 153213705f88SJack F Vogel VftaReg &= ~(1 << BitOffset); 153313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_VFTA(VftaIndex), VftaReg); 153413705f88SJack F Vogel 153513705f88SJack F Vogel return IXGBE_SUCCESS; 153613705f88SJack F Vogel } 153713705f88SJack F Vogel 153813705f88SJack F Vogel /** 153913705f88SJack F Vogel * ixgbe_setup_fc_generic - Configure flow control settings 154013705f88SJack F Vogel * @hw: pointer to hardware structure 154113705f88SJack F Vogel * @packetbuf_num: packet buffer number (0-7) 154213705f88SJack F Vogel * 154313705f88SJack F Vogel * Configures the flow control settings based on SW configuration. 154413705f88SJack F Vogel * This function is used for 802.3x flow control configuration only. 154513705f88SJack F Vogel **/ 154613705f88SJack F Vogel s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num) 154713705f88SJack F Vogel { 154813705f88SJack F Vogel u32 frctl_reg; 154913705f88SJack F Vogel u32 rmcs_reg; 155013705f88SJack F Vogel 155113705f88SJack F Vogel if (packetbuf_num < 0 || packetbuf_num > 7) { 155213705f88SJack F Vogel DEBUGOUT1("Invalid packet buffer number [%d], expected range is" 155313705f88SJack F Vogel " 0-7\n", packetbuf_num); 155413705f88SJack F Vogel ASSERT(0); 155513705f88SJack F Vogel } 155613705f88SJack F Vogel 155713705f88SJack F Vogel frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); 155813705f88SJack F Vogel frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); 155913705f88SJack F Vogel 156013705f88SJack F Vogel rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); 156113705f88SJack F Vogel rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); 156213705f88SJack F Vogel 156313705f88SJack F Vogel /* 156413705f88SJack F Vogel * We want to save off the original Flow Control configuration just in 156513705f88SJack F Vogel * case we get disconnected and then reconnected into a different hub 156613705f88SJack F Vogel * or switch with different Flow Control capabilities. 156713705f88SJack F Vogel */ 156813705f88SJack F Vogel hw->fc.type = hw->fc.original_type; 156913705f88SJack F Vogel 157013705f88SJack F Vogel /* 157113705f88SJack F Vogel * The possible values of the "flow_control" parameter are: 157213705f88SJack F Vogel * 0: Flow control is completely disabled 157313705f88SJack F Vogel * 1: Rx flow control is enabled (we can receive pause frames but not 157413705f88SJack F Vogel * send pause frames). 157513705f88SJack F Vogel * 2: Tx flow control is enabled (we can send pause frames but we do not 157613705f88SJack F Vogel * support receiving pause frames) 157713705f88SJack F Vogel * 3: Both Rx and TX flow control (symmetric) are enabled. 157813705f88SJack F Vogel * other: Invalid. 157913705f88SJack F Vogel */ 158013705f88SJack F Vogel switch (hw->fc.type) { 158113705f88SJack F Vogel case ixgbe_fc_none: 158213705f88SJack F Vogel break; 158313705f88SJack F Vogel case ixgbe_fc_rx_pause: 158413705f88SJack F Vogel /* 158513705f88SJack F Vogel * RX Flow control is enabled, 158613705f88SJack F Vogel * and TX Flow control is disabled. 158713705f88SJack F Vogel */ 158813705f88SJack F Vogel frctl_reg |= IXGBE_FCTRL_RFCE; 158913705f88SJack F Vogel break; 159013705f88SJack F Vogel case ixgbe_fc_tx_pause: 159113705f88SJack F Vogel /* 159213705f88SJack F Vogel * TX Flow control is enabled, and RX Flow control is disabled, 159313705f88SJack F Vogel * by a software over-ride. 159413705f88SJack F Vogel */ 159513705f88SJack F Vogel rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; 159613705f88SJack F Vogel break; 159713705f88SJack F Vogel case ixgbe_fc_full: 159813705f88SJack F Vogel /* 159913705f88SJack F Vogel * Flow control (both RX and TX) is enabled by a software 160013705f88SJack F Vogel * over-ride. 160113705f88SJack F Vogel */ 160213705f88SJack F Vogel frctl_reg |= IXGBE_FCTRL_RFCE; 160313705f88SJack F Vogel rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; 160413705f88SJack F Vogel break; 160513705f88SJack F Vogel default: 160613705f88SJack F Vogel /* We should never get here. The value should be 0-3. */ 160713705f88SJack F Vogel DEBUGOUT("Flow control param set incorrectly\n"); 160813705f88SJack F Vogel ASSERT(0); 160913705f88SJack F Vogel break; 161013705f88SJack F Vogel } 161113705f88SJack F Vogel 161213705f88SJack F Vogel /* Enable 802.3x based flow control settings. */ 161313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg); 161413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); 161513705f88SJack F Vogel 161613705f88SJack F Vogel /* 161713705f88SJack F Vogel * We need to set up the Receive Threshold high and low water 161813705f88SJack F Vogel * marks as well as (optionally) enabling the transmission of 161913705f88SJack F Vogel * XON frames. 162013705f88SJack F Vogel */ 162113705f88SJack F Vogel if (hw->fc.type & ixgbe_fc_tx_pause) { 162213705f88SJack F Vogel if (hw->fc.send_xon) { 162313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), 162413705f88SJack F Vogel (hw->fc.low_water | IXGBE_FCRTL_XONE)); 162513705f88SJack F Vogel } else { 162613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), 162713705f88SJack F Vogel hw->fc.low_water); 162813705f88SJack F Vogel } 162913705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), 163013705f88SJack F Vogel (hw->fc.high_water)|IXGBE_FCRTH_FCEN); 163113705f88SJack F Vogel } 163213705f88SJack F Vogel 163313705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time); 163413705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); 163513705f88SJack F Vogel 163613705f88SJack F Vogel return IXGBE_SUCCESS; 163713705f88SJack F Vogel } 163813705f88SJack F Vogel 163913705f88SJack F Vogel /** 164013705f88SJack F Vogel * ixgbe_disable_pcie_master - Disable PCI-express master access 164113705f88SJack F Vogel * @hw: pointer to hardware structure 164213705f88SJack F Vogel * 164313705f88SJack F Vogel * Disables PCI-Express master access and verifies there are no pending 164413705f88SJack F Vogel * requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable 164513705f88SJack F Vogel * bit hasn't caused the master requests to be disabled, else IXGBE_SUCCESS 164613705f88SJack F Vogel * is returned signifying master requests disabled. 164713705f88SJack F Vogel **/ 164813705f88SJack F Vogel s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) 164913705f88SJack F Vogel { 165013705f88SJack F Vogel u32 ctrl; 165113705f88SJack F Vogel s32 i; 165213705f88SJack F Vogel s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING; 165313705f88SJack F Vogel 165413705f88SJack F Vogel ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); 165513705f88SJack F Vogel ctrl |= IXGBE_CTRL_GIO_DIS; 165613705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); 165713705f88SJack F Vogel 165813705f88SJack F Vogel for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 165913705f88SJack F Vogel if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) { 166013705f88SJack F Vogel status = IXGBE_SUCCESS; 166113705f88SJack F Vogel break; 166213705f88SJack F Vogel } 166313705f88SJack F Vogel usec_delay(100); 166413705f88SJack F Vogel } 166513705f88SJack F Vogel 166613705f88SJack F Vogel return status; 166713705f88SJack F Vogel } 166813705f88SJack F Vogel 166913705f88SJack F Vogel 167013705f88SJack F Vogel /** 167113705f88SJack F Vogel * ixgbe_acquire_swfw_sync - Aquire SWFW semaphore 167213705f88SJack F Vogel * @hw: pointer to hardware structure 167313705f88SJack F Vogel * @mask: Mask to specify wich semaphore to acquire 167413705f88SJack F Vogel * 167513705f88SJack F Vogel * Aquires the SWFW semaphore throught the GSSR register for the specified 167613705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 167713705f88SJack F Vogel **/ 167813705f88SJack F Vogel s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) 167913705f88SJack F Vogel { 168013705f88SJack F Vogel u32 gssr; 168113705f88SJack F Vogel u32 swmask = mask; 168213705f88SJack F Vogel u32 fwmask = mask << 5; 168313705f88SJack F Vogel s32 timeout = 200; 168413705f88SJack F Vogel 168513705f88SJack F Vogel while (timeout) { 168613705f88SJack F Vogel if (ixgbe_get_eeprom_semaphore(hw)) 168713705f88SJack F Vogel return -IXGBE_ERR_SWFW_SYNC; 168813705f88SJack F Vogel 168913705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 169013705f88SJack F Vogel if (!(gssr & (fwmask | swmask))) 169113705f88SJack F Vogel break; 169213705f88SJack F Vogel 169313705f88SJack F Vogel /* 169413705f88SJack F Vogel * Firmware currently using resource (fwmask) or other software 169513705f88SJack F Vogel * thread currently using resource (swmask) 169613705f88SJack F Vogel */ 169713705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 169813705f88SJack F Vogel msec_delay(5); 169913705f88SJack F Vogel timeout--; 170013705f88SJack F Vogel } 170113705f88SJack F Vogel 170213705f88SJack F Vogel if (!timeout) { 170313705f88SJack F Vogel DEBUGOUT("Driver can't access resource, GSSR timeout.\n"); 170413705f88SJack F Vogel return -IXGBE_ERR_SWFW_SYNC; 170513705f88SJack F Vogel } 170613705f88SJack F Vogel 170713705f88SJack F Vogel gssr |= swmask; 170813705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 170913705f88SJack F Vogel 171013705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 171113705f88SJack F Vogel return IXGBE_SUCCESS; 171213705f88SJack F Vogel } 171313705f88SJack F Vogel 171413705f88SJack F Vogel /** 171513705f88SJack F Vogel * ixgbe_release_swfw_sync - Release SWFW semaphore 171613705f88SJack F Vogel * @hw: pointer to hardware structure 171713705f88SJack F Vogel * @mask: Mask to specify wich semaphore to release 171813705f88SJack F Vogel * 171913705f88SJack F Vogel * Releases the SWFW semaphore throught the GSSR register for the specified 172013705f88SJack F Vogel * function (CSR, PHY0, PHY1, EEPROM, Flash) 172113705f88SJack F Vogel **/ 172213705f88SJack F Vogel void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) 172313705f88SJack F Vogel { 172413705f88SJack F Vogel u32 gssr; 172513705f88SJack F Vogel u32 swmask = mask; 172613705f88SJack F Vogel 172713705f88SJack F Vogel ixgbe_get_eeprom_semaphore(hw); 172813705f88SJack F Vogel 172913705f88SJack F Vogel gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 173013705f88SJack F Vogel gssr &= ~swmask; 173113705f88SJack F Vogel IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); 173213705f88SJack F Vogel 173313705f88SJack F Vogel ixgbe_release_eeprom_semaphore(hw); 173413705f88SJack F Vogel } 173513705f88SJack F Vogel 1736