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