aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
diff options
context:
space:
mode:
authorCarolyn Wyborny <carolyn.wyborny@intel.com>2010-11-22 12:17:21 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2010-12-11 01:14:01 -0500
commit9835fd7321a67feba6432e63bf2cba43f5a56bd9 (patch)
treef7df41d2ba5675d6405ec1cfbfd5479abc1f938d /drivers/net/igb
parentc920aa8b87bfec3dbd926ae777430e613e5088df (diff)
igb: Add new function to read part number from EEPROM in string format
New adapters will have part numbers stored in string format rather than simple hex format. This function will read part number formats in either hex or string. Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/igb')
-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" :