aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igb
diff options
context:
space:
mode:
authorCarolyn Wyborny <carolyn.wyborny@intel.com>2012-10-23 09:04:37 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-11-01 05:35:52 -0400
commit09e77287e752c8fc9743d865ddadc1a0d81a4927 (patch)
treef86cf9a83520ce45bbc9e06adf817cf68b372af6 /drivers/net/ethernet/intel/igb
parent40b20122f92b9e29d7770c12eb58b3a30e1cce33 (diff)
igb: Add function to read i211's invm version
The i211's one-time programmable (invm) version field is different than the other fields contained in it. This patch adds a function to get the invm version of it and store it for output from ethtool. Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb')
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c94
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.h11
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.h1
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.c1
4 files changed, 107 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index 77a5f939bc74..41474298d365 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -423,6 +423,100 @@ s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data)
423} 423}
424 424
425/** 425/**
426 * igb_read_invm_version - Reads iNVM version and image type
427 * @hw: pointer to the HW structure
428 * @invm_ver: version structure for the version read
429 *
430 * Reads iNVM version and image type.
431 **/
432s32 igb_read_invm_version(struct e1000_hw *hw,
433 struct e1000_fw_version *invm_ver) {
434 u32 *record = NULL;
435 u32 *next_record = NULL;
436 u32 i = 0;
437 u32 invm_dword = 0;
438 u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
439 E1000_INVM_RECORD_SIZE_IN_BYTES);
440 u32 buffer[E1000_INVM_SIZE];
441 s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
442 u16 version = 0;
443
444 /* Read iNVM memory */
445 for (i = 0; i < E1000_INVM_SIZE; i++) {
446 invm_dword = rd32(E1000_INVM_DATA_REG(i));
447 buffer[i] = invm_dword;
448 }
449
450 /* Read version number */
451 for (i = 1; i < invm_blocks; i++) {
452 record = &buffer[invm_blocks - i];
453 next_record = &buffer[invm_blocks - i + 1];
454
455 /* Check if we have first version location used */
456 if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
457 version = 0;
458 status = E1000_SUCCESS;
459 break;
460 }
461 /* Check if we have second version location used */
462 else if ((i == 1) &&
463 ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
464 version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
465 status = E1000_SUCCESS;
466 break;
467 }
468 /* Check if we have odd version location
469 * used and it is the last one used
470 */
471 else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
472 ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
473 (i != 1))) {
474 version = (*next_record & E1000_INVM_VER_FIELD_TWO)
475 >> 13;
476 status = E1000_SUCCESS;
477 break;
478 }
479 /* Check if we have even version location
480 * used and it is the last one used
481 */
482 else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
483 ((*record & 0x3) == 0)) {
484 version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
485 status = E1000_SUCCESS;
486 break;
487 }
488 }
489
490 if (status == E1000_SUCCESS) {
491 invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
492 >> E1000_INVM_MAJOR_SHIFT;
493 invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
494 }
495 /* Read Image Type */
496 for (i = 1; i < invm_blocks; i++) {
497 record = &buffer[invm_blocks - i];
498 next_record = &buffer[invm_blocks - i + 1];
499
500 /* Check if we have image type in first location used */
501 if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
502 invm_ver->invm_img_type = 0;
503 status = E1000_SUCCESS;
504 break;
505 }
506 /* Check if we have image type in first location used */
507 else if ((((*record & 0x3) == 0) &&
508 ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
509 ((((*record & 0x3) != 0) && (i != 1)))) {
510 invm_ver->invm_img_type =
511 (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
512 status = E1000_SUCCESS;
513 break;
514 }
515 }
516 return status;
517}
518
519/**
426 * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum 520 * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
427 * @hw: pointer to the HW structure 521 * @hw: pointer to the HW structure
428 * 522 *
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
index 5dc2bd3f50bc..974d23584d70 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -43,6 +43,8 @@ extern void igb_release_nvm_i210(struct e1000_hw *hw);
43extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); 43extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
44extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, 44extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
45 u16 *data); 45 u16 *data);
46extern s32 igb_read_invm_version(struct e1000_hw *hw,
47 struct e1000_fw_version *invm_ver);
46 48
47#define E1000_STM_OPCODE 0xDB00 49#define E1000_STM_OPCODE 0xDB00
48#define E1000_EEPROM_FLASH_SIZE_WORD 0x11 50#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
@@ -65,6 +67,15 @@ enum E1000_INVM_STRUCTURE_TYPE {
65 67
66#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 68#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
67#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 69#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
70#define E1000_INVM_ULT_BYTES_SIZE 8
71#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
72#define E1000_INVM_VER_FIELD_ONE 0x1FF8
73#define E1000_INVM_VER_FIELD_TWO 0x7FE000
74#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
75
76#define E1000_INVM_MAJOR_MASK 0x3F0
77#define E1000_INVM_MINOR_MASK 0xF
78#define E1000_INVM_MAJOR_SHIFT 4
68 79
69#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ 80#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
70 (ID_LED_OFF1_OFF2 << 4) | \ 81 (ID_LED_OFF1_OFF2 << 4) | \
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h
index cbddc4e51e30..e2b2c4b9c951 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.h
@@ -33,6 +33,7 @@
33#include "e1000_phy.h" 33#include "e1000_phy.h"
34#include "e1000_nvm.h" 34#include "e1000_nvm.h"
35#include "e1000_defines.h" 35#include "e1000_defines.h"
36#include "e1000_i210.h"
36 37
37/* 38/*
38 * Functions that should not be called directly from drivers but can be used 39 * Functions that should not be called directly from drivers but can be used
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c
index 54ff53905ffe..7db3f80bcd57 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -727,6 +727,7 @@ void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
727 727
728 switch (hw->mac.type) { 728 switch (hw->mac.type) {
729 case e1000_i211: 729 case e1000_i211:
730 igb_read_invm_version(hw, fw_vers);
730 return; 731 return;
731 case e1000_82575: 732 case e1000_82575:
732 case e1000_82576: 733 case e1000_82576: