summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2013-05-01 16:06:23 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2013-05-01 23:47:18 +0000
commit21a6b03bbd82147f869197594e8b3ea8a7600eb1 (patch)
tree91678f757ddd99bda49fa8e4e08d4a635a66b0e3
parent933b08887aa05e6cd9c8fa845b60319533d2b88d (diff)
downloadillumos-joyent-21a6b03bbd82147f869197594e8b3ea8a7600eb1.tar.gz
OS-2160 want FW config version number for igb and ixgberelease-20130502
OS-2186 ship pcitool
-rw-r--r--manifest1
-rw-r--r--usr/src/uts/common/io/igb/igb_api.c22
-rw-r--r--usr/src/uts/common/io/igb/igb_api.h3
-rw-r--r--usr/src/uts/common/io/igb/igb_defines.h8
-rw-r--r--usr/src/uts/common/io/igb/igb_main.c31
-rw-r--r--usr/src/uts/common/io/igb/igb_nvm.c159
-rw-r--r--usr/src/uts/common/io/igb/igb_nvm.h4
-rw-r--r--usr/src/uts/common/io/ixgbe/ixgbe_main.c11
8 files changed, 222 insertions, 17 deletions
diff --git a/manifest b/manifest
index 0c351a8d87..449d12b53b 100644
--- a/manifest
+++ b/manifest
@@ -10405,6 +10405,7 @@ f usr/sbin/nscd 0555 root bin
f usr/sbin/nwamadm 0555 root bin
f usr/sbin/nwamcfg 0555 root bin
h usr/sbin/pbind=usr/lib/isaexec
+f usr/sbin/pcitool 0555 root bin
f usr/sbin/ping 4555 root bin
h usr/sbin/plockstat=usr/lib/isaexec
f usr/sbin/pmadm 0555 root sys
diff --git a/usr/src/uts/common/io/igb/igb_api.c b/usr/src/uts/common/io/igb/igb_api.c
index d151d0abec..da3a428214 100644
--- a/usr/src/uts/common/io/igb/igb_api.c
+++ b/usr/src/uts/common/io/igb/igb_api.c
@@ -984,9 +984,10 @@ e1000_read_mac_addr(struct e1000_hw *hw)
}
/*
- * e1000_read_pba_num - Read device part number
+ * e1000_read_pba_string - Read device part number string
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
+ * @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in pba_num.
@@ -994,9 +995,24 @@ e1000_read_mac_addr(struct e1000_hw *hw)
* generic version of this function.
*/
s32
-e1000_read_pba_num(struct e1000_hw *hw, u32 *pba_num)
+e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size)
{
- return (e1000_read_pba_num_generic(hw, pba_num));
+ return (e1000_read_pba_string_generic(hw, pba_num, pba_num_size));
+}
+
+/*
+ * e1000_read_pba_length - Read device part number string length
+ * @hw: pointer to the HW structure
+ * @pba_num_size: size of part number buffer
+ *
+ * Reads the product board assembly (PBA) number length from the EEPROM and
+ * stores the value in pba_num.
+ * Currently no func pointer exists and all implementations are handled in the
+ * generic version of this function.
+ */
+s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size)
+{
+ return e1000_read_pba_length_generic(hw, pba_num_size);
}
/*
diff --git a/usr/src/uts/common/io/igb/igb_api.h b/usr/src/uts/common/io/igb/igb_api.h
index 9574fc4593..fe5af41526 100644
--- a/usr/src/uts/common/io/igb/igb_api.h
+++ b/usr/src/uts/common/io/igb/igb_api.h
@@ -87,7 +87,8 @@ s32 e1000_phy_commit(struct e1000_hw *hw);
void e1000_power_up_phy(struct e1000_hw *hw);
void e1000_power_down_phy(struct e1000_hw *hw);
s32 e1000_read_mac_addr(struct e1000_hw *hw);
-s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *part_num);
+s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size);
+s32 e1000_read_pbe_length(struct e1000_hw *hw, u32 *pba_num_size);
void e1000_reload_nvm(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum(struct e1000_hw *hw);
s32 e1000_validate_nvm_checksum(struct e1000_hw *hw);
diff --git a/usr/src/uts/common/io/igb/igb_defines.h b/usr/src/uts/common/io/igb/igb_defines.h
index 9b238132dc..91230531f8 100644
--- a/usr/src/uts/common/io/igb/igb_defines.h
+++ b/usr/src/uts/common/io/igb/igb_defines.h
@@ -946,6 +946,9 @@ extern "C" {
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
#define E1000_ERR_MBX 15
+#define E1000_ERR_INVALID_ARGUMENT 16
+#define E1000_ERR_NO_SPACE 17
+#define E1000_ERR_NVM_PBA_SECTION 18
/* Loop limit on how long we wait for auto-negotiation to complete */
#define FIBER_LINK_UP_LIMIT 50
@@ -1230,8 +1233,11 @@ extern "C" {
#define NVM_SUM 0xBABA
#define NVM_MAC_ADDR_OFFSET 0
+#define NVM_OEM_OFFSET_0 6
+#define NVM_OEM_OFFSET_1 7
#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
+#define NVM_PBA_PTR_GUARD 0xFAFA
#define NVM_RESERVED_WORD 0xFFFF
#define NVM_PHY_CLASS_A 0x8000
#define NVM_SERDES_AMPLITUDE_MASK 0x000F
@@ -1240,6 +1246,8 @@ extern "C" {
#define NVM_WORD_SIZE_BASE_SHIFT 6
#define NVM_SWDPIO_EXT_SHIFT 4
+#define E1000_PBANUM_LENGTH 11
+
/* NVM Commands - Microwire */
#define NVM_READ_OPCODE_MICROWIRE 0x6 /* NVM read opcode */
#define NVM_WRITE_OPCODE_MICROWIRE 0x5 /* NVM write opcode */
diff --git a/usr/src/uts/common/io/igb/igb_main.c b/usr/src/uts/common/io/igb/igb_main.c
index 7864a3193f..19abbdf76a 100644
--- a/usr/src/uts/common/io/igb/igb_main.c
+++ b/usr/src/uts/common/io/igb/igb_main.c
@@ -1254,6 +1254,10 @@ igb_init_adapter(igb_t *igb)
struct e1000_hw *hw = &igb->hw;
uint32_t pba;
uint32_t high_water;
+ int oemid[2];
+ uint16_t nvmword;
+ u8 pbanum[E1000_PBANUM_LENGTH];
+ char eepromver[5]; /* f.ff */
int i;
ASSERT(mutex_owned(&igb->gen_lock));
@@ -1397,6 +1401,33 @@ igb_init_adapter(igb_t *igb)
E1000_WRITE_REG(hw, E1000_EITR(i), igb->intr_throttling[i]);
/*
+ * Read identifying information and place in devinfo.
+ */
+ nvmword = 0xffff;
+ (void) e1000_read_nvm(&igb->hw, NVM_OEM_OFFSET_0, 1, &nvmword);
+ oemid[0] = (int)nvmword;
+ (void) e1000_read_nvm(&igb->hw, NVM_OEM_OFFSET_1, 1, &nvmword);
+ oemid[1] = (int)nvmword;
+ (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, igb->dip,
+ "oem-identifier", oemid, 2);
+
+ pbanum[0] = '\0';
+ (void) e1000_read_pba_string(&igb->hw, pbanum, sizeof (pbanum));
+ if (*pbanum != '\0') {
+ (void) ddi_prop_update_string(DDI_DEV_T_NONE, igb->dip,
+ "printed-board-assembly", (char *)pbanum);
+ }
+
+ nvmword = 0xffff;
+ (void) e1000_read_nvm(&igb->hw, NVM_VERSION, 1, &nvmword);
+ if ((nvmword & 0xf00) == 0) {
+ (void) snprintf(eepromver, sizeof (eepromver), "%x.%x",
+ (nvmword & 0xf000) >> 12, (nvmword & 0xff));
+ (void) ddi_prop_update_string(DDI_DEV_T_NONE, igb->dip,
+ "nvm-version", eepromver);
+ }
+
+ /*
* Save the state of the phy
*/
igb_get_phy_state(igb);
diff --git a/usr/src/uts/common/io/igb/igb_nvm.c b/usr/src/uts/common/io/igb/igb_nvm.c
index 71901e0263..6f809a9338 100644
--- a/usr/src/uts/common/io/igb/igb_nvm.c
+++ b/usr/src/uts/common/io/igb/igb_nvm.c
@@ -728,37 +728,172 @@ out:
}
/*
- * e1000_read_pba_num_generic - Read device part number
+ * e1000_read_pba_string_generic - Read device part number
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
+ * @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in pba_num.
*/
-s32
-e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num)
+s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
+ u32 pba_num_size)
{
- s32 ret_val;
+ s32 ret_val;
u16 nvm_data;
+ u16 pba_ptr;
+ u16 offset;
+ u16 length;
+
+ DEBUGFUNC("e1000_read_pba_string_generic");
- DEBUGFUNC("e1000_read_pba_num_generic");
+ if (pba_num == NULL) {
+ DEBUGOUT("PBA string buffer was null\n");
+ return (-E1000_ERR_INVALID_ARGUMENT);
+ }
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
- goto out;
+ return (ret_val);
}
- *pba_num = (u32)(nvm_data << 16);
- ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
- goto out;
+ return (ret_val);
}
- *pba_num |= nvm_data;
-out:
- return (ret_val);
+ /* if nvm_data is not ptr guard the PBA must be in legacy format which
+ * means pba_ptr is actually our second data word for the PBA number
+ * and we can decode it into an ascii string
+ */
+ if (nvm_data != NVM_PBA_PTR_GUARD) {
+ DEBUGOUT("NVM PBA number is not stored as string\n");
+
+ /* make sure callers buffer is big enough to store the PBA */
+ if (pba_num_size < E1000_PBANUM_LENGTH) {
+ DEBUGOUT("PBA string buffer too small\n");
+ return (-E1000_ERR_NO_SPACE);
+ }
+
+ /* extract hex string from data and pba_ptr */
+ pba_num[0] = (nvm_data >> 12) & 0xF;
+ pba_num[1] = (nvm_data >> 8) & 0xF;
+ pba_num[2] = (nvm_data >> 4) & 0xF;
+ pba_num[3] = nvm_data & 0xF;
+ pba_num[4] = (pba_ptr >> 12) & 0xF;
+ pba_num[5] = (pba_ptr >> 8) & 0xF;
+ pba_num[6] = '-';
+ pba_num[7] = 0;
+ pba_num[8] = (pba_ptr >> 4) & 0xF;
+ pba_num[9] = pba_ptr & 0xF;
+
+ /* put a null character on the end of our string */
+ pba_num[10] = '\0';
+
+ /* switch all the data but the '-' to hex char */
+ for (offset = 0; offset < 10; offset++) {
+ if (pba_num[offset] < 0xA)
+ pba_num[offset] += '0';
+ else if (pba_num[offset] < 0x10)
+ pba_num[offset] += 'A' - 0xA;
+ }
+
+ return (E1000_SUCCESS);
+ }
+
+ ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ return (ret_val);
+ }
+
+ if (length == 0xFFFF || length == 0) {
+ DEBUGOUT("NVM PBA number section invalid length\n");
+ return (-E1000_ERR_NVM_PBA_SECTION);
+ }
+ /* check if pba_num buffer is big enough */
+ if (pba_num_size < (((u32)length * 2) - 1)) {
+ DEBUGOUT("PBA string buffer too small\n");
+ return (-E1000_ERR_NO_SPACE);
+ }
+
+ /* trim pba length from start of string */
+ pba_ptr++;
+ length--;
+
+ for (offset = 0; offset < length; offset++) {
+ ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ return (ret_val);
+ }
+ pba_num[offset * 2] = (u8)(nvm_data >> 8);
+ pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
+ }
+ pba_num[offset * 2] = '\0';
+
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_read_pba_length_generic - Read device part number length
+ * @hw: pointer to the HW structure
+ * @pba_num_size: size of part number buffer
+ *
+ * Reads the product board assembly (PBA) number length from the EEPROM and
+ * stores the value in pba_num_size.
+ */
+s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
+{
+ s32 ret_val;
+ u16 nvm_data;
+ u16 pba_ptr;
+ u16 length;
+
+ DEBUGFUNC("e1000_read_pba_length_generic");
+
+ if (pba_num_size == NULL) {
+ DEBUGOUT("PBA buffer size was null\n");
+ return (-E1000_ERR_INVALID_ARGUMENT);
+ }
+
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ return (ret_val);
+ }
+
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ return (ret_val);
+ }
+
+ /* if data is not ptr guard the PBA must be in legacy format */
+ if (nvm_data != NVM_PBA_PTR_GUARD) {
+ *pba_num_size = E1000_PBANUM_LENGTH;
+ return (E1000_SUCCESS);
+ }
+
+ ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ return (ret_val);
+ }
+
+ if (length == 0xFFFF || length == 0) {
+ DEBUGOUT("NVM PBA number section invalid length\n");
+ return (-E1000_ERR_NVM_PBA_SECTION);
+ }
+
+ /* Convert from length in u16 values to u8 chars, add 1 for NULL,
+ * and subtract 2 because length field is included in length.
+ */
+ *pba_num_size = ((u32)length * 2) - 1;
+
+ return (E1000_SUCCESS);
}
/*
diff --git a/usr/src/uts/common/io/igb/igb_nvm.h b/usr/src/uts/common/io/igb/igb_nvm.h
index e0de52b748..ceb42a4f10 100644
--- a/usr/src/uts/common/io/igb/igb_nvm.h
+++ b/usr/src/uts/common/io/igb/igb_nvm.h
@@ -45,7 +45,9 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw);
s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
-s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num);
+s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
+ u32 pba_num_size);
+s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size);
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words,
diff --git a/usr/src/uts/common/io/ixgbe/ixgbe_main.c b/usr/src/uts/common/io/ixgbe/ixgbe_main.c
index 791df9eff8..848e3470c7 100644
--- a/usr/src/uts/common/io/ixgbe/ixgbe_main.c
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_main.c
@@ -1246,6 +1246,7 @@ static int
ixgbe_init(ixgbe_t *ixgbe)
{
struct ixgbe_hw *hw = &ixgbe->hw;
+ u8 pbanum[IXGBE_PBANUM_LENGTH];
mutex_enter(&ixgbe->gen_lock);
@@ -1308,6 +1309,16 @@ ixgbe_init(ixgbe_t *ixgbe)
goto init_fail;
}
+ /*
+ * Read identifying information and place in devinfo.
+ */
+ pbanum[0] = '\0';
+ (void) ixgbe_read_pba_string(hw, pbanum, sizeof (pbanum));
+ if (*pbanum != '\0') {
+ (void) ddi_prop_update_string(DDI_DEV_T_NONE, ixgbe->dip,
+ "printed-board-assembly", (char *)pbanum);
+ }
+
if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
goto init_fail;
}