diff options
-rw-r--r-- | drivers/net/igb/e1000_defines.h | 7 | ||||
-rw-r--r-- | drivers/net/igb/e1000_nvm.c | 93 | ||||
-rw-r--r-- | drivers/net/igb/e1000_nvm.h | 2 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 11 |
4 files changed, 102 insertions, 11 deletions
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 62222796a8b3..6319ed902bc0 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h | |||
@@ -419,6 +419,9 @@ | |||
419 | #define E1000_ERR_SWFW_SYNC 13 | 419 | #define E1000_ERR_SWFW_SYNC 13 |
420 | #define E1000_NOT_IMPLEMENTED 14 | 420 | #define E1000_NOT_IMPLEMENTED 14 |
421 | #define E1000_ERR_MBX 15 | 421 | #define E1000_ERR_MBX 15 |
422 | #define E1000_ERR_INVALID_ARGUMENT 16 | ||
423 | #define E1000_ERR_NO_SPACE 17 | ||
424 | #define E1000_ERR_NVM_PBA_SECTION 18 | ||
422 | 425 | ||
423 | /* Loop limit on how long we wait for auto-negotiation to complete */ | 426 | /* Loop limit on how long we wait for auto-negotiation to complete */ |
424 | #define COPPER_LINK_UP_LIMIT 10 | 427 | #define COPPER_LINK_UP_LIMIT 10 |
@@ -580,11 +583,15 @@ | |||
580 | 583 | ||
581 | /* Mask bits for fields in Word 0x1a of the NVM */ | 584 | /* Mask bits for fields in Word 0x1a of the NVM */ |
582 | 585 | ||
586 | /* length of string needed to store part num */ | ||
587 | #define E1000_PBANUM_LENGTH 11 | ||
588 | |||
583 | /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ | 589 | /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ |
584 | #define NVM_SUM 0xBABA | 590 | #define NVM_SUM 0xBABA |
585 | 591 | ||
586 | #define NVM_PBA_OFFSET_0 8 | 592 | #define NVM_PBA_OFFSET_0 8 |
587 | #define NVM_PBA_OFFSET_1 9 | 593 | #define NVM_PBA_OFFSET_1 9 |
594 | #define NVM_PBA_PTR_GUARD 0xFAFA | ||
588 | #define NVM_WORD_SIZE_BASE_SHIFT 6 | 595 | #define NVM_WORD_SIZE_BASE_SHIFT 6 |
589 | 596 | ||
590 | /* NVM Commands - Microwire */ | 597 | /* NVM Commands - Microwire */ |
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c index d83b77fa4038..6b5cc2cc453d 100644 --- a/drivers/net/igb/e1000_nvm.c +++ b/drivers/net/igb/e1000_nvm.c | |||
@@ -445,31 +445,112 @@ out: | |||
445 | } | 445 | } |
446 | 446 | ||
447 | /** | 447 | /** |
448 | * igb_read_part_num - Read device part number | 448 | * igb_read_part_string - Read device part number |
449 | * @hw: pointer to the HW structure | 449 | * @hw: pointer to the HW structure |
450 | * @part_num: pointer to device part number | 450 | * @part_num: pointer to device part number |
451 | * @part_num_size: size of part number buffer | ||
451 | * | 452 | * |
452 | * Reads the product board assembly (PBA) number from the EEPROM and stores | 453 | * Reads the product board assembly (PBA) number from the EEPROM and stores |
453 | * the value in part_num. | 454 | * the value in part_num. |
454 | **/ | 455 | **/ |
455 | s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num) | 456 | s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, u32 part_num_size) |
456 | { | 457 | { |
457 | s32 ret_val; | 458 | s32 ret_val; |
458 | u16 nvm_data; | 459 | u16 nvm_data; |
460 | u16 pointer; | ||
461 | u16 offset; | ||
462 | u16 length; | ||
463 | |||
464 | if (part_num == NULL) { | ||
465 | hw_dbg("PBA string buffer was null\n"); | ||
466 | ret_val = E1000_ERR_INVALID_ARGUMENT; | ||
467 | goto out; | ||
468 | } | ||
459 | 469 | ||
460 | ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); | 470 | ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); |
461 | if (ret_val) { | 471 | if (ret_val) { |
462 | hw_dbg("NVM Read Error\n"); | 472 | hw_dbg("NVM Read Error\n"); |
463 | goto out; | 473 | goto out; |
464 | } | 474 | } |
465 | *part_num = (u32)(nvm_data << 16); | ||
466 | 475 | ||
467 | ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); | 476 | ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pointer); |
477 | if (ret_val) { | ||
478 | hw_dbg("NVM Read Error\n"); | ||
479 | goto out; | ||
480 | } | ||
481 | |||
482 | /* | ||
483 | * if nvm_data is not ptr guard the PBA must be in legacy format which | ||
484 | * means pointer is actually our second data word for the PBA number | ||
485 | * and we can decode it into an ascii string | ||
486 | */ | ||
487 | if (nvm_data != NVM_PBA_PTR_GUARD) { | ||
488 | hw_dbg("NVM PBA number is not stored as string\n"); | ||
489 | |||
490 | /* we will need 11 characters to store the PBA */ | ||
491 | if (part_num_size < 11) { | ||
492 | hw_dbg("PBA string buffer too small\n"); | ||
493 | return E1000_ERR_NO_SPACE; | ||
494 | } | ||
495 | |||
496 | /* extract hex string from data and pointer */ | ||
497 | part_num[0] = (nvm_data >> 12) & 0xF; | ||
498 | part_num[1] = (nvm_data >> 8) & 0xF; | ||
499 | part_num[2] = (nvm_data >> 4) & 0xF; | ||
500 | part_num[3] = nvm_data & 0xF; | ||
501 | part_num[4] = (pointer >> 12) & 0xF; | ||
502 | part_num[5] = (pointer >> 8) & 0xF; | ||
503 | part_num[6] = '-'; | ||
504 | part_num[7] = 0; | ||
505 | part_num[8] = (pointer >> 4) & 0xF; | ||
506 | part_num[9] = pointer & 0xF; | ||
507 | |||
508 | /* put a null character on the end of our string */ | ||
509 | part_num[10] = '\0'; | ||
510 | |||
511 | /* switch all the data but the '-' to hex char */ | ||
512 | for (offset = 0; offset < 10; offset++) { | ||
513 | if (part_num[offset] < 0xA) | ||
514 | part_num[offset] += '0'; | ||
515 | else if (part_num[offset] < 0x10) | ||
516 | part_num[offset] += 'A' - 0xA; | ||
517 | } | ||
518 | |||
519 | goto out; | ||
520 | } | ||
521 | |||
522 | ret_val = hw->nvm.ops.read(hw, pointer, 1, &length); | ||
468 | if (ret_val) { | 523 | if (ret_val) { |
469 | hw_dbg("NVM Read Error\n"); | 524 | hw_dbg("NVM Read Error\n"); |
470 | goto out; | 525 | goto out; |
471 | } | 526 | } |
472 | *part_num |= nvm_data; | 527 | |
528 | if (length == 0xFFFF || length == 0) { | ||
529 | hw_dbg("NVM PBA number section invalid length\n"); | ||
530 | ret_val = E1000_ERR_NVM_PBA_SECTION; | ||
531 | goto out; | ||
532 | } | ||
533 | /* check if part_num buffer is big enough */ | ||
534 | if (part_num_size < (((u32)length * 2) - 1)) { | ||
535 | hw_dbg("PBA string buffer too small\n"); | ||
536 | ret_val = E1000_ERR_NO_SPACE; | ||
537 | goto out; | ||
538 | } | ||
539 | |||
540 | /* trim pba length from start of string */ | ||
541 | pointer++; | ||
542 | length--; | ||
543 | |||
544 | for (offset = 0; offset < length; offset++) { | ||
545 | ret_val = hw->nvm.ops.read(hw, pointer + offset, 1, &nvm_data); | ||
546 | if (ret_val) { | ||
547 | hw_dbg("NVM Read Error\n"); | ||
548 | goto out; | ||
549 | } | ||
550 | part_num[offset * 2] = (u8)(nvm_data >> 8); | ||
551 | part_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); | ||
552 | } | ||
553 | part_num[offset * 2] = '\0'; | ||
473 | 554 | ||
474 | out: | 555 | out: |
475 | return ret_val; | 556 | return ret_val; |
diff --git a/drivers/net/igb/e1000_nvm.h b/drivers/net/igb/e1000_nvm.h index 1041c34dcbe1..29c956a84bd0 100644 --- a/drivers/net/igb/e1000_nvm.h +++ b/drivers/net/igb/e1000_nvm.h | |||
@@ -32,6 +32,8 @@ s32 igb_acquire_nvm(struct e1000_hw *hw); | |||
32 | void igb_release_nvm(struct e1000_hw *hw); | 32 | void igb_release_nvm(struct e1000_hw *hw); |
33 | s32 igb_read_mac_addr(struct e1000_hw *hw); | 33 | s32 igb_read_mac_addr(struct e1000_hw *hw); |
34 | s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num); | 34 | s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num); |
35 | s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, | ||
36 | u32 part_num_size); | ||
35 | s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); | 37 | s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); |
36 | s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); | 38 | s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); |
37 | s32 igb_validate_nvm_checksum(struct e1000_hw *hw); | 39 | s32 igb_validate_nvm_checksum(struct e1000_hw *hw); |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 67ea262e482a..041f8e6f74f4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -1729,12 +1729,13 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1729 | struct igb_adapter *adapter; | 1729 | struct igb_adapter *adapter; |
1730 | struct e1000_hw *hw; | 1730 | struct e1000_hw *hw; |
1731 | u16 eeprom_data = 0; | 1731 | u16 eeprom_data = 0; |
1732 | s32 ret_val; | ||
1732 | static int global_quad_port_a; /* global quad port a indication */ | 1733 | static int global_quad_port_a; /* global quad port a indication */ |
1733 | const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; | 1734 | const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; |
1734 | unsigned long mmio_start, mmio_len; | 1735 | unsigned long mmio_start, mmio_len; |
1735 | int err, pci_using_dac; | 1736 | int err, pci_using_dac; |
1736 | u16 eeprom_apme_mask = IGB_EEPROM_APME; | 1737 | u16 eeprom_apme_mask = IGB_EEPROM_APME; |
1737 | u32 part_num; | 1738 | u8 part_str[E1000_PBANUM_LENGTH]; |
1738 | 1739 | ||
1739 | /* Catch broken hardware that put the wrong VF device ID in | 1740 | /* Catch broken hardware that put the wrong VF device ID in |
1740 | * the PCIe SR-IOV capability. | 1741 | * the PCIe SR-IOV capability. |
@@ -2000,10 +2001,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
2000 | "unknown"), | 2001 | "unknown"), |
2001 | netdev->dev_addr); | 2002 | netdev->dev_addr); |
2002 | 2003 | ||
2003 | igb_read_part_num(hw, &part_num); | 2004 | ret_val = igb_read_part_string(hw, part_str, E1000_PBANUM_LENGTH); |
2004 | dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name, | 2005 | if (ret_val) |
2005 | (part_num >> 8), (part_num & 0xff)); | 2006 | strcpy(part_str, "Unknown"); |
2006 | 2007 | dev_info(&pdev->dev, "%s: PBA No: %s\n", netdev->name, part_str); | |
2007 | dev_info(&pdev->dev, | 2008 | dev_info(&pdev->dev, |
2008 | "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n", | 2009 | "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n", |
2009 | adapter->msix_entries ? "MSI-X" : | 2010 | adapter->msix_entries ? "MSI-X" : |