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