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