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