aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorCarolyn Wyborny <carolyn.wyborny@intel.com>2013-07-17 15:02:53 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-08-22 05:26:00 -0400
commitef3a009297c50876980f21060aee61e8b516a990 (patch)
tree9875242d44568e9a3c66f460a9a8c778bd658dfb /drivers/net
parent5a823d8cdd0e16081bc09a03fa253b9750c4b034 (diff)
igb: Refactor NVM read functions to accommodate devices with no flash
This patch refactors NVM read functions in order to accommodate i210 devices that do not have a flash. Previously, this was not supported on i210 devices. 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')
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h5
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c110
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.h3
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c19
4 files changed, 77 insertions, 60 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 179935576e14..452219811cc3 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -628,6 +628,11 @@
628#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) 628#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0)
629#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 629#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06
630#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 630#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01
631#define E1000_I210_FLASH_SECTOR_SIZE 0x1000 /* 4KB FLASH sector unit size */
632/* Secure FLASH mode requires removing MSb */
633#define E1000_I210_FW_PTR_MASK 0x7FFF
634/* Firmware code revision field word offset*/
635#define E1000_I210_FW_VER_OFFSET 328
631#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ 636#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */
632#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/ 637#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/
633#define E1000_FLUDONE_ATTEMPTS 20000 638#define E1000_FLUDONE_ATTEMPTS 20000
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index 4aebf35a0d75..0c0393316a3a 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -335,57 +335,101 @@ s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
335} 335}
336 336
337/** 337/**
338 * igb_read_nvm_i211 - Read NVM wrapper function for I211 338 * igb_read_invm_word_i210 - Reads OTP
339 * @hw: pointer to the HW structure
340 * @address: the word address (aka eeprom offset) to read
341 * @data: pointer to the data read
342 *
343 * Reads 16-bit words from the OTP. Return error when the word is not
344 * stored in OTP.
345 **/
346static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
347{
348 s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
349 u32 invm_dword;
350 u16 i;
351 u8 record_type, word_address;
352
353 for (i = 0; i < E1000_INVM_SIZE; i++) {
354 invm_dword = rd32(E1000_INVM_DATA_REG(i));
355 /* Get record type */
356 record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
357 if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
358 break;
359 if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
360 i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
361 if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
362 i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
363 if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
364 word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
365 if (word_address == address) {
366 *data = INVM_DWORD_TO_WORD_DATA(invm_dword);
367 hw_dbg("Read INVM Word 0x%02x = %x",
368 address, *data);
369 status = E1000_SUCCESS;
370 break;
371 }
372 }
373 }
374 if (status != E1000_SUCCESS)
375 hw_dbg("Requested word 0x%02x not found in OTP\n", address);
376 return status;
377}
378
379/**
380 * igb_read_invm_i210 - Read invm wrapper function for I210/I211
339 * @hw: pointer to the HW structure 381 * @hw: pointer to the HW structure
340 * @words: number of words to read 382 * @words: number of words to read
341 * @data: pointer to the data read 383 * @data: pointer to the data read
342 * 384 *
343 * Wrapper function to return data formerly found in the NVM. 385 * Wrapper function to return data formerly found in the NVM.
344 **/ 386 **/
345s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, 387static s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset,
346 u16 *data) 388 u16 words __always_unused, u16 *data)
347{ 389{
348 s32 ret_val = E1000_SUCCESS; 390 s32 ret_val = E1000_SUCCESS;
349 391
350 /* Only the MAC addr is required to be present in the iNVM */ 392 /* Only the MAC addr is required to be present in the iNVM */
351 switch (offset) { 393 switch (offset) {
352 case NVM_MAC_ADDR: 394 case NVM_MAC_ADDR:
353 ret_val = igb_read_invm_i211(hw, offset, &data[0]); 395 ret_val = igb_read_invm_word_i210(hw, (u8)offset, &data[0]);
354 ret_val |= igb_read_invm_i211(hw, offset+1, &data[1]); 396 ret_val |= igb_read_invm_word_i210(hw, (u8)offset+1,
355 ret_val |= igb_read_invm_i211(hw, offset+2, &data[2]); 397 &data[1]);
398 ret_val |= igb_read_invm_word_i210(hw, (u8)offset+2,
399 &data[2]);
356 if (ret_val != E1000_SUCCESS) 400 if (ret_val != E1000_SUCCESS)
357 hw_dbg("MAC Addr not found in iNVM\n"); 401 hw_dbg("MAC Addr not found in iNVM\n");
358 break; 402 break;
359 case NVM_INIT_CTRL_2: 403 case NVM_INIT_CTRL_2:
360 ret_val = igb_read_invm_i211(hw, (u8)offset, data); 404 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
361 if (ret_val != E1000_SUCCESS) { 405 if (ret_val != E1000_SUCCESS) {
362 *data = NVM_INIT_CTRL_2_DEFAULT_I211; 406 *data = NVM_INIT_CTRL_2_DEFAULT_I211;
363 ret_val = E1000_SUCCESS; 407 ret_val = E1000_SUCCESS;
364 } 408 }
365 break; 409 break;
366 case NVM_INIT_CTRL_4: 410 case NVM_INIT_CTRL_4:
367 ret_val = igb_read_invm_i211(hw, (u8)offset, data); 411 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
368 if (ret_val != E1000_SUCCESS) { 412 if (ret_val != E1000_SUCCESS) {
369 *data = NVM_INIT_CTRL_4_DEFAULT_I211; 413 *data = NVM_INIT_CTRL_4_DEFAULT_I211;
370 ret_val = E1000_SUCCESS; 414 ret_val = E1000_SUCCESS;
371 } 415 }
372 break; 416 break;
373 case NVM_LED_1_CFG: 417 case NVM_LED_1_CFG:
374 ret_val = igb_read_invm_i211(hw, (u8)offset, data); 418 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
375 if (ret_val != E1000_SUCCESS) { 419 if (ret_val != E1000_SUCCESS) {
376 *data = NVM_LED_1_CFG_DEFAULT_I211; 420 *data = NVM_LED_1_CFG_DEFAULT_I211;
377 ret_val = E1000_SUCCESS; 421 ret_val = E1000_SUCCESS;
378 } 422 }
379 break; 423 break;
380 case NVM_LED_0_2_CFG: 424 case NVM_LED_0_2_CFG:
381 igb_read_invm_i211(hw, offset, data); 425 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
382 if (ret_val != E1000_SUCCESS) { 426 if (ret_val != E1000_SUCCESS) {
383 *data = NVM_LED_0_2_CFG_DEFAULT_I211; 427 *data = NVM_LED_0_2_CFG_DEFAULT_I211;
384 ret_val = E1000_SUCCESS; 428 ret_val = E1000_SUCCESS;
385 } 429 }
386 break; 430 break;
387 case NVM_ID_LED_SETTINGS: 431 case NVM_ID_LED_SETTINGS:
388 ret_val = igb_read_invm_i211(hw, (u8)offset, data); 432 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
389 if (ret_val != E1000_SUCCESS) { 433 if (ret_val != E1000_SUCCESS) {
390 *data = ID_LED_RESERVED_FFFF; 434 *data = ID_LED_RESERVED_FFFF;
391 ret_val = E1000_SUCCESS; 435 ret_val = E1000_SUCCESS;
@@ -411,48 +455,6 @@ s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
411} 455}
412 456
413/** 457/**
414 * igb_read_invm_i211 - Reads OTP
415 * @hw: pointer to the HW structure
416 * @address: the word address (aka eeprom offset) to read
417 * @data: pointer to the data read
418 *
419 * Reads 16-bit words from the OTP. Return error when the word is not
420 * stored in OTP.
421 **/
422s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data)
423{
424 s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
425 u32 invm_dword;
426 u16 i;
427 u8 record_type, word_address;
428
429 for (i = 0; i < E1000_INVM_SIZE; i++) {
430 invm_dword = rd32(E1000_INVM_DATA_REG(i));
431 /* Get record type */
432 record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
433 if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
434 break;
435 if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
436 i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
437 if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
438 i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
439 if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
440 word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
441 if (word_address == (u8)address) {
442 *data = INVM_DWORD_TO_WORD_DATA(invm_dword);
443 hw_dbg("Read INVM Word 0x%02x = %x",
444 address, *data);
445 status = E1000_SUCCESS;
446 break;
447 }
448 }
449 }
450 if (status != E1000_SUCCESS)
451 hw_dbg("Requested word 0x%02x not found in OTP\n", address);
452 return status;
453}
454
455/**
456 * igb_read_invm_version - Reads iNVM version and image type 458 * igb_read_invm_version - Reads iNVM version and image type
457 * @hw: pointer to the HW structure 459 * @hw: pointer to the HW structure
458 * @invm_ver: version structure for the version read 460 * @invm_ver: version structure for the version read
@@ -826,7 +828,7 @@ s32 igb_init_nvm_params_i210(struct e1000_hw *hw)
826 nvm->ops.update = igb_update_nvm_checksum_i210; 828 nvm->ops.update = igb_update_nvm_checksum_i210;
827 } else { 829 } else {
828 hw->nvm.type = e1000_nvm_invm; 830 hw->nvm.type = e1000_nvm_invm;
829 nvm->ops.read = igb_read_nvm_i211; 831 nvm->ops.read = igb_read_invm_i210;
830 nvm->ops.write = NULL; 832 nvm->ops.write = NULL;
831 nvm->ops.validate = NULL; 833 nvm->ops.validate = NULL;
832 nvm->ops.update = NULL; 834 nvm->ops.update = NULL;
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
index a2a1f70cc8dd..dde3c4b7ea99 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -35,14 +35,11 @@ extern s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
35 u16 words, u16 *data); 35 u16 words, u16 *data);
36extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, 36extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
37 u16 words, u16 *data); 37 u16 words, u16 *data);
38extern s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data);
39extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); 38extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
40extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); 39extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
41extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw); 40extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw);
42extern void igb_release_nvm_i210(struct e1000_hw *hw); 41extern void igb_release_nvm_i210(struct e1000_hw *hw);
43extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); 42extern 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,
45 u16 *data);
46extern s32 igb_read_invm_version(struct e1000_hw *hw, 43extern s32 igb_read_invm_version(struct e1000_hw *hw,
47 struct e1000_fw_version *invm_ver); 44 struct e1000_fw_version *invm_ver);
48extern s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, 45extern s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 1a0137d68109..387864db7259 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2166,15 +2166,28 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2166 */ 2166 */
2167 hw->mac.ops.reset_hw(hw); 2167 hw->mac.ops.reset_hw(hw);
2168 2168
2169 /* make sure the NVM is good , i211 parts have special NVM that 2169 /* make sure the NVM is good , i211/i210 parts can have special NVM
2170 * doesn't contain a checksum 2170 * that doesn't contain a checksum
2171 */ 2171 */
2172 if (hw->mac.type != e1000_i211) { 2172 switch (hw->mac.type) {
2173 case e1000_i210:
2174 case e1000_i211:
2175 if (igb_get_flash_presence_i210(hw)) {
2176 if (hw->nvm.ops.validate(hw) < 0) {
2177 dev_err(&pdev->dev,
2178 "The NVM Checksum Is Not Valid\n");
2179 err = -EIO;
2180 goto err_eeprom;
2181 }
2182 }
2183 break;
2184 default:
2173 if (hw->nvm.ops.validate(hw) < 0) { 2185 if (hw->nvm.ops.validate(hw) < 0) {
2174 dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); 2186 dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n");
2175 err = -EIO; 2187 err = -EIO;
2176 goto err_eeprom; 2188 goto err_eeprom;
2177 } 2189 }
2190 break;
2178 } 2191 }
2179 2192
2180 /* copy the MAC address out of the NVM */ 2193 /* copy the MAC address out of the NVM */