diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2013-05-01 16:06:23 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2013-05-01 23:47:18 +0000 |
commit | 21a6b03bbd82147f869197594e8b3ea8a7600eb1 (patch) | |
tree | 91678f757ddd99bda49fa8e4e08d4a635a66b0e3 | |
parent | 933b08887aa05e6cd9c8fa845b60319533d2b88d (diff) | |
download | illumos-joyent-21a6b03bbd82147f869197594e8b3ea8a7600eb1.tar.gz |
OS-2160 want FW config version number for igb and ixgberelease-20130502
OS-2186 ship pcitool
-rw-r--r-- | manifest | 1 | ||||
-rw-r--r-- | usr/src/uts/common/io/igb/igb_api.c | 22 | ||||
-rw-r--r-- | usr/src/uts/common/io/igb/igb_api.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/igb/igb_defines.h | 8 | ||||
-rw-r--r-- | usr/src/uts/common/io/igb/igb_main.c | 31 | ||||
-rw-r--r-- | usr/src/uts/common/io/igb/igb_nvm.c | 159 | ||||
-rw-r--r-- | usr/src/uts/common/io/igb/igb_nvm.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/io/ixgbe/ixgbe_main.c | 11 |
8 files changed, 222 insertions, 17 deletions
@@ -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; } |