LCOV - code coverage report
Current view: top level - dev/pci - ixgbe_x540.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 297 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 20 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ixgbe_x540.c,v 1.9 2016/11/17 21:08:27 mikeb Exp $    */
       2             : 
       3             : /******************************************************************************
       4             : 
       5             :   Copyright (c) 2001-2015, Intel Corporation
       6             :   All rights reserved.
       7             : 
       8             :   Redistribution and use in source and binary forms, with or without
       9             :   modification, are permitted provided that the following conditions are met:
      10             : 
      11             :    1. Redistributions of source code must retain the above copyright notice,
      12             :       this list of conditions and the following disclaimer.
      13             : 
      14             :    2. Redistributions in binary form must reproduce the above copyright
      15             :       notice, this list of conditions and the following disclaimer in the
      16             :       documentation and/or other materials provided with the distribution.
      17             : 
      18             :    3. Neither the name of the Intel Corporation nor the names of its
      19             :       contributors may be used to endorse or promote products derived from
      20             :       this software without specific prior written permission.
      21             : 
      22             :   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      23             :   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      24             :   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      25             :   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      26             :   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      27             :   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      28             :   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      29             :   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      30             :   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      31             :   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      32             :   POSSIBILITY OF SUCH DAMAGE.
      33             : 
      34             : ******************************************************************************/
      35             : /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x540.c 295093 2016-01-31 15:14:23Z smh $*/
      36             : 
      37             : #include <dev/pci/ixgbe.h>
      38             : #include <dev/pci/ixgbe_type.h>
      39             : 
      40             : #define IXGBE_X540_MAX_TX_QUEUES        128
      41             : #define IXGBE_X540_MAX_RX_QUEUES        128
      42             : #define IXGBE_X540_RAR_ENTRIES          128
      43             : #define IXGBE_X540_MC_TBL_SIZE          128
      44             : #define IXGBE_X540_VFT_TBL_SIZE         128
      45             : #define IXGBE_X540_RX_PB_SIZE           384
      46             : 
      47             : int32_t ixgbe_update_flash_X540(struct ixgbe_hw *hw);
      48             : int32_t ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
      49             : int32_t ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw);
      50             : void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw);
      51             : 
      52             : enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw);
      53             : int32_t ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed,
      54             :                                   bool link_up_wait_to_complete);
      55             : int32_t ixgbe_reset_hw_X540(struct ixgbe_hw *hw);
      56             : int32_t ixgbe_start_hw_X540(struct ixgbe_hw *hw);
      57             : uint32_t ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw);
      58             : 
      59             : int32_t ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw);
      60             : int32_t ixgbe_read_eerd_X540(struct ixgbe_hw *hw, uint16_t offset, uint16_t *data);
      61             : int32_t ixgbe_write_eewr_X540(struct ixgbe_hw *hw, uint16_t offset, uint16_t data);
      62             : int32_t ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw);
      63             : int32_t ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, uint16_t *checksum_val);
      64             : int32_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw);
      65             : 
      66             : int32_t ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask);
      67             : void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask);
      68             : 
      69             : int32_t ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, uint32_t index);
      70             : int32_t ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, uint32_t index);
      71             : 
      72             : /**
      73             :  *  ixgbe_init_ops_X540 - Inits func ptrs and MAC type
      74             :  *  @hw: pointer to hardware structure
      75             :  *
      76             :  *  Initialize the function pointers and assign the MAC type for X540.
      77             :  *  Does not touch the hardware.
      78             :  **/
      79           0 : int32_t ixgbe_init_ops_X540(struct ixgbe_hw *hw)
      80             : {
      81           0 :         struct ixgbe_mac_info *mac = &hw->mac;
      82           0 :         struct ixgbe_phy_info *phy = &hw->phy;
      83           0 :         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
      84             :         int32_t ret_val;
      85             : 
      86             :         DEBUGFUNC("ixgbe_init_ops_X540");
      87             : 
      88           0 :         ret_val = ixgbe_init_phy_ops_generic(hw);
      89           0 :         ret_val = ixgbe_init_ops_generic(hw);
      90             : 
      91             :         /* EEPROM */
      92           0 :         eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
      93           0 :         eeprom->ops.read = ixgbe_read_eerd_X540;
      94           0 :         eeprom->ops.write = ixgbe_write_eewr_X540;
      95           0 :         eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X540;
      96           0 :         eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X540;
      97           0 :         eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X540;
      98             : 
      99             :         /* PHY */
     100           0 :         phy->ops.init = ixgbe_init_phy_ops_generic;
     101           0 :         phy->ops.reset = NULL;
     102           0 :         phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
     103             : 
     104             :         /* MAC */
     105           0 :         mac->ops.reset_hw = ixgbe_reset_hw_X540;
     106           0 :         mac->ops.get_media_type = ixgbe_get_media_type_X540;
     107           0 :         mac->ops.get_supported_physical_layer =
     108             :                                     ixgbe_get_supported_physical_layer_X540;
     109           0 :         mac->ops.read_analog_reg8 = NULL;
     110           0 :         mac->ops.write_analog_reg8 = NULL;
     111           0 :         mac->ops.start_hw = ixgbe_start_hw_X540;
     112           0 :         mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540;
     113           0 :         mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540;
     114           0 :         mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic;
     115           0 :         mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic;
     116             : 
     117             :         /* RAR, Multicast, VLAN */
     118           0 :         mac->ops.set_vmdq = ixgbe_set_vmdq_generic;
     119           0 :         mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic;
     120           0 :         mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic;
     121           0 :         mac->rar_highwater = 1;
     122           0 :         mac->ops.set_vfta = ixgbe_set_vfta_generic;
     123           0 :         mac->ops.clear_vfta = ixgbe_clear_vfta_generic;
     124           0 :         mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic;
     125             : 
     126             :         /* Link */
     127           0 :         mac->ops.get_link_capabilities =
     128             :                                 ixgbe_get_copper_link_capabilities_generic;
     129           0 :         mac->ops.setup_link = ixgbe_setup_mac_link_X540;
     130           0 :         mac->ops.check_link = ixgbe_check_mac_link_generic;
     131             : 
     132           0 :         mac->mcft_size               = IXGBE_X540_MC_TBL_SIZE;
     133           0 :         mac->vft_size                = IXGBE_X540_VFT_TBL_SIZE;
     134           0 :         mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES;
     135           0 :         mac->rx_pb_size              = IXGBE_X540_RX_PB_SIZE;
     136           0 :         mac->max_rx_queues   = IXGBE_X540_MAX_RX_QUEUES;
     137           0 :         mac->max_tx_queues   = IXGBE_X540_MAX_TX_QUEUES;
     138           0 :         mac->max_msix_vectors        = 0 /*ixgbe_get_pcie_msix_count_generic(hw)*/;
     139             : 
     140           0 :         hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
     141             : 
     142             :         /* LEDs */
     143           0 :         mac->ops.blink_led_start = ixgbe_blink_led_start_X540;
     144           0 :         mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540;
     145             : 
     146           0 :         return ret_val;
     147             : }
     148             : 
     149             : /**
     150             :  *  ixgbe_get_media_type_X540 - Get media type
     151             :  *  @hw: pointer to hardware structure
     152             :  *
     153             :  *  Returns the media type (fiber, copper, backplane)
     154             :  **/
     155           0 : enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
     156             : {
     157           0 :         return ixgbe_media_type_copper;
     158             : }
     159             : 
     160             : /**
     161             :  *  ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities
     162             :  *  @hw: pointer to hardware structure
     163             :  *  @speed: new link speed
     164             :  *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
     165             :  **/
     166           0 : int32_t ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
     167             :                                   ixgbe_link_speed speed,
     168             :                                   bool autoneg_wait_to_complete)
     169             : {
     170             :         DEBUGFUNC("ixgbe_setup_mac_link_X540");
     171           0 :         return hw->phy.ops.setup_link_speed(hw, speed,
     172             :                                             autoneg_wait_to_complete);
     173             : }
     174             : 
     175             : /**
     176             :  *  ixgbe_reset_hw_X540 - Perform hardware reset
     177             :  *  @hw: pointer to hardware structure
     178             :  *
     179             :  *  Resets the hardware by resetting the transmit and receive units, masks
     180             :  *  and clears all interrupts, and perform a reset.
     181             :  **/
     182           0 : int32_t ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
     183             : {
     184             :         int32_t status;
     185             :         uint32_t ctrl, i;
     186             : 
     187             :         DEBUGFUNC("ixgbe_reset_hw_X540");
     188             : 
     189             :         /* Call adapter stop to disable tx/rx and clear interrupts */
     190           0 :         status = hw->mac.ops.stop_adapter(hw);
     191           0 :         if (status != IXGBE_SUCCESS)
     192             :                 goto reset_hw_out;
     193             : 
     194             :         /* flush pending Tx transactions */
     195           0 :         ixgbe_clear_tx_pending(hw);
     196             : 
     197             : mac_reset_top:
     198             :         ctrl = IXGBE_CTRL_RST;
     199           0 :         ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
     200           0 :         IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
     201           0 :         IXGBE_WRITE_FLUSH(hw);
     202             : 
     203             :         /* Poll for reset bit to self-clear indicating reset is complete */
     204           0 :         for (i = 0; i < 10; i++) {
     205           0 :                 usec_delay(1);
     206           0 :                 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
     207           0 :                 if (!(ctrl & IXGBE_CTRL_RST_MASK))
     208             :                         break;
     209             :         }
     210             : 
     211           0 :         if (ctrl & IXGBE_CTRL_RST_MASK) {
     212             :                 status = IXGBE_ERR_RESET_FAILED;
     213             :                 DEBUGOUT("Reset polling failed to complete.\n");
     214           0 :         }
     215           0 :         msec_delay(100);
     216             : 
     217             :         /*
     218             :          * Double resets are required for recovery from certain error
     219             :          * conditions.  Between resets, it is necessary to stall to allow time
     220             :          * for any pending HW events to complete.
     221             :          */
     222           0 :         if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
     223           0 :                 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
     224           0 :                 goto mac_reset_top;
     225             :         }
     226             : 
     227             :         /* Set the Rx packet buffer size. */
     228           0 :         IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT);
     229             : 
     230             :         /* Store the permanent mac address */
     231           0 :         hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
     232             : 
     233             :         /*
     234             :          * Store MAC address from RAR0, clear receive address registers, and
     235             :          * clear the multicast table.  Also reset num_rar_entries to 128,
     236             :          * since we modify this value when programming the SAN MAC address.
     237             :          */
     238           0 :         hw->mac.num_rar_entries = 128;
     239           0 :         hw->mac.ops.init_rx_addrs(hw);
     240             : 
     241             : reset_hw_out:
     242           0 :         return status;
     243             : }
     244             : 
     245             : /**
     246             :  *  ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
     247             :  *  @hw: pointer to hardware structure
     248             :  *
     249             :  *  Starts the hardware using the generic start_hw function
     250             :  *  and the generation start_hw function.
     251             :  *  Then performs revision-specific operations, if any.
     252             :  **/
     253           0 : int32_t ixgbe_start_hw_X540(struct ixgbe_hw *hw)
     254             : {
     255             :         int32_t ret_val = IXGBE_SUCCESS;
     256             : 
     257             :         DEBUGFUNC("ixgbe_start_hw_X540");
     258             : 
     259           0 :         ret_val = ixgbe_start_hw_generic(hw);
     260           0 :         if (ret_val != IXGBE_SUCCESS)
     261             :                 goto out;
     262             : 
     263           0 :         ret_val = ixgbe_start_hw_gen2(hw);
     264             : 
     265             : out:
     266           0 :         return ret_val;
     267             : }
     268             : 
     269             : /**
     270             :  *  ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
     271             :  *  @hw: pointer to hardware structure
     272             :  *
     273             :  *  Determines physical layer capabilities of the current configuration.
     274             :  **/
     275           0 : uint32_t ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
     276             : {
     277             :         uint32_t physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
     278           0 :         uint16_t ext_ability = 0;
     279             : 
     280             :         DEBUGFUNC("ixgbe_get_supported_physical_layer_X540");
     281             : 
     282           0 :         hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
     283             :         IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
     284           0 :         if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
     285           0 :                 physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
     286           0 :         if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
     287           0 :                 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
     288           0 :         if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
     289           0 :                 physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
     290             : 
     291           0 :         return physical_layer;
     292           0 : }
     293             : 
     294             : /**
     295             :  *  ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
     296             :  *  @hw: pointer to hardware structure
     297             :  *
     298             :  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
     299             :  *  ixgbe_hw struct in order to set up EEPROM access.
     300             :  **/
     301           0 : int32_t ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
     302             : {
     303           0 :         struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
     304             :         uint32_t eec;
     305             :         uint16_t eeprom_size;
     306             : 
     307             :         DEBUGFUNC("ixgbe_init_eeprom_params_X540");
     308             : 
     309           0 :         if (eeprom->type == ixgbe_eeprom_uninitialized) {
     310           0 :                 eeprom->semaphore_delay = 10;
     311           0 :                 eeprom->type = ixgbe_flash;
     312             : 
     313           0 :                 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
     314           0 :                 eeprom_size = (uint16_t)((eec & IXGBE_EEC_SIZE) >>
     315             :                                     IXGBE_EEC_SIZE_SHIFT);
     316           0 :                 eeprom->word_size = 1 << (eeprom_size +
     317             :                                           IXGBE_EEPROM_WORD_SIZE_SHIFT);
     318             : 
     319             :                 DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
     320             :                           eeprom->type, eeprom->word_size);
     321           0 :         }
     322             : 
     323           0 :         return IXGBE_SUCCESS;
     324             : }
     325             : 
     326             : /**
     327             :  *  ixgbe_read_eerd_X540- Read EEPROM word using EERD
     328             :  *  @hw: pointer to hardware structure
     329             :  *  @offset: offset of  word in the EEPROM to read
     330             :  *  @data: word read from the EEPROM
     331             :  *
     332             :  *  Reads a 16 bit word from the EEPROM using the EERD register.
     333             :  **/
     334           0 : int32_t ixgbe_read_eerd_X540(struct ixgbe_hw *hw, uint16_t offset, uint16_t *data)
     335             : {
     336             :         int32_t status = IXGBE_SUCCESS;
     337             : 
     338             :         DEBUGFUNC("ixgbe_read_eerd_X540");
     339           0 :         if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
     340             :             IXGBE_SUCCESS) {
     341           0 :                 status = ixgbe_read_eerd_generic(hw, offset, data);
     342           0 :                 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
     343           0 :         } else {
     344             :                 status = IXGBE_ERR_SWFW_SYNC;
     345             :         }
     346             : 
     347           0 :         return status;
     348             : }
     349             : 
     350             : /**
     351             :  *  ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
     352             :  *  @hw: pointer to hardware structure
     353             :  *  @offset: offset of  word in the EEPROM to write
     354             :  *  @data: word write to the EEPROM
     355             :  *
     356             :  *  Write a 16 bit word to the EEPROM using the EEWR register.
     357             :  **/
     358           0 : int32_t ixgbe_write_eewr_X540(struct ixgbe_hw *hw, uint16_t offset, uint16_t data)
     359             : {
     360             :         int32_t status = IXGBE_SUCCESS;
     361             : 
     362             :         DEBUGFUNC("ixgbe_write_eewr_X540");
     363           0 :         if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
     364             :             IXGBE_SUCCESS) {
     365           0 :                 status = ixgbe_write_eewr_generic(hw, offset, data);
     366           0 :                 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
     367           0 :         } else {
     368             :                 status = IXGBE_ERR_SWFW_SYNC;
     369             :         }
     370             : 
     371           0 :         return status;
     372             : }
     373             : 
     374             : /**
     375             :  *  ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
     376             :  *
     377             :  *  This function does not use synchronization for EERD and EEWR. It can
     378             :  *  be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
     379             :  *
     380             :  *  @hw: pointer to hardware structure
     381             :  *
     382             :  *  Returns a negative error code on error, or the 16-bit checksum
     383             :  **/
     384           0 : int32_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
     385             : {
     386             :         uint16_t i, j;
     387             :         uint16_t checksum = 0;
     388           0 :         uint16_t length = 0;
     389           0 :         uint16_t pointer = 0;
     390           0 :         uint16_t word = 0;
     391             :         uint16_t checksum_last_word = IXGBE_EEPROM_CHECKSUM;
     392             :         uint16_t ptr_start = IXGBE_PCIE_ANALOG_PTR;
     393             : 
     394             :         /* Do not use hw->eeprom.ops.read because we do not want to take
     395             :          * the synchronization semaphores here. Instead use
     396             :          * ixgbe_read_eerd_generic
     397             :          */
     398             : 
     399             :         DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540");
     400             : 
     401             :         /* Include 0x0-0x3F in the checksum */
     402           0 :         for (i = 0; i <= checksum_last_word; i++) {
     403           0 :                 if (ixgbe_read_eerd_generic(hw, i, &word)) {
     404             :                         DEBUGOUT("EEPROM read failed\n");
     405           0 :                         return IXGBE_ERR_EEPROM;
     406             :                 }
     407           0 :                 if (i != IXGBE_EEPROM_CHECKSUM)
     408           0 :                         checksum += word;
     409             :         }
     410             : 
     411             :         /* Include all data from pointers 0x3, 0x6-0xE.  This excludes the
     412             :          * FW, PHY module, and PCIe Expansion/Option ROM pointers.
     413             :          */
     414           0 :         for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
     415           0 :                 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
     416             :                         continue;
     417             : 
     418           0 :                 if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
     419             :                         DEBUGOUT("EEPROM read failed\n");
     420           0 :                         return IXGBE_ERR_EEPROM;
     421             :                 }
     422             : 
     423             :                 /* Skip pointer section if the pointer is invalid. */
     424           0 :                 if (pointer == 0xFFFF || pointer == 0 ||
     425           0 :                     pointer >= hw->eeprom.word_size)
     426             :                         continue;
     427             : 
     428           0 :                 if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
     429             :                         DEBUGOUT("EEPROM read failed\n");
     430           0 :                         return IXGBE_ERR_EEPROM;
     431             :                 }
     432             : 
     433             :                 /* Skip pointer section if length is invalid. */
     434           0 :                 if (length == 0xFFFF || length == 0 ||
     435           0 :                     (pointer + length) >= hw->eeprom.word_size)
     436             :                         continue;
     437             : 
     438           0 :                 for (j = pointer + 1; j <= pointer + length; j++) {
     439           0 :                         if (ixgbe_read_eerd_generic(hw, j, &word)) {
     440             :                                 DEBUGOUT("EEPROM read failed\n");
     441           0 :                                 return IXGBE_ERR_EEPROM;
     442             :                         }
     443           0 :                         checksum += word;
     444             :                 }
     445             :         }
     446             : 
     447           0 :         checksum = (uint16_t)IXGBE_EEPROM_SUM - checksum;
     448             : 
     449           0 :         return (int32_t)checksum;
     450           0 : }
     451             : 
     452             : /**
     453             :  *  ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
     454             :  *  @hw: pointer to hardware structure
     455             :  *  @checksum_val: calculated checksum
     456             :  *
     457             :  *  Performs checksum calculation and validates the EEPROM checksum.  If the
     458             :  *  caller does not need checksum_val, the value can be NULL.
     459             :  **/
     460           0 : int32_t ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
     461             :                                             uint16_t *checksum_val)
     462             : {
     463             :         int32_t status;
     464           0 :         uint16_t checksum;
     465           0 :         uint16_t read_checksum = 0;
     466             : 
     467             :         DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540");
     468             : 
     469             :         /* Read the first word from the EEPROM. If this times out or fails, do
     470             :          * not continue or we could be in for a very long wait while every
     471             :          * EEPROM read fails
     472             :          */
     473           0 :         status = hw->eeprom.ops.read(hw, 0, &checksum);
     474           0 :         if (status) {
     475             :                 DEBUGOUT("EEPROM read failed\n");
     476           0 :                 return status;
     477             :         }
     478             : 
     479           0 :         if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
     480           0 :                 return IXGBE_ERR_SWFW_SYNC;
     481             : 
     482           0 :         status = hw->eeprom.ops.calc_checksum(hw);
     483           0 :         if (status < 0)
     484             :                 goto out;
     485             : 
     486           0 :         checksum = (uint16_t)(status & 0xffff);
     487             : 
     488             :         /* Do not use hw->eeprom.ops.read because we do not want to take
     489             :          * the synchronization semaphores twice here.
     490             :          */
     491           0 :         status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
     492             :                                          &read_checksum);
     493           0 :         if (status)
     494             :                 goto out;
     495             : 
     496             :         /* Verify read checksum from EEPROM is the same as
     497             :          * calculated checksum
     498             :          */
     499           0 :         if (read_checksum != checksum) {
     500             :                 DEBUGOUT("Invalid EEPROM checksum\n");
     501             :                 status = IXGBE_ERR_EEPROM_CHECKSUM;
     502           0 :         }
     503             : 
     504             :         /* If the user cares, return the calculated checksum */
     505           0 :         if (checksum_val)
     506           0 :                 *checksum_val = checksum;
     507             : 
     508             : out:
     509           0 :         hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
     510             : 
     511           0 :         return status;
     512           0 : }
     513             : 
     514             : /**
     515             :  * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
     516             :  * @hw: pointer to hardware structure
     517             :  *
     518             :  * After writing EEPROM to shadow RAM using EEWR register, software calculates
     519             :  * checksum and updates the EEPROM and instructs the hardware to update
     520             :  * the flash.
     521             :  **/
     522           0 : int32_t ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
     523             : {
     524             :         int32_t status;
     525           0 :         uint16_t checksum;
     526             : 
     527             :         DEBUGFUNC("ixgbe_update_eeprom_checksum_X540");
     528             : 
     529             :         /* Read the first word from the EEPROM. If this times out or fails, do
     530             :          * not continue or we could be in for a very long wait while every
     531             :          * EEPROM read fails
     532             :          */
     533           0 :         status = hw->eeprom.ops.read(hw, 0, &checksum);
     534           0 :         if (status) {
     535             :                 DEBUGOUT("EEPROM read failed\n");
     536           0 :                 return status;
     537             :         }
     538             : 
     539           0 :         if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
     540           0 :                 return IXGBE_ERR_SWFW_SYNC;
     541             : 
     542           0 :         status = hw->eeprom.ops.calc_checksum(hw);
     543           0 :         if (status < 0)
     544             :                 goto out;
     545             : 
     546           0 :         checksum = (uint16_t)(status & 0xffff);
     547             : 
     548             :         /* Do not use hw->eeprom.ops.write because we do not want to
     549             :          * take the synchronization semaphores twice here.
     550             :          */
     551           0 :         status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
     552           0 :         if (status)
     553             :                 goto out;
     554             : 
     555           0 :         status = ixgbe_update_flash_X540(hw);
     556             : 
     557             : out:
     558           0 :         hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
     559             : 
     560           0 :         return status;
     561           0 : }
     562             : 
     563             : /**
     564             :  *  ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device
     565             :  *  @hw: pointer to hardware structure
     566             :  *
     567             :  *  Set FLUP (bit 23) of the EEC register to instruct Hardware to copy
     568             :  *  EEPROM from shadow RAM to the flash device.
     569             :  **/
     570           0 : int32_t ixgbe_update_flash_X540(struct ixgbe_hw *hw)
     571             : {
     572             :         uint32_t flup;
     573             :         int32_t status;
     574             : 
     575             :         DEBUGFUNC("ixgbe_update_flash_X540");
     576             : 
     577           0 :         status = ixgbe_poll_flash_update_done_X540(hw);
     578           0 :         if (status == IXGBE_ERR_EEPROM) {
     579             :                 DEBUGOUT("Flash update time out\n");
     580             :                 goto out;
     581             :         }
     582             : 
     583           0 :         flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP;
     584           0 :         IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
     585             : 
     586           0 :         status = ixgbe_poll_flash_update_done_X540(hw);
     587             :         if (status == IXGBE_SUCCESS)
     588             :                 DEBUGOUT("Flash update complete\n");
     589             :         else
     590             :                 DEBUGOUT("Flash update time out\n");
     591             : 
     592           0 :         if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) {
     593           0 :                 flup = IXGBE_READ_REG(hw, IXGBE_EEC);
     594             : 
     595           0 :                 if (flup & IXGBE_EEC_SEC1VAL) {
     596           0 :                         flup |= IXGBE_EEC_FLUP;
     597           0 :                         IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
     598           0 :                 }
     599             : 
     600           0 :                 status = ixgbe_poll_flash_update_done_X540(hw);
     601             :                 if (status == IXGBE_SUCCESS)
     602             :                         DEBUGOUT("Flash update complete\n");
     603             :                 else
     604             :                         DEBUGOUT("Flash update time out\n");
     605           0 :         }
     606             : out:
     607           0 :         return status;
     608             : }
     609             : 
     610             : /**
     611             :  *  ixgbe_poll_flash_update_done_X540 - Poll flash update status
     612             :  *  @hw: pointer to hardware structure
     613             :  *
     614             :  *  Polls the FLUDONE (bit 26) of the EEC Register to determine when the
     615             :  *  flash update is done.
     616             :  **/
     617           0 : int32_t ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
     618             : {
     619             :         uint32_t i;
     620             :         uint32_t reg;
     621             :         int32_t status = IXGBE_ERR_EEPROM;
     622             : 
     623             :         DEBUGFUNC("ixgbe_poll_flash_update_done_X540");
     624             : 
     625           0 :         for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
     626           0 :                 reg = IXGBE_READ_REG(hw, IXGBE_EEC);
     627           0 :                 if (reg & IXGBE_EEC_FLUDONE) {
     628             :                         status = IXGBE_SUCCESS;
     629           0 :                         break;
     630             :                 }
     631           0 :                 msec_delay(5);
     632             :         }
     633           0 :         return status;
     634             : }
     635             : 
     636             : /**
     637             :  *  ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore
     638             :  *  @hw: pointer to hardware structure
     639             :  *  @mask: Mask to specify which semaphore to acquire
     640             :  *
     641             :  *  Acquires the SWFW semaphore thought the SW_FW_SYNC register for
     642             :  *  the specified function (CSR, PHY0, PHY1, NVM, Flash)
     643             :  **/
     644           0 : int32_t ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask)
     645             : {
     646           0 :         uint32_t swmask = mask & IXGBE_GSSR_NVM_PHY_MASK;
     647           0 :         uint32_t fwmask = swmask << 5;
     648           0 :         uint32_t swi2c_mask = mask & IXGBE_GSSR_I2C_MASK;
     649             :         uint32_t timeout = 200;
     650             :         uint32_t hwmask = 0;
     651             :         uint32_t swfw_sync;
     652             :         uint32_t i;
     653             : 
     654             :         DEBUGFUNC("ixgbe_acquire_swfw_sync_X540");
     655             : 
     656           0 :         if (swmask & IXGBE_GSSR_EEP_SM)
     657           0 :                 hwmask |= IXGBE_GSSR_FLASH_SM;
     658             : 
     659             :         /* SW only mask doesn't have FW bit pair */
     660           0 :         if (mask & IXGBE_GSSR_SW_MNG_SM)
     661           0 :                 swmask |= IXGBE_GSSR_SW_MNG_SM;
     662             : 
     663           0 :         swmask |= swi2c_mask;
     664           0 :         fwmask |= swi2c_mask << 2;
     665           0 :         for (i = 0; i < timeout; i++) {
     666             :                 /* SW NVM semaphore bit is used for access to all
     667             :                  * SW_FW_SYNC bits (not just NVM)
     668             :                  */
     669           0 :                 if (ixgbe_get_swfw_sync_semaphore(hw))
     670           0 :                         return IXGBE_ERR_SWFW_SYNC;
     671             : 
     672           0 :                 swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
     673           0 :                 if (!(swfw_sync & (fwmask | swmask | hwmask))) {
     674           0 :                         swfw_sync |= swmask;
     675           0 :                         IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
     676           0 :                         ixgbe_release_swfw_sync_semaphore(hw);
     677           0 :                         msec_delay(5);
     678           0 :                         return IXGBE_SUCCESS;
     679             :                 }
     680             :                 /* Firmware currently using resource (fwmask), hardware
     681             :                  * currently using resource (hwmask), or other software
     682             :                  * thread currently using resource (swmask)
     683             :                  */
     684           0 :                 ixgbe_release_swfw_sync_semaphore(hw);
     685           0 :                 msec_delay(5);
     686             :         }
     687             : 
     688             :         /* Failed to get SW only semaphore */
     689           0 :         if (swmask == IXGBE_GSSR_SW_MNG_SM) {
     690           0 :                 return IXGBE_ERR_SWFW_SYNC;
     691             :         }
     692             : 
     693             :         /* If the resource is not released by the FW/HW the SW can assume that
     694             :          * the FW/HW malfunctions. In that case the SW should set the SW bit(s)
     695             :          * of the requested resource(s) while ignoring the corresponding FW/HW
     696             :          * bits in the SW_FW_SYNC register.
     697             :          */
     698           0 :         if (ixgbe_get_swfw_sync_semaphore(hw))
     699           0 :                 return IXGBE_ERR_SWFW_SYNC;
     700           0 :         swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
     701           0 :         if (swfw_sync & (fwmask | hwmask)) {
     702           0 :                 swfw_sync |= swmask;
     703           0 :                 IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
     704           0 :                 ixgbe_release_swfw_sync_semaphore(hw);
     705           0 :                 msec_delay(5);
     706           0 :                 return IXGBE_SUCCESS;
     707             :         }
     708             :         /* If the resource is not released by other SW the SW can assume that
     709             :          * the other SW malfunctions. In that case the SW should clear all SW
     710             :          * flags that it does not own and then repeat the whole process once
     711             :          * again.
     712             :          */
     713           0 :         if (swfw_sync & swmask) {
     714             :                 uint32_t rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
     715             :                                  IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM;
     716             : 
     717           0 :                 if (swi2c_mask)
     718           0 :                         rmask |= IXGBE_GSSR_I2C_MASK;
     719           0 :                 ixgbe_release_swfw_sync_X540(hw, rmask);
     720           0 :                 ixgbe_release_swfw_sync_semaphore(hw);
     721             :                 return IXGBE_ERR_SWFW_SYNC;
     722             :         }
     723           0 :         ixgbe_release_swfw_sync_semaphore(hw);
     724             : 
     725           0 :         return IXGBE_ERR_SWFW_SYNC;
     726           0 : }
     727             : 
     728             : /**
     729             :  *  ixgbe_release_swfw_sync_X540 - Release SWFW semaphore
     730             :  *  @hw: pointer to hardware structure
     731             :  *  @mask: Mask to specify which semaphore to release
     732             :  *
     733             :  *  Releases the SWFW semaphore through the SW_FW_SYNC register
     734             :  *  for the specified function (CSR, PHY0, PHY1, EVM, Flash)
     735             :  **/
     736           0 : void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask)
     737             : {
     738           0 :         uint32_t swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM);
     739             :         uint32_t swfw_sync;
     740             : 
     741             :         DEBUGFUNC("ixgbe_release_swfw_sync_X540");
     742             : 
     743           0 :         if (mask & IXGBE_GSSR_I2C_MASK)
     744           0 :                 swmask |= mask & IXGBE_GSSR_I2C_MASK;
     745           0 :         ixgbe_get_swfw_sync_semaphore(hw);
     746             : 
     747           0 :         swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
     748           0 :         swfw_sync &= ~swmask;
     749           0 :         IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
     750             : 
     751           0 :         ixgbe_release_swfw_sync_semaphore(hw);
     752           0 :         msec_delay(5);
     753           0 : }
     754             : 
     755             : /**
     756             :  *  ixgbe_get_swfw_sync_semaphore - Get hardware semaphore
     757             :  *  @hw: pointer to hardware structure
     758             :  *
     759             :  *  Sets the hardware semaphores so SW/FW can gain control of shared resources
     760             :  **/
     761           0 : int32_t ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
     762             : {
     763             :         int32_t status = IXGBE_ERR_EEPROM;
     764             :         uint32_t timeout = 2000;
     765             :         uint32_t i;
     766             :         uint32_t swsm;
     767             : 
     768             :         DEBUGFUNC("ixgbe_get_swfw_sync_semaphore");
     769             : 
     770             :         /* Get SMBI software semaphore between device drivers first */
     771           0 :         for (i = 0; i < timeout; i++) {
     772             :                 /*
     773             :                  * If the SMBI bit is 0 when we read it, then the bit will be
     774             :                  * set and we have the semaphore
     775             :                  */
     776           0 :                 swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
     777           0 :                 if (!(swsm & IXGBE_SWSM_SMBI)) {
     778             :                         status = IXGBE_SUCCESS;
     779           0 :                         break;
     780             :                 }
     781           0 :                 usec_delay(50);
     782             :         }
     783             : 
     784             :         /* Now get the semaphore between SW/FW through the REGSMP bit */
     785           0 :         if (status == IXGBE_SUCCESS) {
     786           0 :                 for (i = 0; i < timeout; i++) {
     787           0 :                         swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
     788           0 :                         if (!(swsm & IXGBE_SWFW_REGSMP))
     789             :                                 break;
     790             : 
     791           0 :                         usec_delay(50);
     792             :                 }
     793             : 
     794             :                 /*
     795             :                  * Release semaphores and return error if SW NVM semaphore
     796             :                  * was not granted because we don't have access to the EEPROM
     797             :                  */
     798           0 :                 if (i >= timeout) {
     799             :                         DEBUGOUT("REGSMP Software NVM semaphore not "
     800             :                                  "granted.\n");
     801           0 :                         ixgbe_release_swfw_sync_semaphore(hw);
     802             :                         status = IXGBE_ERR_EEPROM;
     803           0 :                 }
     804             :         } else {
     805             :                 DEBUGOUT("Software semaphore SMBI between device drivers "
     806             :                          "not granted.\n");
     807             :         }
     808             : 
     809           0 :         return status;
     810             : }
     811             : 
     812             : /**
     813             :  *  ixgbe_release_swfw_sync_semaphore - Release hardware semaphore
     814             :  *  @hw: pointer to hardware structure
     815             :  *
     816             :  *  This function clears hardware semaphore bits.
     817             :  **/
     818           0 : void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
     819             : {
     820             :         uint32_t swsm;
     821             : 
     822             :         DEBUGFUNC("ixgbe_release_swfw_sync_semaphore");
     823             : 
     824             :         /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
     825             : 
     826           0 :         swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
     827           0 :         swsm &= ~IXGBE_SWFW_REGSMP;
     828           0 :         IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm);
     829             : 
     830           0 :         swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
     831           0 :         swsm &= ~IXGBE_SWSM_SMBI;
     832           0 :         IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
     833             : 
     834           0 :         IXGBE_WRITE_FLUSH(hw);
     835           0 : }
     836             : 
     837             : /**
     838             :  * ixgbe_blink_led_start_X540 - Blink LED based on index.
     839             :  * @hw: pointer to hardware structure
     840             :  * @index: led number to blink
     841             :  *
     842             :  * Devices that implement the version 2 interface:
     843             :  *   X540
     844             :  **/
     845           0 : int32_t ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, uint32_t index)
     846             : {
     847             :         uint32_t macc_reg;
     848             :         uint32_t ledctl_reg;
     849           0 :         ixgbe_link_speed speed;
     850           0 :         bool link_up;
     851             : 
     852             :         DEBUGFUNC("ixgbe_blink_led_start_X540");
     853             : 
     854             :         /*
     855             :          * Link should be up in order for the blink bit in the LED control
     856             :          * register to work. Force link and speed in the MAC if link is down.
     857             :          * This will be reversed when we stop the blinking.
     858             :          */
     859           0 :         hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
     860           0 :         if (link_up == FALSE) {
     861           0 :                 macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
     862           0 :                 macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
     863           0 :                 IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
     864           0 :         }
     865             :         /* Set the LED to LINK_UP + BLINK. */
     866           0 :         ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
     867           0 :         ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
     868           0 :         ledctl_reg |= IXGBE_LED_BLINK(index);
     869           0 :         IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
     870           0 :         IXGBE_WRITE_FLUSH(hw);
     871             : 
     872           0 :         return IXGBE_SUCCESS;
     873           0 : }
     874             : 
     875             : /**
     876             :  * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index.
     877             :  * @hw: pointer to hardware structure
     878             :  * @index: led number to stop blinking
     879             :  *
     880             :  * Devices that implement the version 2 interface:
     881             :  *   X540
     882             :  **/
     883           0 : int32_t ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, uint32_t index)
     884             : {
     885             :         uint32_t macc_reg;
     886             :         uint32_t ledctl_reg;
     887             : 
     888             :         DEBUGFUNC("ixgbe_blink_led_stop_X540");
     889             : 
     890             :         /* Restore the LED to its default value. */
     891           0 :         ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
     892           0 :         ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
     893           0 :         ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
     894           0 :         ledctl_reg &= ~IXGBE_LED_BLINK(index);
     895           0 :         IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
     896             : 
     897             :         /* Unforce link and speed in the MAC. */
     898           0 :         macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
     899           0 :         macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS);
     900           0 :         IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
     901           0 :         IXGBE_WRITE_FLUSH(hw);
     902             : 
     903           0 :         return IXGBE_SUCCESS;
     904             : }

Generated by: LCOV version 1.13