summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2016-11-17 20:44:05 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2016-11-17 20:44:05 +0000
commit78cd421d84646ec0ce1a76cca391d854e48b22a4 (patch)
tree5c695b6364ff50bad18da4505e181adb94206701 /sys/dev
parent244408ba40a32ede2f8ad06cd569db93d55ad4c8 (diff)
EEPROM code refactoring for X540
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/ixgbe.c405
-rw-r--r--sys/dev/pci/ixgbe.h5
-rw-r--r--sys/dev/pci/ixgbe_type.h5
-rw-r--r--sys/dev/pci/ixgbe_x540.c142
4 files changed, 356 insertions, 201 deletions
diff --git a/sys/dev/pci/ixgbe.c b/sys/dev/pci/ixgbe.c
index 462c79e7458..23128bc744b 100644
--- a/sys/dev/pci/ixgbe.c
+++ b/sys/dev/pci/ixgbe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ixgbe.c,v 1.17 2016/11/17 19:26:57 mikeb Exp $ */
+/* $OpenBSD: ixgbe.c,v 1.18 2016/11/17 20:44:04 mikeb Exp $ */
/******************************************************************************
@@ -895,27 +895,25 @@ int32_t ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
}
/**
- * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
* @hw: pointer to hardware structure
* @offset: offset within the EEPROM to be written to
- * @data: 16 bit word to be written to the EEPROM
+ * @words: number of word(s)
+ * @data: 16 bit word(s) to be written to the EEPROM
*
* If ixgbe_eeprom_update_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum.
**/
-int32_t ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t data)
+static int32_t ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, uint16_t offset,
+ uint16_t words, uint16_t *data)
{
int32_t status;
+ uint16_t word;
+ uint16_t page_size;
+ uint16_t i;
uint8_t write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
- DEBUGFUNC("ixgbe_write_eeprom_generic");
-
- hw->eeprom.ops.init_params(hw);
-
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
+ DEBUGFUNC("ixgbe_write_eeprom_buffer_bit_bang");
/* Prepare the EEPROM for writing */
status = ixgbe_acquire_eeprom(hw);
@@ -928,54 +926,71 @@ int32_t ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_
}
if (status == IXGBE_SUCCESS) {
- ixgbe_standby_eeprom(hw);
-
- /* Send the WRITE ENABLE command (8 bit opcode ) */
- ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
- IXGBE_EEPROM_OPCODE_BITS);
-
- ixgbe_standby_eeprom(hw);
-
- /*
- * Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((hw->eeprom.address_bits == 8) && (offset >= 128))
- write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
- /* Send the Write command (8-bit opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, write_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (uint16_t)(offset*2),
- hw->eeprom.address_bits);
+ /* Send the WRITE ENABLE command (8 bit opcode ) */
+ ixgbe_shift_out_eeprom_bits(hw,
+ IXGBE_EEPROM_WREN_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
- /* Send the data */
- data = (data >> 8) | (data << 8);
- ixgbe_shift_out_eeprom_bits(hw, data, 16);
- ixgbe_standby_eeprom(hw);
+ ixgbe_standby_eeprom(hw);
+ /*
+ * Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the Write command (8-bit opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (uint16_t)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ page_size = hw->eeprom.word_page_size;
+
+ /* Send the data in burst via SPI*/
+ do {
+ word = data[i];
+ word = (word >> 8) | (word << 8);
+ ixgbe_shift_out_eeprom_bits(hw, word, 16);
+
+ if (page_size == 0)
+ break;
+
+ /* do not wrap around page */
+ if (((offset + i) & (page_size - 1)) ==
+ (page_size - 1))
+ break;
+ } while (++i < words);
+
+ ixgbe_standby_eeprom(hw);
+ msec_delay(10);
+ }
/* Done with writing - release the EEPROM */
ixgbe_release_eeprom(hw);
}
-out:
return status;
}
/**
- * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
* @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be read
- * @data: read 16 bit value from EEPROM
+ * @offset: offset within the EEPROM to be written to
+ * @data: 16 bit word to be written to the EEPROM
*
- * Reads 16 bit value from EEPROM through bit-bang method
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
**/
-int32_t ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, uint16_t offset,
- uint16_t *data)
+int32_t ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t data)
{
int32_t status;
- uint16_t word_in;
- uint8_t read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+
+ DEBUGFUNC("ixgbe_write_eeprom_generic");
hw->eeprom.ops.init_params(hw);
@@ -984,6 +999,31 @@ int32_t ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, uint16_t offset,
goto out;
}
+ status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @words: number of word(s)
+ * @data: read 16 bit word(s) from EEPROM
+ *
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
+ **/
+static int32_t ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, uint16_t offset,
+ uint16_t words, uint16_t *data)
+{
+ int32_t status;
+ uint16_t word_in;
+ uint8_t read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+ uint16_t i;
+
+ DEBUGFUNC("ixgbe_read_eeprom_buffer_bit_bang");
+
/* Prepare the EEPROM for reading */
status = ixgbe_acquire_eeprom(hw);
@@ -995,104 +1035,176 @@ int32_t ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, uint16_t offset,
}
if (status == IXGBE_SUCCESS) {
- ixgbe_standby_eeprom(hw);
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
+ /*
+ * Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the READ command (opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (uint16_t)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ /* Read the data. */
+ word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+ data[i] = (word_in >> 8) | (word_in << 8);
+ }
- /*
- * Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((hw->eeprom.address_bits == 8) && (offset >= 128))
- read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+ /* End this read operation */
+ ixgbe_release_eeprom(hw);
+ }
- /* Send the READ command (opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, read_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (uint16_t)(offset*2),
- hw->eeprom.address_bits);
+ return status;
+}
- /* Read the data. */
- word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
- *data = (word_in >> 8) | (word_in << 8);
+/**
+ * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @data: read 16 bit value from EEPROM
+ *
+ * Reads 16 bit value from EEPROM through bit-bang method
+ **/
+int32_t ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, uint16_t offset,
+ uint16_t *data)
+{
+ int32_t status;
- /* End this read operation */
- ixgbe_release_eeprom(hw);
+ DEBUGFUNC("ixgbe_read_eeprom_bit_bang_generic");
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
}
+ status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+
out:
return status;
}
/**
- * ixgbe_read_eerd_generic - Read EEPROM word using EERD
+ * ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
* @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EEPROM
+ * @offset: offset of word in the EEPROM to read
+ * @words: number of word(s)
+ * @data: 16 bit word(s) from the EEPROM
*
- * Reads a 16 bit word from the EEPROM using the EERD register.
+ * Reads a 16 bit word(s) from the EEPROM using the EERD register.
**/
-int32_t ixgbe_read_eerd_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t *data)
+int32_t ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, uint16_t offset,
+ uint16_t words, uint16_t *data)
{
uint32_t eerd;
- int32_t status;
+ int32_t status = IXGBE_SUCCESS;
+ uint32_t i;
+
+ DEBUGFUNC("ixgbe_read_eerd_buffer_generic");
hw->eeprom.ops.init_params(hw);
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
+ goto out;
+ }
+
if (offset >= hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
+ ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
goto out;
}
- eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) +
- IXGBE_EEPROM_RW_REG_START;
+ for (i = 0; i < words; i++) {
+ eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
+ IXGBE_EEPROM_RW_REG_START;
- IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
-
- if (status == IXGBE_SUCCESS)
- *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
- IXGBE_EEPROM_RW_REG_DATA);
- else
- DEBUGOUT("Eeprom read timed out\n");
+ IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
+ if (status == IXGBE_SUCCESS) {
+ data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
+ IXGBE_EEPROM_RW_REG_DATA);
+ } else {
+ DEBUGOUT("Eeprom read timed out\n");
+ goto out;
+ }
+ }
out:
return status;
}
/**
- * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ * ixgbe_read_eerd_generic - Read EEPROM word using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EEPROM
+ *
+ * Reads a 16 bit word from the EEPROM using the EERD register.
+ **/
+int32_t ixgbe_read_eerd_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t *data)
+{
+ return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
+}
+
+/**
+ * ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
* @hw: pointer to hardware structure
* @offset: offset of word in the EEPROM to write
- * @data: word write to the EEPROM
+ * @words: number of word(s)
+ * @data: word(s) write to the EEPROM
*
- * Write a 16 bit word to the EEPROM using the EEWR register.
+ * Write a 16 bit word(s) to the EEPROM using the EEWR register.
**/
-int32_t ixgbe_write_eewr_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t data)
+int32_t ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, uint16_t offset,
+ uint16_t words, uint16_t *data)
{
uint32_t eewr;
- int32_t status;
+ int32_t status = IXGBE_SUCCESS;
+ uint16_t i;
+
+ DEBUGFUNC("ixgbe_write_eewr_generic");
hw->eeprom.ops.init_params(hw);
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM words");
+ goto out;
+ }
+
if (offset >= hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
+ ERROR_REPORT1(IXGBE_ERROR_ARGUMENT, "Invalid EEPROM offset");
goto out;
}
- eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
- (data << IXGBE_EEPROM_RW_REG_DATA) | IXGBE_EEPROM_RW_REG_START;
+ for (i = 0; i < words; i++) {
+ eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
+ (data[i] << IXGBE_EEPROM_RW_REG_DATA) |
+ IXGBE_EEPROM_RW_REG_START;
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != IXGBE_SUCCESS) {
- DEBUGOUT("Eeprom write EEWR timed out\n");
- goto out;
- }
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != IXGBE_SUCCESS) {
+ DEBUGOUT("Eeprom write EEWR timed out\n");
+ goto out;
+ }
- IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+ IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != IXGBE_SUCCESS) {
- DEBUGOUT("Eeprom write EEWR timed out\n");
- goto out;
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != IXGBE_SUCCESS) {
+ DEBUGOUT("Eeprom write EEWR timed out\n");
+ goto out;
+ }
}
out:
@@ -1100,6 +1212,19 @@ out:
}
/**
+ * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+int32_t ixgbe_write_eewr_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t data)
+{
+ return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
+}
+
+/**
* ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
* @hw: pointer to hardware structure
* @ee_reg: EEPROM flag for polling
@@ -1372,7 +1497,7 @@ void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
* @count: number of bits to shift out
**/
void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, uint16_t data,
- uint16_t count)
+ uint16_t count)
{
uint32_t eec;
uint32_t mask;
@@ -1532,8 +1657,10 @@ void ixgbe_release_eeprom(struct ixgbe_hw *hw)
/**
* ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
* @hw: pointer to hardware structure
+ *
+ * Returns a negative error code on error, or the 16-bit checksum
**/
-uint16_t ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
+int32_t ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
{
uint16_t i;
uint16_t j;
@@ -1546,33 +1673,44 @@ uint16_t ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
/* Include 0x0-0x3F in the checksum */
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (hw->eeprom.ops.read(hw, i, &word) != IXGBE_SUCCESS) {
+ if (hw->eeprom.ops.read(hw, i, &word)) {
DEBUGOUT("EEPROM read failed\n");
- break;
+ return IXGBE_ERR_EEPROM;
}
checksum += word;
}
/* Include all data from pointers except for the fw pointer */
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
- hw->eeprom.ops.read(hw, i, &pointer);
+ if (hw->eeprom.ops.read(hw, i, &pointer)) {
+ DEBUGOUT("EEPROM read failed\n");
+ return IXGBE_ERR_EEPROM;
+ }
- /* Make sure the pointer seems valid */
- if (pointer != 0xFFFF && pointer != 0) {
- hw->eeprom.ops.read(hw, pointer, &length);
+ /* If the pointer seems invalid */
+ if (pointer == 0xFFFF || pointer == 0)
+ continue;
- if (length != 0xFFFF && length != 0) {
- for (j = pointer+1; j <= pointer+length; j++) {
- hw->eeprom.ops.read(hw, j, &word);
- checksum += word;
- }
+ if (hw->eeprom.ops.read(hw, pointer, &length)) {
+ DEBUGOUT("EEPROM read failed\n");
+ return IXGBE_ERR_EEPROM;
+ }
+
+ if (length == 0xFFFF || length == 0)
+ continue;
+
+ for (j = pointer + 1; j <= pointer + length; j++) {
+ if (hw->eeprom.ops.read(hw, j, &word)) {
+ DEBUGOUT("EEPROM read failed\n");
+ return IXGBE_ERR_EEPROM;
}
+ checksum += word;
}
}
checksum = (uint16_t)IXGBE_EEPROM_SUM - checksum;
- return checksum;
+ return (int32_t)checksum;
}
/**
@@ -1597,26 +1735,33 @@ int32_t ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);
+ if (status) {
+ DEBUGOUT("EEPROM read failed\n");
+ return status;
+ }
- if (status == IXGBE_SUCCESS) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
-
- hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
+ status = hw->eeprom.ops.calc_checksum(hw);
+ if (status < 0)
+ return status;
- /*
- * Verify read checksum from EEPROM is the same as
- * calculated checksum
- */
- if (read_checksum != checksum)
- status = IXGBE_ERR_EEPROM_CHECKSUM;
+ checksum = (uint16_t)(status & 0xffff);
- /* If the user cares, return the calculated checksum */
- if (checksum_val)
- *checksum_val = checksum;
- } else {
+ status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
+ if (status) {
DEBUGOUT("EEPROM read failed\n");
+ return status;
}
+ /* Verify read checksum from EEPROM is the same as
+ * calculated checksum
+ */
+ if (read_checksum != checksum)
+ status = IXGBE_ERR_EEPROM_CHECKSUM;
+
+ /* If the user cares, return the calculated checksum */
+ if (checksum_val)
+ *checksum_val = checksum;
+
return status;
}
@@ -1636,15 +1781,19 @@ int32_t ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status == IXGBE_SUCCESS) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
- status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
- checksum);
- } else {
+ if (status) {
DEBUGOUT("EEPROM read failed\n");
+ return status;
}
+ status = hw->eeprom.ops.calc_checksum(hw);
+ if (status < 0)
+ return status;
+
+ checksum = (uint16_t)(status & 0xffff);
+
+ status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum);
+
return status;
}
diff --git a/sys/dev/pci/ixgbe.h b/sys/dev/pci/ixgbe.h
index abef797ceea..959e368d349 100644
--- a/sys/dev/pci/ixgbe.h
+++ b/sys/dev/pci/ixgbe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ixgbe.h,v 1.24 2016/11/17 19:26:57 mikeb Exp $ */
+/* $OpenBSD: ixgbe.h,v 1.25 2016/11/17 20:44:04 mikeb Exp $ */
/******************************************************************************
@@ -176,7 +176,7 @@ int32_t ixgbe_read_eerd_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t *
int32_t ixgbe_write_eewr_generic(struct ixgbe_hw *hw, uint16_t offset, uint16_t data);
int32_t ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, uint16_t offset,
uint16_t *data);
-uint16_t ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
+int32_t ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
int32_t ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
uint16_t *checksum_val);
int32_t ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
@@ -340,7 +340,6 @@ int32_t ixgbe_check_for_msg(struct ixgbe_hw *, uint16_t);
int32_t ixgbe_check_for_ack(struct ixgbe_hw *, uint16_t);
int32_t ixgbe_check_for_rst(struct ixgbe_hw *, uint16_t);
void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw);
-void ixgbe_init_mbx_params_vf(struct ixgbe_hw *);
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
#endif /* _IXGBE_H_ */
diff --git a/sys/dev/pci/ixgbe_type.h b/sys/dev/pci/ixgbe_type.h
index 47eb87c6aaf..ba8f578609f 100644
--- a/sys/dev/pci/ixgbe_type.h
+++ b/sys/dev/pci/ixgbe_type.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ixgbe_type.h,v 1.26 2016/11/17 19:26:57 mikeb Exp $ */
+/* $OpenBSD: ixgbe_type.h,v 1.27 2016/11/17 20:44:04 mikeb Exp $ */
/******************************************************************************
@@ -3386,7 +3386,7 @@ struct ixgbe_eeprom_operations {
int32_t (*write)(struct ixgbe_hw *, uint16_t, uint16_t);
int32_t (*validate_checksum)(struct ixgbe_hw *, uint16_t *);
int32_t (*update_checksum)(struct ixgbe_hw *);
- uint16_t (*calc_checksum)(struct ixgbe_hw *);
+ int32_t (*calc_checksum)(struct ixgbe_hw *);
};
struct ixgbe_mac_operations {
@@ -3676,7 +3676,6 @@ struct ixgbe_hw {
bool adapter_stopped;
int api_version;
bool force_full_reset;
- bool mng_fw_enabled;
};
/* Error Codes */
diff --git a/sys/dev/pci/ixgbe_x540.c b/sys/dev/pci/ixgbe_x540.c
index 511d7bf7345..dcb7a2d1561 100644
--- a/sys/dev/pci/ixgbe_x540.c
+++ b/sys/dev/pci/ixgbe_x540.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: ixgbe_x540.c,v 1.7 2016/11/17 19:26:57 mikeb Exp $ */
+/* $OpenBSD: ixgbe_x540.c,v 1.8 2016/11/17 20:44:04 mikeb Exp $ */
/******************************************************************************
- Copyright (c) 2001-2013, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/* FreeBSD: src/sys/dev/ixgbe/ixgbe_x540.c 251964 Jun 18 21:28:19 2013 UTC */
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x540.c 295093 2016-01-31 15:14:23Z smh $*/
#include <dev/pci/ixgbe.h>
#include <dev/pci/ixgbe_type.h>
@@ -61,7 +61,7 @@ int32_t ixgbe_read_eerd_X540(struct ixgbe_hw *hw, uint16_t offset, uint16_t *dat
int32_t ixgbe_write_eewr_X540(struct ixgbe_hw *hw, uint16_t offset, uint16_t data);
int32_t ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw);
int32_t ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, uint16_t *checksum_val);
-uint16_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw);
+int32_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw);
int32_t ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, uint16_t mask);
void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, uint16_t mask);
@@ -378,18 +378,20 @@ int32_t ixgbe_write_eewr_X540(struct ixgbe_hw *hw, uint16_t offset, uint16_t dat
* be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
*
* @hw: pointer to hardware structure
+ *
+ * Returns a negative error code on error, or the 16-bit checksum
**/
-uint16_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
+int32_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
{
- uint16_t i;
- uint16_t j;
+ uint16_t i, j;
uint16_t checksum = 0;
uint16_t length = 0;
uint16_t pointer = 0;
uint16_t word = 0;
+ uint16_t checksum_last_word = IXGBE_EEPROM_CHECKSUM;
+ uint16_t ptr_start = IXGBE_PCIE_ANALOG_PTR;
- /*
- * Do not use hw->eeprom.ops.read because we do not want to take
+ /* Do not use hw->eeprom.ops.read because we do not want to take
* the synchronization semaphores here. Instead use
* ixgbe_read_eerd_generic
*/
@@ -397,25 +399,25 @@ uint16_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540");
/* Include 0x0-0x3F in the checksum */
- for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (ixgbe_read_eerd_generic(hw, i, &word) != IXGBE_SUCCESS) {
+ for (i = 0; i <= checksum_last_word; i++) {
+ if (ixgbe_read_eerd_generic(hw, i, &word)) {
DEBUGOUT("EEPROM read failed\n");
- break;
+ return IXGBE_ERR_EEPROM;
}
- checksum += word;
+ if (i != IXGBE_EEPROM_CHECKSUM)
+ checksum += word;
}
- /*
- * Include all data from pointers 0x3, 0x6-0xE. This excludes the
+ /* Include all data from pointers 0x3, 0x6-0xE. This excludes the
* FW, PHY module, and PCIe Expansion/Option ROM pointers.
*/
- for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
+ for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
continue;
- if (ixgbe_read_eerd_generic(hw, i, &pointer) != IXGBE_SUCCESS) {
+ if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
DEBUGOUT("EEPROM read failed\n");
- break;
+ return IXGBE_ERR_EEPROM;
}
/* Skip pointer section if the pointer is invalid. */
@@ -423,10 +425,9 @@ uint16_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
pointer >= hw->eeprom.word_size)
continue;
- if (ixgbe_read_eerd_generic(hw, pointer, &length) !=
- IXGBE_SUCCESS) {
+ if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
DEBUGOUT("EEPROM read failed\n");
- break;
+ return IXGBE_ERR_EEPROM;
}
/* Skip pointer section if length is invalid. */
@@ -434,11 +435,10 @@ uint16_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
(pointer + length) >= hw->eeprom.word_size)
continue;
- for (j = pointer+1; j <= pointer+length; j++) {
- if (ixgbe_read_eerd_generic(hw, j, &word) !=
- IXGBE_SUCCESS) {
+ for (j = pointer + 1; j <= pointer + length; j++) {
+ if (ixgbe_read_eerd_generic(hw, j, &word)) {
DEBUGOUT("EEPROM read failed\n");
- break;
+ return IXGBE_ERR_EEPROM;
}
checksum += word;
}
@@ -446,7 +446,7 @@ uint16_t ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
checksum = (uint16_t)IXGBE_EEPROM_SUM - checksum;
- return checksum;
+ return (int32_t)checksum;
}
/**
@@ -471,39 +471,43 @@ int32_t ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status != IXGBE_SUCCESS) {
+ if (status) {
DEBUGOUT("EEPROM read failed\n");
- goto out;
+ return status;
}
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- IXGBE_SUCCESS) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
- /*
- * Do not use hw->eeprom.ops.read because we do not want to take
- * the synchronization semaphores twice here.
- */
- ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
- &read_checksum);
+ status = hw->eeprom.ops.calc_checksum(hw);
+ if (status < 0)
+ goto out;
- /*
- * Verify read checksum from EEPROM is the same as
- * calculated checksum
- */
- if (read_checksum != checksum)
- status = IXGBE_ERR_EEPROM_CHECKSUM;
+ checksum = (uint16_t)(status & 0xffff);
- /* If the user cares, return the calculated checksum */
- if (checksum_val)
- *checksum_val = checksum;
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- } else {
- status = IXGBE_ERR_SWFW_SYNC;
+ /* Do not use hw->eeprom.ops.read because we do not want to take
+ * the synchronization semaphores twice here.
+ */
+ status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
+ &read_checksum);
+ if (status)
+ goto out;
+
+ /* Verify read checksum from EEPROM is the same as
+ * calculated checksum
+ */
+ if (read_checksum != checksum) {
+ DEBUGOUT("Invalid EEPROM checksum\n");
+ status = IXGBE_ERR_EEPROM_CHECKSUM;
}
+ /* If the user cares, return the calculated checksum */
+ if (checksum_val)
+ *checksum_val = checksum;
+
out:
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+
return status;
}
@@ -527,27 +531,31 @@ int32_t ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status != IXGBE_SUCCESS)
+ if (status) {
DEBUGOUT("EEPROM read failed\n");
+ return status;
+ }
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- IXGBE_SUCCESS) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
- /*
- * Do not use hw->eeprom.ops.write because we do not want to
- * take the synchronization semaphores twice here.
- */
- status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM,
- checksum);
+ status = hw->eeprom.ops.calc_checksum(hw);
+ if (status < 0)
+ goto out;
- if (status == IXGBE_SUCCESS)
- status = ixgbe_update_flash_X540(hw);
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- } else {
- status = IXGBE_ERR_SWFW_SYNC;
- }
+ checksum = (uint16_t)(status & 0xffff);
+
+ /* Do not use hw->eeprom.ops.write because we do not want to
+ * take the synchronization semaphores twice here.
+ */
+ status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
+ if (status)
+ goto out;
+
+ status = ixgbe_update_flash_X540(hw);
+
+out:
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
}