FreeBSD/Linux Kernel Cross Reference
sys/dev/igc/igc_i225.c
1 /*-
2 * Copyright 2021 Intel Corp
3 * Copyright 2021 Rubicon Communications, LLC (Netgate)
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <sys/cdefs.h>
8 __FBSDID("$FreeBSD$");
9
10 #include "igc_api.h"
11
12 static s32 igc_init_nvm_params_i225(struct igc_hw *hw);
13 static s32 igc_init_mac_params_i225(struct igc_hw *hw);
14 static s32 igc_init_phy_params_i225(struct igc_hw *hw);
15 static s32 igc_reset_hw_i225(struct igc_hw *hw);
16 static s32 igc_acquire_nvm_i225(struct igc_hw *hw);
17 static void igc_release_nvm_i225(struct igc_hw *hw);
18 static s32 igc_get_hw_semaphore_i225(struct igc_hw *hw);
19 static s32 __igc_write_nvm_srwr(struct igc_hw *hw, u16 offset, u16 words,
20 u16 *data);
21 static s32 igc_pool_flash_update_done_i225(struct igc_hw *hw);
22
23 /**
24 * igc_init_nvm_params_i225 - Init NVM func ptrs.
25 * @hw: pointer to the HW structure
26 **/
27 static s32 igc_init_nvm_params_i225(struct igc_hw *hw)
28 {
29 struct igc_nvm_info *nvm = &hw->nvm;
30 u32 eecd = IGC_READ_REG(hw, IGC_EECD);
31 u16 size;
32
33 DEBUGFUNC("igc_init_nvm_params_i225");
34
35 size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
36 IGC_EECD_SIZE_EX_SHIFT);
37 /*
38 * Added to a constant, "size" becomes the left-shift value
39 * for setting word_size.
40 */
41 size += NVM_WORD_SIZE_BASE_SHIFT;
42
43 /* Just in case size is out of range, cap it to the largest
44 * EEPROM size supported
45 */
46 if (size > 15)
47 size = 15;
48
49 nvm->word_size = 1 << size;
50 nvm->opcode_bits = 8;
51 nvm->delay_usec = 1;
52 nvm->type = igc_nvm_eeprom_spi;
53
54
55 nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
56 nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
57 16 : 8;
58
59 if (nvm->word_size == (1 << 15))
60 nvm->page_size = 128;
61
62 nvm->ops.acquire = igc_acquire_nvm_i225;
63 nvm->ops.release = igc_release_nvm_i225;
64 if (igc_get_flash_presence_i225(hw)) {
65 hw->nvm.type = igc_nvm_flash_hw;
66 nvm->ops.read = igc_read_nvm_srrd_i225;
67 nvm->ops.write = igc_write_nvm_srwr_i225;
68 nvm->ops.validate = igc_validate_nvm_checksum_i225;
69 nvm->ops.update = igc_update_nvm_checksum_i225;
70 } else {
71 hw->nvm.type = igc_nvm_invm;
72 nvm->ops.write = igc_null_write_nvm;
73 nvm->ops.validate = igc_null_ops_generic;
74 nvm->ops.update = igc_null_ops_generic;
75 }
76
77 return IGC_SUCCESS;
78 }
79
80 /**
81 * igc_init_mac_params_i225 - Init MAC func ptrs.
82 * @hw: pointer to the HW structure
83 **/
84 static s32 igc_init_mac_params_i225(struct igc_hw *hw)
85 {
86 struct igc_mac_info *mac = &hw->mac;
87 struct igc_dev_spec_i225 *dev_spec = &hw->dev_spec._i225;
88
89 DEBUGFUNC("igc_init_mac_params_i225");
90
91 /* Initialize function pointer */
92 igc_init_mac_ops_generic(hw);
93
94 /* Set media type */
95 hw->phy.media_type = igc_media_type_copper;
96 /* Set mta register count */
97 mac->mta_reg_count = 128;
98 /* Set rar entry count */
99 mac->rar_entry_count = IGC_RAR_ENTRIES_BASE;
100
101 /* reset */
102 mac->ops.reset_hw = igc_reset_hw_i225;
103 /* hw initialization */
104 mac->ops.init_hw = igc_init_hw_i225;
105 /* link setup */
106 mac->ops.setup_link = igc_setup_link_generic;
107 /* check for link */
108 mac->ops.check_for_link = igc_check_for_link_i225;
109 /* link info */
110 mac->ops.get_link_up_info = igc_get_speed_and_duplex_copper_generic;
111 /* acquire SW_FW sync */
112 mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
113 /* release SW_FW sync */
114 mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;
115
116 /* Allow a single clear of the SW semaphore on I225 */
117 dev_spec->clear_semaphore_once = true;
118 mac->ops.setup_physical_interface = igc_setup_copper_link_i225;
119
120 /* Set if part includes ASF firmware */
121 mac->asf_firmware_present = true;
122
123 /* multicast address update */
124 mac->ops.update_mc_addr_list = igc_update_mc_addr_list_generic;
125
126 mac->ops.write_vfta = igc_write_vfta_generic;
127
128 return IGC_SUCCESS;
129 }
130
131 /**
132 * igc_init_phy_params_i225 - Init PHY func ptrs.
133 * @hw: pointer to the HW structure
134 **/
135 static s32 igc_init_phy_params_i225(struct igc_hw *hw)
136 {
137 struct igc_phy_info *phy = &hw->phy;
138 s32 ret_val = IGC_SUCCESS;
139
140 DEBUGFUNC("igc_init_phy_params_i225");
141
142
143 if (hw->phy.media_type != igc_media_type_copper) {
144 phy->type = igc_phy_none;
145 goto out;
146 }
147
148 phy->ops.power_up = igc_power_up_phy_copper;
149 phy->ops.power_down = igc_power_down_phy_copper_base;
150
151 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT_2500;
152
153 phy->reset_delay_us = 100;
154
155 phy->ops.acquire = igc_acquire_phy_base;
156 phy->ops.check_reset_block = igc_check_reset_block_generic;
157 phy->ops.release = igc_release_phy_base;
158 phy->ops.reset = igc_phy_hw_reset_generic;
159 phy->ops.read_reg = igc_read_phy_reg_gpy;
160 phy->ops.write_reg = igc_write_phy_reg_gpy;
161
162 /* Make sure the PHY is in a good state. Several people have reported
163 * firmware leaving the PHY's page select register set to something
164 * other than the default of zero, which causes the PHY ID read to
165 * access something other than the intended register.
166 */
167 ret_val = hw->phy.ops.reset(hw);
168 if (ret_val)
169 goto out;
170
171 ret_val = igc_get_phy_id(hw);
172 phy->type = igc_phy_i225;
173
174 out:
175 return ret_val;
176 }
177
178 /**
179 * igc_reset_hw_i225 - Reset hardware
180 * @hw: pointer to the HW structure
181 *
182 * This resets the hardware into a known state.
183 **/
184 static s32 igc_reset_hw_i225(struct igc_hw *hw)
185 {
186 u32 ctrl;
187 s32 ret_val;
188
189 DEBUGFUNC("igc_reset_hw_i225");
190
191 /*
192 * Prevent the PCI-E bus from sticking if there is no TLP connection
193 * on the last TLP read/write transaction when MAC is reset.
194 */
195 ret_val = igc_disable_pcie_master_generic(hw);
196 if (ret_val)
197 DEBUGOUT("PCI-E Master disable polling has failed.\n");
198
199 DEBUGOUT("Masking off all interrupts\n");
200 IGC_WRITE_REG(hw, IGC_IMC, 0xffffffff);
201
202 IGC_WRITE_REG(hw, IGC_RCTL, 0);
203 IGC_WRITE_REG(hw, IGC_TCTL, IGC_TCTL_PSP);
204 IGC_WRITE_FLUSH(hw);
205
206 msec_delay(10);
207
208 ctrl = IGC_READ_REG(hw, IGC_CTRL);
209
210 DEBUGOUT("Issuing a global reset to MAC\n");
211 IGC_WRITE_REG(hw, IGC_CTRL, ctrl | IGC_CTRL_DEV_RST);
212
213 ret_val = igc_get_auto_rd_done_generic(hw);
214 if (ret_val) {
215 /*
216 * When auto config read does not complete, do not
217 * return with an error. This can happen in situations
218 * where there is no eeprom and prevents getting link.
219 */
220 DEBUGOUT("Auto Read Done did not complete\n");
221 }
222
223 /* Clear any pending interrupt events. */
224 IGC_WRITE_REG(hw, IGC_IMC, 0xffffffff);
225 IGC_READ_REG(hw, IGC_ICR);
226
227 /* Install any alternate MAC address into RAR0 */
228 ret_val = igc_check_alt_mac_addr_generic(hw);
229
230 return ret_val;
231 }
232
233 /* igc_acquire_nvm_i225 - Request for access to EEPROM
234 * @hw: pointer to the HW structure
235 *
236 * Acquire the necessary semaphores for exclusive access to the EEPROM.
237 * Set the EEPROM access request bit and wait for EEPROM access grant bit.
238 * Return successful if access grant bit set, else clear the request for
239 * EEPROM access and return -IGC_ERR_NVM (-1).
240 */
241 static s32 igc_acquire_nvm_i225(struct igc_hw *hw)
242 {
243 s32 ret_val;
244
245 DEBUGFUNC("igc_acquire_nvm_i225");
246
247 ret_val = igc_acquire_swfw_sync_i225(hw, IGC_SWFW_EEP_SM);
248
249 return ret_val;
250 }
251
252 /* igc_release_nvm_i225 - Release exclusive access to EEPROM
253 * @hw: pointer to the HW structure
254 *
255 * Stop any current commands to the EEPROM and clear the EEPROM request bit,
256 * then release the semaphores acquired.
257 */
258 static void igc_release_nvm_i225(struct igc_hw *hw)
259 {
260 DEBUGFUNC("igc_release_nvm_i225");
261
262 igc_release_swfw_sync_i225(hw, IGC_SWFW_EEP_SM);
263 }
264
265 /* igc_acquire_swfw_sync_i225 - Acquire SW/FW semaphore
266 * @hw: pointer to the HW structure
267 * @mask: specifies which semaphore to acquire
268 *
269 * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
270 * will also specify which port we're acquiring the lock for.
271 */
272 s32 igc_acquire_swfw_sync_i225(struct igc_hw *hw, u16 mask)
273 {
274 u32 swfw_sync;
275 u32 swmask = mask;
276 u32 fwmask = mask << 16;
277 s32 ret_val = IGC_SUCCESS;
278 s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
279
280 DEBUGFUNC("igc_acquire_swfw_sync_i225");
281
282 while (i < timeout) {
283 if (igc_get_hw_semaphore_i225(hw)) {
284 ret_val = -IGC_ERR_SWFW_SYNC;
285 goto out;
286 }
287
288 swfw_sync = IGC_READ_REG(hw, IGC_SW_FW_SYNC);
289 if (!(swfw_sync & (fwmask | swmask)))
290 break;
291
292 /* Firmware currently using resource (fwmask)
293 * or other software thread using resource (swmask)
294 */
295 igc_put_hw_semaphore_generic(hw);
296 msec_delay_irq(5);
297 i++;
298 }
299
300 if (i == timeout) {
301 DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
302 ret_val = -IGC_ERR_SWFW_SYNC;
303 goto out;
304 }
305
306 swfw_sync |= swmask;
307 IGC_WRITE_REG(hw, IGC_SW_FW_SYNC, swfw_sync);
308
309 igc_put_hw_semaphore_generic(hw);
310
311 out:
312 return ret_val;
313 }
314
315 /* igc_release_swfw_sync_i225 - Release SW/FW semaphore
316 * @hw: pointer to the HW structure
317 * @mask: specifies which semaphore to acquire
318 *
319 * Release the SW/FW semaphore used to access the PHY or NVM. The mask
320 * will also specify which port we're releasing the lock for.
321 */
322 void igc_release_swfw_sync_i225(struct igc_hw *hw, u16 mask)
323 {
324 u32 swfw_sync;
325
326 DEBUGFUNC("igc_release_swfw_sync_i225");
327
328 while (igc_get_hw_semaphore_i225(hw) != IGC_SUCCESS)
329 ; /* Empty */
330
331 swfw_sync = IGC_READ_REG(hw, IGC_SW_FW_SYNC);
332 swfw_sync &= ~mask;
333 IGC_WRITE_REG(hw, IGC_SW_FW_SYNC, swfw_sync);
334
335 igc_put_hw_semaphore_generic(hw);
336 }
337
338 /*
339 * igc_setup_copper_link_i225 - Configure copper link settings
340 * @hw: pointer to the HW structure
341 *
342 * Configures the link for auto-neg or forced speed and duplex. Then we check
343 * for link, once link is established calls to configure collision distance
344 * and flow control are called.
345 */
346 s32 igc_setup_copper_link_i225(struct igc_hw *hw)
347 {
348 u32 phpm_reg;
349 s32 ret_val;
350 u32 ctrl;
351
352 DEBUGFUNC("igc_setup_copper_link_i225");
353
354 ctrl = IGC_READ_REG(hw, IGC_CTRL);
355 ctrl |= IGC_CTRL_SLU;
356 ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX);
357 IGC_WRITE_REG(hw, IGC_CTRL, ctrl);
358
359 phpm_reg = IGC_READ_REG(hw, IGC_I225_PHPM);
360 phpm_reg &= ~IGC_I225_PHPM_GO_LINKD;
361 IGC_WRITE_REG(hw, IGC_I225_PHPM, phpm_reg);
362
363 ret_val = igc_setup_copper_link_generic(hw);
364
365 return ret_val;
366 }
367
368 /* igc_get_hw_semaphore_i225 - Acquire hardware semaphore
369 * @hw: pointer to the HW structure
370 *
371 * Acquire the HW semaphore to access the PHY or NVM
372 */
373 static s32 igc_get_hw_semaphore_i225(struct igc_hw *hw)
374 {
375 u32 swsm;
376 s32 timeout = hw->nvm.word_size + 1;
377 s32 i = 0;
378
379 DEBUGFUNC("igc_get_hw_semaphore_i225");
380
381 /* Get the SW semaphore */
382 while (i < timeout) {
383 swsm = IGC_READ_REG(hw, IGC_SWSM);
384 if (!(swsm & IGC_SWSM_SMBI))
385 break;
386
387 usec_delay(50);
388 i++;
389 }
390
391 if (i == timeout) {
392 /* In rare circumstances, the SW semaphore may already be held
393 * unintentionally. Clear the semaphore once before giving up.
394 */
395 if (hw->dev_spec._i225.clear_semaphore_once) {
396 hw->dev_spec._i225.clear_semaphore_once = false;
397 igc_put_hw_semaphore_generic(hw);
398 for (i = 0; i < timeout; i++) {
399 swsm = IGC_READ_REG(hw, IGC_SWSM);
400 if (!(swsm & IGC_SWSM_SMBI))
401 break;
402
403 usec_delay(50);
404 }
405 }
406
407 /* If we do not have the semaphore here, we have to give up. */
408 if (i == timeout) {
409 DEBUGOUT("Driver can't access device -\n");
410 DEBUGOUT("SMBI bit is set.\n");
411 return -IGC_ERR_NVM;
412 }
413 }
414
415 /* Get the FW semaphore. */
416 for (i = 0; i < timeout; i++) {
417 swsm = IGC_READ_REG(hw, IGC_SWSM);
418 IGC_WRITE_REG(hw, IGC_SWSM, swsm | IGC_SWSM_SWESMBI);
419
420 /* Semaphore acquired if bit latched */
421 if (IGC_READ_REG(hw, IGC_SWSM) & IGC_SWSM_SWESMBI)
422 break;
423
424 usec_delay(50);
425 }
426
427 if (i == timeout) {
428 /* Release semaphores */
429 igc_put_hw_semaphore_generic(hw);
430 DEBUGOUT("Driver can't access the NVM\n");
431 return -IGC_ERR_NVM;
432 }
433
434 return IGC_SUCCESS;
435 }
436
437 /* igc_read_nvm_srrd_i225 - Reads Shadow Ram using EERD register
438 * @hw: pointer to the HW structure
439 * @offset: offset of word in the Shadow Ram to read
440 * @words: number of words to read
441 * @data: word read from the Shadow Ram
442 *
443 * Reads a 16 bit word from the Shadow Ram using the EERD register.
444 * Uses necessary synchronization semaphores.
445 */
446 s32 igc_read_nvm_srrd_i225(struct igc_hw *hw, u16 offset, u16 words,
447 u16 *data)
448 {
449 s32 status = IGC_SUCCESS;
450 u16 i, count;
451
452 DEBUGFUNC("igc_read_nvm_srrd_i225");
453
454 /* We cannot hold synchronization semaphores for too long,
455 * because of forceful takeover procedure. However it is more efficient
456 * to read in bursts than synchronizing access for each word.
457 */
458 for (i = 0; i < words; i += IGC_EERD_EEWR_MAX_COUNT) {
459 count = (words - i) / IGC_EERD_EEWR_MAX_COUNT > 0 ?
460 IGC_EERD_EEWR_MAX_COUNT : (words - i);
461 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) {
462 status = igc_read_nvm_eerd(hw, offset, count,
463 data + i);
464 hw->nvm.ops.release(hw);
465 } else {
466 status = IGC_ERR_SWFW_SYNC;
467 }
468
469 if (status != IGC_SUCCESS)
470 break;
471 }
472
473 return status;
474 }
475
476 /* igc_write_nvm_srwr_i225 - Write to Shadow RAM using EEWR
477 * @hw: pointer to the HW structure
478 * @offset: offset within the Shadow RAM to be written to
479 * @words: number of words to write
480 * @data: 16 bit word(s) to be written to the Shadow RAM
481 *
482 * Writes data to Shadow RAM at offset using EEWR register.
483 *
484 * If igc_update_nvm_checksum is not called after this function , the
485 * data will not be committed to FLASH and also Shadow RAM will most likely
486 * contain an invalid checksum.
487 *
488 * If error code is returned, data and Shadow RAM may be inconsistent - buffer
489 * partially written.
490 */
491 s32 igc_write_nvm_srwr_i225(struct igc_hw *hw, u16 offset, u16 words,
492 u16 *data)
493 {
494 s32 status = IGC_SUCCESS;
495 u16 i, count;
496
497 DEBUGFUNC("igc_write_nvm_srwr_i225");
498
499 /* We cannot hold synchronization semaphores for too long,
500 * because of forceful takeover procedure. However it is more efficient
501 * to write in bursts than synchronizing access for each word.
502 */
503 for (i = 0; i < words; i += IGC_EERD_EEWR_MAX_COUNT) {
504 count = (words - i) / IGC_EERD_EEWR_MAX_COUNT > 0 ?
505 IGC_EERD_EEWR_MAX_COUNT : (words - i);
506 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) {
507 status = __igc_write_nvm_srwr(hw, offset, count,
508 data + i);
509 hw->nvm.ops.release(hw);
510 } else {
511 status = IGC_ERR_SWFW_SYNC;
512 }
513
514 if (status != IGC_SUCCESS)
515 break;
516 }
517
518 return status;
519 }
520
521 /* __igc_write_nvm_srwr - Write to Shadow Ram using EEWR
522 * @hw: pointer to the HW structure
523 * @offset: offset within the Shadow Ram to be written to
524 * @words: number of words to write
525 * @data: 16 bit word(s) to be written to the Shadow Ram
526 *
527 * Writes data to Shadow Ram at offset using EEWR register.
528 *
529 * If igc_update_nvm_checksum is not called after this function , the
530 * Shadow Ram will most likely contain an invalid checksum.
531 */
532 static s32 __igc_write_nvm_srwr(struct igc_hw *hw, u16 offset, u16 words,
533 u16 *data)
534 {
535 struct igc_nvm_info *nvm = &hw->nvm;
536 u32 i, k, eewr = 0;
537 u32 attempts = 100000;
538 s32 ret_val = IGC_SUCCESS;
539
540 DEBUGFUNC("__igc_write_nvm_srwr");
541
542 /* A check for invalid values: offset too large, too many words,
543 * too many words for the offset, and not enough words.
544 */
545 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
546 (words == 0)) {
547 DEBUGOUT("nvm parameter(s) out of bounds\n");
548 ret_val = -IGC_ERR_NVM;
549 goto out;
550 }
551
552 for (i = 0; i < words; i++) {
553 eewr = ((offset + i) << IGC_NVM_RW_ADDR_SHIFT) |
554 (data[i] << IGC_NVM_RW_REG_DATA) |
555 IGC_NVM_RW_REG_START;
556
557 IGC_WRITE_REG(hw, IGC_SRWR, eewr);
558
559 for (k = 0; k < attempts; k++) {
560 if (IGC_NVM_RW_REG_DONE &
561 IGC_READ_REG(hw, IGC_SRWR)) {
562 ret_val = IGC_SUCCESS;
563 break;
564 }
565 usec_delay(5);
566 }
567
568 if (ret_val != IGC_SUCCESS) {
569 DEBUGOUT("Shadow RAM write EEWR timed out\n");
570 break;
571 }
572 }
573
574 out:
575 return ret_val;
576 }
577
578 /* igc_validate_nvm_checksum_i225 - Validate EEPROM checksum
579 * @hw: pointer to the HW structure
580 *
581 * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
582 * and then verifies that the sum of the EEPROM is equal to 0xBABA.
583 */
584 s32 igc_validate_nvm_checksum_i225(struct igc_hw *hw)
585 {
586 s32 status = IGC_SUCCESS;
587 s32 (*read_op_ptr)(struct igc_hw *, u16, u16, u16 *);
588
589 DEBUGFUNC("igc_validate_nvm_checksum_i225");
590
591 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) {
592 /* Replace the read function with semaphore grabbing with
593 * the one that skips this for a while.
594 * We have semaphore taken already here.
595 */
596 read_op_ptr = hw->nvm.ops.read;
597 hw->nvm.ops.read = igc_read_nvm_eerd;
598
599 status = igc_validate_nvm_checksum_generic(hw);
600
601 /* Revert original read operation. */
602 hw->nvm.ops.read = read_op_ptr;
603
604 hw->nvm.ops.release(hw);
605 } else {
606 status = IGC_ERR_SWFW_SYNC;
607 }
608
609 return status;
610 }
611
612 /* igc_update_nvm_checksum_i225 - Update EEPROM checksum
613 * @hw: pointer to the HW structure
614 *
615 * Updates the EEPROM checksum by reading/adding each word of the EEPROM
616 * up to the checksum. Then calculates the EEPROM checksum and writes the
617 * value to the EEPROM. Next commit EEPROM data onto the Flash.
618 */
619 s32 igc_update_nvm_checksum_i225(struct igc_hw *hw)
620 {
621 s32 ret_val;
622 u16 checksum = 0;
623 u16 i, nvm_data;
624
625 DEBUGFUNC("igc_update_nvm_checksum_i225");
626
627 /* Read the first word from the EEPROM. If this times out or fails, do
628 * not continue or we could be in for a very long wait while every
629 * EEPROM read fails
630 */
631 ret_val = igc_read_nvm_eerd(hw, 0, 1, &nvm_data);
632 if (ret_val != IGC_SUCCESS) {
633 DEBUGOUT("EEPROM read failed\n");
634 goto out;
635 }
636
637 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) {
638 /* Do not use hw->nvm.ops.write, hw->nvm.ops.read
639 * because we do not want to take the synchronization
640 * semaphores twice here.
641 */
642
643 for (i = 0; i < NVM_CHECKSUM_REG; i++) {
644 ret_val = igc_read_nvm_eerd(hw, i, 1, &nvm_data);
645 if (ret_val) {
646 hw->nvm.ops.release(hw);
647 DEBUGOUT("NVM Read Error while updating\n");
648 DEBUGOUT("checksum.\n");
649 goto out;
650 }
651 checksum += nvm_data;
652 }
653 checksum = (u16)NVM_SUM - checksum;
654 ret_val = __igc_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
655 &checksum);
656 if (ret_val != IGC_SUCCESS) {
657 hw->nvm.ops.release(hw);
658 DEBUGOUT("NVM Write Error while updating checksum.\n");
659 goto out;
660 }
661
662 hw->nvm.ops.release(hw);
663
664 ret_val = igc_update_flash_i225(hw);
665 } else {
666 ret_val = IGC_ERR_SWFW_SYNC;
667 }
668 out:
669 return ret_val;
670 }
671
672 /* igc_get_flash_presence_i225 - Check if flash device is detected.
673 * @hw: pointer to the HW structure
674 */
675 bool igc_get_flash_presence_i225(struct igc_hw *hw)
676 {
677 u32 eec = 0;
678 bool ret_val = false;
679
680 DEBUGFUNC("igc_get_flash_presence_i225");
681
682 eec = IGC_READ_REG(hw, IGC_EECD);
683
684 if (eec & IGC_EECD_FLASH_DETECTED_I225)
685 ret_val = true;
686
687 return ret_val;
688 }
689
690 /* igc_set_flsw_flash_burst_counter_i225 - sets FLSW NVM Burst
691 * Counter in FLSWCNT register.
692 *
693 * @hw: pointer to the HW structure
694 * @burst_counter: size in bytes of the Flash burst to read or write
695 */
696 s32 igc_set_flsw_flash_burst_counter_i225(struct igc_hw *hw,
697 u32 burst_counter)
698 {
699 s32 ret_val = IGC_SUCCESS;
700
701 DEBUGFUNC("igc_set_flsw_flash_burst_counter_i225");
702
703 /* Validate input data */
704 if (burst_counter < IGC_I225_SHADOW_RAM_SIZE) {
705 /* Write FLSWCNT - burst counter */
706 IGC_WRITE_REG(hw, IGC_I225_FLSWCNT, burst_counter);
707 } else {
708 ret_val = IGC_ERR_INVALID_ARGUMENT;
709 }
710
711 return ret_val;
712 }
713
714 /* igc_write_erase_flash_command_i225 - write/erase to a sector
715 * region on a given address.
716 *
717 * @hw: pointer to the HW structure
718 * @opcode: opcode to be used for the write command
719 * @address: the offset to write into the FLASH image
720 */
721 s32 igc_write_erase_flash_command_i225(struct igc_hw *hw, u32 opcode,
722 u32 address)
723 {
724 u32 flswctl = 0;
725 s32 timeout = IGC_NVM_GRANT_ATTEMPTS;
726 s32 ret_val = IGC_SUCCESS;
727
728 DEBUGFUNC("igc_write_erase_flash_command_i225");
729
730 flswctl = IGC_READ_REG(hw, IGC_I225_FLSWCTL);
731 /* Polling done bit on FLSWCTL register */
732 while (timeout) {
733 if (flswctl & IGC_FLSWCTL_DONE)
734 break;
735 usec_delay(5);
736 flswctl = IGC_READ_REG(hw, IGC_I225_FLSWCTL);
737 timeout--;
738 }
739
740 if (!timeout) {
741 DEBUGOUT("Flash transaction was not done\n");
742 return -IGC_ERR_NVM;
743 }
744
745 /* Build and issue command on FLSWCTL register */
746 flswctl = address | opcode;
747 IGC_WRITE_REG(hw, IGC_I225_FLSWCTL, flswctl);
748
749 /* Check if issued command is valid on FLSWCTL register */
750 flswctl = IGC_READ_REG(hw, IGC_I225_FLSWCTL);
751 if (!(flswctl & IGC_FLSWCTL_CMDV)) {
752 DEBUGOUT("Write flash command failed\n");
753 ret_val = IGC_ERR_INVALID_ARGUMENT;
754 }
755
756 return ret_val;
757 }
758
759 /* igc_update_flash_i225 - Commit EEPROM to the flash
760 * if fw_valid_bit is set, FW is active. setting FLUPD bit in EEC
761 * register makes the FW load the internal shadow RAM into the flash.
762 * Otherwise, fw_valid_bit is 0. if FL_SECU.block_prtotected_sw = 0
763 * then FW is not active so the SW is responsible shadow RAM dump.
764 *
765 * @hw: pointer to the HW structure
766 */
767 s32 igc_update_flash_i225(struct igc_hw *hw)
768 {
769 u16 current_offset_data = 0;
770 u32 block_sw_protect = 1;
771 u16 base_address = 0x0;
772 u32 i, fw_valid_bit;
773 u16 current_offset;
774 s32 ret_val = 0;
775 u32 flup;
776
777 DEBUGFUNC("igc_update_flash_i225");
778
779 block_sw_protect = IGC_READ_REG(hw, IGC_I225_FLSECU) &
780 IGC_FLSECU_BLK_SW_ACCESS_I225;
781 fw_valid_bit = IGC_READ_REG(hw, IGC_FWSM) &
782 IGC_FWSM_FW_VALID_I225;
783 if (fw_valid_bit) {
784 ret_val = igc_pool_flash_update_done_i225(hw);
785 if (ret_val == -IGC_ERR_NVM) {
786 DEBUGOUT("Flash update time out\n");
787 goto out;
788 }
789
790 flup = IGC_READ_REG(hw, IGC_EECD) | IGC_EECD_FLUPD_I225;
791 IGC_WRITE_REG(hw, IGC_EECD, flup);
792
793 ret_val = igc_pool_flash_update_done_i225(hw);
794 if (ret_val == IGC_SUCCESS)
795 DEBUGOUT("Flash update complete\n");
796 else
797 DEBUGOUT("Flash update time out\n");
798 } else if (!block_sw_protect) {
799 /* FW is not active and security protection is disabled.
800 * therefore, SW is in charge of shadow RAM dump.
801 * Check which sector is valid. if sector 0 is valid,
802 * base address remains 0x0. otherwise, sector 1 is
803 * valid and it's base address is 0x1000
804 */
805 if (IGC_READ_REG(hw, IGC_EECD) & IGC_EECD_SEC1VAL_I225)
806 base_address = 0x1000;
807
808 /* Valid sector erase */
809 ret_val = igc_write_erase_flash_command_i225(hw,
810 IGC_I225_ERASE_CMD_OPCODE,
811 base_address);
812 if (!ret_val) {
813 DEBUGOUT("Sector erase failed\n");
814 goto out;
815 }
816
817 current_offset = base_address;
818
819 /* Write */
820 for (i = 0; i < IGC_I225_SHADOW_RAM_SIZE / 2; i++) {
821 /* Set burst write length */
822 ret_val = igc_set_flsw_flash_burst_counter_i225(hw,
823 0x2);
824 if (ret_val != IGC_SUCCESS)
825 break;
826
827 /* Set address and opcode */
828 ret_val = igc_write_erase_flash_command_i225(hw,
829 IGC_I225_WRITE_CMD_OPCODE,
830 2 * current_offset);
831 if (ret_val != IGC_SUCCESS)
832 break;
833
834 ret_val = igc_read_nvm_eerd(hw, current_offset,
835 1, ¤t_offset_data);
836 if (ret_val) {
837 DEBUGOUT("Failed to read from EEPROM\n");
838 goto out;
839 }
840
841 /* Write CurrentOffseData to FLSWDATA register */
842 IGC_WRITE_REG(hw, IGC_I225_FLSWDATA,
843 current_offset_data);
844 current_offset++;
845
846 /* Wait till operation has finished */
847 ret_val = igc_poll_eerd_eewr_done(hw,
848 IGC_NVM_POLL_READ);
849 if (ret_val)
850 break;
851
852 usec_delay(1000);
853 }
854 }
855 out:
856 return ret_val;
857 }
858
859 /* igc_pool_flash_update_done_i225 - Pool FLUDONE status.
860 * @hw: pointer to the HW structure
861 */
862 s32 igc_pool_flash_update_done_i225(struct igc_hw *hw)
863 {
864 s32 ret_val = -IGC_ERR_NVM;
865 u32 i, reg;
866
867 DEBUGFUNC("igc_pool_flash_update_done_i225");
868
869 for (i = 0; i < IGC_FLUDONE_ATTEMPTS; i++) {
870 reg = IGC_READ_REG(hw, IGC_EECD);
871 if (reg & IGC_EECD_FLUDONE_I225) {
872 ret_val = IGC_SUCCESS;
873 break;
874 }
875 usec_delay(5);
876 }
877
878 return ret_val;
879 }
880
881 /* igc_set_ltr_i225 - Set Latency Tolerance Reporting thresholds.
882 * @hw: pointer to the HW structure
883 * @link: bool indicating link status
884 *
885 * Set the LTR thresholds based on the link speed (Mbps), EEE, and DMAC
886 * settings, otherwise specify that there is no LTR requirement.
887 */
888 static s32 igc_set_ltr_i225(struct igc_hw *hw, bool link)
889 {
890 u16 speed, duplex;
891 u32 tw_system, ltrc, ltrv, ltr_min, ltr_max, scale_min, scale_max;
892 s32 size;
893
894 DEBUGFUNC("igc_set_ltr_i225");
895
896 /* If we do not have link, LTR thresholds are zero. */
897 if (link) {
898 hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
899
900 /* Check if using copper interface with EEE enabled or if the
901 * link speed is 10 Mbps.
902 */
903 if ((hw->phy.media_type == igc_media_type_copper) &&
904 !(hw->dev_spec._i225.eee_disable) &&
905 (speed != SPEED_10)) {
906 /* EEE enabled, so send LTRMAX threshold. */
907 ltrc = IGC_READ_REG(hw, IGC_LTRC) |
908 IGC_LTRC_EEEMS_EN;
909 IGC_WRITE_REG(hw, IGC_LTRC, ltrc);
910
911 /* Calculate tw_system (nsec). */
912 if (speed == SPEED_100) {
913 tw_system = ((IGC_READ_REG(hw, IGC_EEE_SU) &
914 IGC_TW_SYSTEM_100_MASK) >>
915 IGC_TW_SYSTEM_100_SHIFT) * 500;
916 } else {
917 tw_system = (IGC_READ_REG(hw, IGC_EEE_SU) &
918 IGC_TW_SYSTEM_1000_MASK) * 500;
919 }
920 } else {
921 tw_system = 0;
922 }
923
924 /* Get the Rx packet buffer size. */
925 size = IGC_READ_REG(hw, IGC_RXPBS) &
926 IGC_RXPBS_SIZE_I225_MASK;
927
928 /* Calculations vary based on DMAC settings. */
929 if (IGC_READ_REG(hw, IGC_DMACR) & IGC_DMACR_DMAC_EN) {
930 size -= (IGC_READ_REG(hw, IGC_DMACR) &
931 IGC_DMACR_DMACTHR_MASK) >>
932 IGC_DMACR_DMACTHR_SHIFT;
933 /* Convert size to bits. */
934 size *= 1024 * 8;
935 } else {
936 /* Convert size to bytes, subtract the MTU, and then
937 * convert the size to bits.
938 */
939 size *= 1024;
940 size -= hw->dev_spec._i225.mtu;
941 size *= 8;
942 }
943
944 if (size < 0) {
945 DEBUGOUT1("Invalid effective Rx buffer size %d\n",
946 size);
947 return -IGC_ERR_CONFIG;
948 }
949
950 /* Calculate the thresholds. Since speed is in Mbps, simplify
951 * the calculation by multiplying size/speed by 1000 for result
952 * to be in nsec before dividing by the scale in nsec. Set the
953 * scale such that the LTR threshold fits in the register.
954 */
955 ltr_min = (1000 * size) / speed;
956 ltr_max = ltr_min + tw_system;
957 scale_min = (ltr_min / 1024) < 1024 ? IGC_LTRMINV_SCALE_1024 :
958 IGC_LTRMINV_SCALE_32768;
959 scale_max = (ltr_max / 1024) < 1024 ? IGC_LTRMAXV_SCALE_1024 :
960 IGC_LTRMAXV_SCALE_32768;
961 ltr_min /= scale_min == IGC_LTRMINV_SCALE_1024 ? 1024 : 32768;
962 ltr_max /= scale_max == IGC_LTRMAXV_SCALE_1024 ? 1024 : 32768;
963
964 /* Only write the LTR thresholds if they differ from before. */
965 ltrv = IGC_READ_REG(hw, IGC_LTRMINV);
966 if (ltr_min != (ltrv & IGC_LTRMINV_LTRV_MASK)) {
967 ltrv = IGC_LTRMINV_LSNP_REQ | ltr_min |
968 (scale_min << IGC_LTRMINV_SCALE_SHIFT);
969 IGC_WRITE_REG(hw, IGC_LTRMINV, ltrv);
970 }
971
972 ltrv = IGC_READ_REG(hw, IGC_LTRMAXV);
973 if (ltr_max != (ltrv & IGC_LTRMAXV_LTRV_MASK)) {
974 ltrv = IGC_LTRMAXV_LSNP_REQ | ltr_max |
975 (scale_min << IGC_LTRMAXV_SCALE_SHIFT);
976 IGC_WRITE_REG(hw, IGC_LTRMAXV, ltrv);
977 }
978 }
979
980 return IGC_SUCCESS;
981 }
982
983 /* igc_check_for_link_i225 - Check for link
984 * @hw: pointer to the HW structure
985 *
986 * Checks to see of the link status of the hardware has changed. If a
987 * change in link status has been detected, then we read the PHY registers
988 * to get the current speed/duplex if link exists.
989 */
990 s32 igc_check_for_link_i225(struct igc_hw *hw)
991 {
992 struct igc_mac_info *mac = &hw->mac;
993 s32 ret_val;
994 bool link = false;
995
996 DEBUGFUNC("igc_check_for_link_i225");
997
998 /* We only want to go out to the PHY registers to see if
999 * Auto-Neg has completed and/or if our link status has
1000 * changed. The get_link_status flag is set upon receiving
1001 * a Link Status Change or Rx Sequence Error interrupt.
1002 */
1003 if (!mac->get_link_status) {
1004 ret_val = IGC_SUCCESS;
1005 goto out;
1006 }
1007
1008 /* First we want to see if the MII Status Register reports
1009 * link. If so, then we want to get the current speed/duplex
1010 * of the PHY.
1011 */
1012 ret_val = igc_phy_has_link_generic(hw, 1, 0, &link);
1013 if (ret_val)
1014 goto out;
1015
1016 if (!link)
1017 goto out; /* No link detected */
1018
1019 /* First we want to see if the MII Status Register reports
1020 * link. If so, then we want to get the current speed/duplex
1021 * of the PHY.
1022 */
1023 ret_val = igc_phy_has_link_generic(hw, 1, 0, &link);
1024 if (ret_val)
1025 goto out;
1026
1027 if (!link)
1028 goto out; /* No link detected */
1029
1030 mac->get_link_status = false;
1031
1032 /* Check if there was DownShift, must be checked
1033 * immediately after link-up
1034 */
1035 igc_check_downshift_generic(hw);
1036
1037 /* If we are forcing speed/duplex, then we simply return since
1038 * we have already determined whether we have link or not.
1039 */
1040 if (!mac->autoneg)
1041 goto out;
1042
1043 /* Auto-Neg is enabled. Auto Speed Detection takes care
1044 * of MAC speed/duplex configuration. So we only need to
1045 * configure Collision Distance in the MAC.
1046 */
1047 mac->ops.config_collision_dist(hw);
1048
1049 /* Configure Flow Control now that Auto-Neg has completed.
1050 * First, we need to restore the desired flow control
1051 * settings because we may have had to re-autoneg with a
1052 * different link partner.
1053 */
1054 ret_val = igc_config_fc_after_link_up_generic(hw);
1055 if (ret_val)
1056 DEBUGOUT("Error configuring flow control\n");
1057 out:
1058 /* Now that we are aware of our link settings, we can set the LTR
1059 * thresholds.
1060 */
1061 ret_val = igc_set_ltr_i225(hw, link);
1062
1063 return ret_val;
1064 }
1065
1066 /* igc_init_function_pointers_i225 - Init func ptrs.
1067 * @hw: pointer to the HW structure
1068 *
1069 * Called to initialize all function pointers and parameters.
1070 */
1071 void igc_init_function_pointers_i225(struct igc_hw *hw)
1072 {
1073 igc_init_mac_ops_generic(hw);
1074 igc_init_phy_ops_generic(hw);
1075 igc_init_nvm_ops_generic(hw);
1076 hw->mac.ops.init_params = igc_init_mac_params_i225;
1077 hw->nvm.ops.init_params = igc_init_nvm_params_i225;
1078 hw->phy.ops.init_params = igc_init_phy_params_i225;
1079 }
1080
1081 /* igc_init_hw_i225 - Init hw for I225
1082 * @hw: pointer to the HW structure
1083 *
1084 * Called to initialize hw for i225 hw family.
1085 */
1086 s32 igc_init_hw_i225(struct igc_hw *hw)
1087 {
1088 s32 ret_val;
1089
1090 DEBUGFUNC("igc_init_hw_i225");
1091
1092 ret_val = igc_init_hw_base(hw);
1093 return ret_val;
1094 }
1095
1096 /*
1097 * igc_set_d0_lplu_state_i225 - Set Low-Power-Link-Up (LPLU) D0 state
1098 * @hw: pointer to the HW structure
1099 * @active: true to enable LPLU, false to disable
1100 *
1101 * Note: since I225 does not actually support LPLU, this function
1102 * simply enables/disables 1G and 2.5G speeds in D0.
1103 */
1104 s32 igc_set_d0_lplu_state_i225(struct igc_hw *hw, bool active)
1105 {
1106 u32 data;
1107
1108 DEBUGFUNC("igc_set_d0_lplu_state_i225");
1109
1110 data = IGC_READ_REG(hw, IGC_I225_PHPM);
1111
1112 if (active) {
1113 data |= IGC_I225_PHPM_DIS_1000;
1114 data |= IGC_I225_PHPM_DIS_2500;
1115 } else {
1116 data &= ~IGC_I225_PHPM_DIS_1000;
1117 data &= ~IGC_I225_PHPM_DIS_2500;
1118 }
1119
1120 IGC_WRITE_REG(hw, IGC_I225_PHPM, data);
1121 return IGC_SUCCESS;
1122 }
1123
1124 /*
1125 * igc_set_d3_lplu_state_i225 - Set Low-Power-Link-Up (LPLU) D3 state
1126 * @hw: pointer to the HW structure
1127 * @active: true to enable LPLU, false to disable
1128 *
1129 * Note: since I225 does not actually support LPLU, this function
1130 * simply enables/disables 100M, 1G and 2.5G speeds in D3.
1131 */
1132 s32 igc_set_d3_lplu_state_i225(struct igc_hw *hw, bool active)
1133 {
1134 u32 data;
1135
1136 DEBUGFUNC("igc_set_d3_lplu_state_i225");
1137
1138 data = IGC_READ_REG(hw, IGC_I225_PHPM);
1139
1140 if (active) {
1141 data |= IGC_I225_PHPM_DIS_100_D3;
1142 data |= IGC_I225_PHPM_DIS_1000_D3;
1143 data |= IGC_I225_PHPM_DIS_2500_D3;
1144 } else {
1145 data &= ~IGC_I225_PHPM_DIS_100_D3;
1146 data &= ~IGC_I225_PHPM_DIS_1000_D3;
1147 data &= ~IGC_I225_PHPM_DIS_2500_D3;
1148 }
1149
1150 IGC_WRITE_REG(hw, IGC_I225_PHPM, data);
1151 return IGC_SUCCESS;
1152 }
1153
1154 /**
1155 * igc_set_eee_i225 - Enable/disable EEE support
1156 * @hw: pointer to the HW structure
1157 * @adv2p5G: boolean flag enabling 2.5G EEE advertisement
1158 * @adv1G: boolean flag enabling 1G EEE advertisement
1159 * @adv100M: boolean flag enabling 100M EEE advertisement
1160 *
1161 * Enable/disable EEE based on setting in dev_spec structure.
1162 *
1163 **/
1164 s32 igc_set_eee_i225(struct igc_hw *hw, bool adv2p5G, bool adv1G,
1165 bool adv100M)
1166 {
1167 u32 ipcnfg, eeer;
1168
1169 DEBUGFUNC("igc_set_eee_i225");
1170
1171 if (hw->mac.type != igc_i225 ||
1172 hw->phy.media_type != igc_media_type_copper)
1173 goto out;
1174 ipcnfg = IGC_READ_REG(hw, IGC_IPCNFG);
1175 eeer = IGC_READ_REG(hw, IGC_EEER);
1176
1177 /* enable or disable per user setting */
1178 if (!(hw->dev_spec._i225.eee_disable)) {
1179 u32 eee_su = IGC_READ_REG(hw, IGC_EEE_SU);
1180
1181 if (adv100M)
1182 ipcnfg |= IGC_IPCNFG_EEE_100M_AN;
1183 else
1184 ipcnfg &= ~IGC_IPCNFG_EEE_100M_AN;
1185
1186 if (adv1G)
1187 ipcnfg |= IGC_IPCNFG_EEE_1G_AN;
1188 else
1189 ipcnfg &= ~IGC_IPCNFG_EEE_1G_AN;
1190
1191 if (adv2p5G)
1192 ipcnfg |= IGC_IPCNFG_EEE_2_5G_AN;
1193 else
1194 ipcnfg &= ~IGC_IPCNFG_EEE_2_5G_AN;
1195
1196 eeer |= (IGC_EEER_TX_LPI_EN | IGC_EEER_RX_LPI_EN |
1197 IGC_EEER_LPI_FC);
1198
1199 /* This bit should not be set in normal operation. */
1200 if (eee_su & IGC_EEE_SU_LPI_CLK_STP)
1201 DEBUGOUT("LPI Clock Stop Bit should not be set!\n");
1202 } else {
1203 ipcnfg &= ~(IGC_IPCNFG_EEE_2_5G_AN | IGC_IPCNFG_EEE_1G_AN |
1204 IGC_IPCNFG_EEE_100M_AN);
1205 eeer &= ~(IGC_EEER_TX_LPI_EN | IGC_EEER_RX_LPI_EN |
1206 IGC_EEER_LPI_FC);
1207 }
1208 IGC_WRITE_REG(hw, IGC_IPCNFG, ipcnfg);
1209 IGC_WRITE_REG(hw, IGC_EEER, eeer);
1210 IGC_READ_REG(hw, IGC_IPCNFG);
1211 IGC_READ_REG(hw, IGC_EEER);
1212 out:
1213
1214 return IGC_SUCCESS;
1215 }
1216
Cache object: 5ff549aeba62a7e4af485edcc1b4e5ce
|