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