aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/igb/e1000_defines.h7
-rw-r--r--drivers/net/igb/e1000_nvm.c93
-rw-r--r--drivers/net/igb/e1000_nvm.h2
-rw-r--r--drivers/net/igb/igb_main.c11
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 **/
455s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num) 456s32 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
474out: 555out:
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);
32void igb_release_nvm(struct e1000_hw *hw); 32void igb_release_nvm(struct e1000_hw *hw);
33s32 igb_read_mac_addr(struct e1000_hw *hw); 33s32 igb_read_mac_addr(struct e1000_hw *hw);
34s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num); 34s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
35s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num,
36 u32 part_num_size);
35s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); 37s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
36s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); 38s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
37s32 igb_validate_nvm_checksum(struct e1000_hw *hw); 39s32 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" :