diff options
Diffstat (limited to 'drivers/net/e1000e/ich8lan.c')
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 692251b60915..523b9716a543 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #define ICH_FLASH_HSFCTL 0x0006 | 60 | #define ICH_FLASH_HSFCTL 0x0006 |
61 | #define ICH_FLASH_FADDR 0x0008 | 61 | #define ICH_FLASH_FADDR 0x0008 |
62 | #define ICH_FLASH_FDATA0 0x0010 | 62 | #define ICH_FLASH_FDATA0 0x0010 |
63 | #define ICH_FLASH_PR0 0x0074 | ||
63 | 64 | ||
64 | #define ICH_FLASH_READ_COMMAND_TIMEOUT 500 | 65 | #define ICH_FLASH_READ_COMMAND_TIMEOUT 500 |
65 | #define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 | 66 | #define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 |
@@ -152,6 +153,19 @@ union ich8_hws_flash_regacc { | |||
152 | u16 regval; | 153 | u16 regval; |
153 | }; | 154 | }; |
154 | 155 | ||
156 | /* ICH Flash Protected Region */ | ||
157 | union ich8_flash_protected_range { | ||
158 | struct ich8_pr { | ||
159 | u32 base:13; /* 0:12 Protected Range Base */ | ||
160 | u32 reserved1:2; /* 13:14 Reserved */ | ||
161 | u32 rpe:1; /* 15 Read Protection Enable */ | ||
162 | u32 limit:13; /* 16:28 Protected Range Limit */ | ||
163 | u32 reserved2:2; /* 29:30 Reserved */ | ||
164 | u32 wpe:1; /* 31 Write Protection Enable */ | ||
165 | } range; | ||
166 | u32 regval; | ||
167 | }; | ||
168 | |||
155 | static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); | 169 | static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); |
156 | static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); | 170 | static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); |
157 | static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); | 171 | static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); |
@@ -371,6 +385,9 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) | |||
371 | return 0; | 385 | return 0; |
372 | } | 386 | } |
373 | 387 | ||
388 | static DEFINE_MUTEX(nvm_mutex); | ||
389 | static pid_t nvm_owner = -1; | ||
390 | |||
374 | /** | 391 | /** |
375 | * e1000_acquire_swflag_ich8lan - Acquire software control flag | 392 | * e1000_acquire_swflag_ich8lan - Acquire software control flag |
376 | * @hw: pointer to the HW structure | 393 | * @hw: pointer to the HW structure |
@@ -384,6 +401,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | |||
384 | u32 extcnf_ctrl; | 401 | u32 extcnf_ctrl; |
385 | u32 timeout = PHY_CFG_TIMEOUT; | 402 | u32 timeout = PHY_CFG_TIMEOUT; |
386 | 403 | ||
404 | might_sleep(); | ||
405 | |||
406 | if (!mutex_trylock(&nvm_mutex)) { | ||
407 | WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n", | ||
408 | nvm_owner); | ||
409 | mutex_lock(&nvm_mutex); | ||
410 | } | ||
411 | nvm_owner = current->pid; | ||
412 | |||
387 | while (timeout) { | 413 | while (timeout) { |
388 | extcnf_ctrl = er32(EXTCNF_CTRL); | 414 | extcnf_ctrl = er32(EXTCNF_CTRL); |
389 | extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; | 415 | extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; |
@@ -400,6 +426,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | |||
400 | hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); | 426 | hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); |
401 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; | 427 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; |
402 | ew32(EXTCNF_CTRL, extcnf_ctrl); | 428 | ew32(EXTCNF_CTRL, extcnf_ctrl); |
429 | nvm_owner = -1; | ||
430 | mutex_unlock(&nvm_mutex); | ||
403 | return -E1000_ERR_CONFIG; | 431 | return -E1000_ERR_CONFIG; |
404 | } | 432 | } |
405 | 433 | ||
@@ -421,6 +449,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) | |||
421 | extcnf_ctrl = er32(EXTCNF_CTRL); | 449 | extcnf_ctrl = er32(EXTCNF_CTRL); |
422 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; | 450 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; |
423 | ew32(EXTCNF_CTRL, extcnf_ctrl); | 451 | ew32(EXTCNF_CTRL, extcnf_ctrl); |
452 | |||
453 | nvm_owner = -1; | ||
454 | mutex_unlock(&nvm_mutex); | ||
424 | } | 455 | } |
425 | 456 | ||
426 | /** | 457 | /** |
@@ -1386,6 +1417,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1386 | * programming failed. | 1417 | * programming failed. |
1387 | */ | 1418 | */ |
1388 | if (ret_val) { | 1419 | if (ret_val) { |
1420 | /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ | ||
1389 | hw_dbg(hw, "Flash commit failed.\n"); | 1421 | hw_dbg(hw, "Flash commit failed.\n"); |
1390 | e1000_release_swflag_ich8lan(hw); | 1422 | e1000_release_swflag_ich8lan(hw); |
1391 | return ret_val; | 1423 | return ret_val; |
@@ -1476,6 +1508,49 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1476 | } | 1508 | } |
1477 | 1509 | ||
1478 | /** | 1510 | /** |
1511 | * e1000e_write_protect_nvm_ich8lan - Make the NVM read-only | ||
1512 | * @hw: pointer to the HW structure | ||
1513 | * | ||
1514 | * To prevent malicious write/erase of the NVM, set it to be read-only | ||
1515 | * so that the hardware ignores all write/erase cycles of the NVM via | ||
1516 | * the flash control registers. The shadow-ram copy of the NVM will | ||
1517 | * still be updated, however any updates to this copy will not stick | ||
1518 | * across driver reloads. | ||
1519 | **/ | ||
1520 | void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) | ||
1521 | { | ||
1522 | union ich8_flash_protected_range pr0; | ||
1523 | union ich8_hws_flash_status hsfsts; | ||
1524 | u32 gfpreg; | ||
1525 | s32 ret_val; | ||
1526 | |||
1527 | ret_val = e1000_acquire_swflag_ich8lan(hw); | ||
1528 | if (ret_val) | ||
1529 | return; | ||
1530 | |||
1531 | gfpreg = er32flash(ICH_FLASH_GFPREG); | ||
1532 | |||
1533 | /* Write-protect GbE Sector of NVM */ | ||
1534 | pr0.regval = er32flash(ICH_FLASH_PR0); | ||
1535 | pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK; | ||
1536 | pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK); | ||
1537 | pr0.range.wpe = true; | ||
1538 | ew32flash(ICH_FLASH_PR0, pr0.regval); | ||
1539 | |||
1540 | /* | ||
1541 | * Lock down a subset of GbE Flash Control Registers, e.g. | ||
1542 | * PR0 to prevent the write-protection from being lifted. | ||
1543 | * Once FLOCKDN is set, the registers protected by it cannot | ||
1544 | * be written until FLOCKDN is cleared by a hardware reset. | ||
1545 | */ | ||
1546 | hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); | ||
1547 | hsfsts.hsf_status.flockdn = true; | ||
1548 | ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); | ||
1549 | |||
1550 | e1000_release_swflag_ich8lan(hw); | ||
1551 | } | ||
1552 | |||
1553 | /** | ||
1479 | * e1000_write_flash_data_ich8lan - Writes bytes to the NVM | 1554 | * e1000_write_flash_data_ich8lan - Writes bytes to the NVM |
1480 | * @hw: pointer to the HW structure | 1555 | * @hw: pointer to the HW structure |
1481 | * @offset: The offset (in bytes) of the byte/word to read. | 1556 | * @offset: The offset (in bytes) of the byte/word to read. |
@@ -1822,6 +1897,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
1822 | ew32(CTRL, (ctrl | E1000_CTRL_RST)); | 1897 | ew32(CTRL, (ctrl | E1000_CTRL_RST)); |
1823 | msleep(20); | 1898 | msleep(20); |
1824 | 1899 | ||
1900 | /* release the swflag because it is not reset by hardware reset */ | ||
1901 | e1000_release_swflag_ich8lan(hw); | ||
1902 | |||
1825 | ret_val = e1000e_get_auto_rd_done(hw); | 1903 | ret_val = e1000e_get_auto_rd_done(hw); |
1826 | if (ret_val) { | 1904 | if (ret_val) { |
1827 | /* | 1905 | /* |