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 9e38452a738c..bcd2bc477af2 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | #define ICH_FLASH_HSFCTL 0x0006 | 58 | #define ICH_FLASH_HSFCTL 0x0006 |
| 59 | #define ICH_FLASH_FADDR 0x0008 | 59 | #define ICH_FLASH_FADDR 0x0008 |
| 60 | #define ICH_FLASH_FDATA0 0x0010 | 60 | #define ICH_FLASH_FDATA0 0x0010 |
| 61 | #define ICH_FLASH_PR0 0x0074 | ||
| 61 | 62 | ||
| 62 | #define ICH_FLASH_READ_COMMAND_TIMEOUT 500 | 63 | #define ICH_FLASH_READ_COMMAND_TIMEOUT 500 |
| 63 | #define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 | 64 | #define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 |
| @@ -150,6 +151,19 @@ union ich8_hws_flash_regacc { | |||
| 150 | u16 regval; | 151 | u16 regval; |
| 151 | }; | 152 | }; |
| 152 | 153 | ||
| 154 | /* ICH Flash Protected Region */ | ||
| 155 | union ich8_flash_protected_range { | ||
| 156 | struct ich8_pr { | ||
| 157 | u32 base:13; /* 0:12 Protected Range Base */ | ||
| 158 | u32 reserved1:2; /* 13:14 Reserved */ | ||
| 159 | u32 rpe:1; /* 15 Read Protection Enable */ | ||
| 160 | u32 limit:13; /* 16:28 Protected Range Limit */ | ||
| 161 | u32 reserved2:2; /* 29:30 Reserved */ | ||
| 162 | u32 wpe:1; /* 31 Write Protection Enable */ | ||
| 163 | } range; | ||
| 164 | u32 regval; | ||
| 165 | }; | ||
| 166 | |||
| 153 | static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); | 167 | static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); |
| 154 | static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); | 168 | static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); |
| 155 | static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); | 169 | static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); |
| @@ -366,6 +380,9 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) | |||
| 366 | return 0; | 380 | return 0; |
| 367 | } | 381 | } |
| 368 | 382 | ||
| 383 | static DEFINE_MUTEX(nvm_mutex); | ||
| 384 | static pid_t nvm_owner = -1; | ||
| 385 | |||
| 369 | /** | 386 | /** |
| 370 | * e1000_acquire_swflag_ich8lan - Acquire software control flag | 387 | * e1000_acquire_swflag_ich8lan - Acquire software control flag |
| 371 | * @hw: pointer to the HW structure | 388 | * @hw: pointer to the HW structure |
| @@ -379,6 +396,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | |||
| 379 | u32 extcnf_ctrl; | 396 | u32 extcnf_ctrl; |
| 380 | u32 timeout = PHY_CFG_TIMEOUT; | 397 | u32 timeout = PHY_CFG_TIMEOUT; |
| 381 | 398 | ||
| 399 | might_sleep(); | ||
| 400 | |||
| 401 | if (!mutex_trylock(&nvm_mutex)) { | ||
| 402 | WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n", | ||
| 403 | nvm_owner); | ||
| 404 | mutex_lock(&nvm_mutex); | ||
| 405 | } | ||
| 406 | nvm_owner = current->pid; | ||
| 407 | |||
| 382 | while (timeout) { | 408 | while (timeout) { |
| 383 | extcnf_ctrl = er32(EXTCNF_CTRL); | 409 | extcnf_ctrl = er32(EXTCNF_CTRL); |
| 384 | extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; | 410 | extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; |
| @@ -393,6 +419,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | |||
| 393 | 419 | ||
| 394 | if (!timeout) { | 420 | if (!timeout) { |
| 395 | hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); | 421 | hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); |
| 422 | nvm_owner = -1; | ||
| 423 | mutex_unlock(&nvm_mutex); | ||
| 396 | return -E1000_ERR_CONFIG; | 424 | return -E1000_ERR_CONFIG; |
| 397 | } | 425 | } |
| 398 | 426 | ||
| @@ -414,6 +442,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) | |||
| 414 | extcnf_ctrl = er32(EXTCNF_CTRL); | 442 | extcnf_ctrl = er32(EXTCNF_CTRL); |
| 415 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; | 443 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; |
| 416 | ew32(EXTCNF_CTRL, extcnf_ctrl); | 444 | ew32(EXTCNF_CTRL, extcnf_ctrl); |
| 445 | |||
| 446 | nvm_owner = -1; | ||
| 447 | mutex_unlock(&nvm_mutex); | ||
| 417 | } | 448 | } |
| 418 | 449 | ||
| 419 | /** | 450 | /** |
| @@ -1284,6 +1315,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
| 1284 | * programming failed. | 1315 | * programming failed. |
| 1285 | */ | 1316 | */ |
| 1286 | if (ret_val) { | 1317 | if (ret_val) { |
| 1318 | /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ | ||
| 1287 | hw_dbg(hw, "Flash commit failed.\n"); | 1319 | hw_dbg(hw, "Flash commit failed.\n"); |
| 1288 | e1000_release_swflag_ich8lan(hw); | 1320 | e1000_release_swflag_ich8lan(hw); |
| 1289 | return ret_val; | 1321 | return ret_val; |
| @@ -1374,6 +1406,49 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
| 1374 | } | 1406 | } |
| 1375 | 1407 | ||
| 1376 | /** | 1408 | /** |
| 1409 | * e1000e_write_protect_nvm_ich8lan - Make the NVM read-only | ||
| 1410 | * @hw: pointer to the HW structure | ||
| 1411 | * | ||
| 1412 | * To prevent malicious write/erase of the NVM, set it to be read-only | ||
| 1413 | * so that the hardware ignores all write/erase cycles of the NVM via | ||
| 1414 | * the flash control registers. The shadow-ram copy of the NVM will | ||
| 1415 | * still be updated, however any updates to this copy will not stick | ||
| 1416 | * across driver reloads. | ||
| 1417 | **/ | ||
| 1418 | void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) | ||
| 1419 | { | ||
| 1420 | union ich8_flash_protected_range pr0; | ||
| 1421 | union ich8_hws_flash_status hsfsts; | ||
| 1422 | u32 gfpreg; | ||
| 1423 | s32 ret_val; | ||
| 1424 | |||
| 1425 | ret_val = e1000_acquire_swflag_ich8lan(hw); | ||
| 1426 | if (ret_val) | ||
| 1427 | return; | ||
| 1428 | |||
| 1429 | gfpreg = er32flash(ICH_FLASH_GFPREG); | ||
| 1430 | |||
| 1431 | /* Write-protect GbE Sector of NVM */ | ||
| 1432 | pr0.regval = er32flash(ICH_FLASH_PR0); | ||
| 1433 | pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK; | ||
| 1434 | pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK); | ||
| 1435 | pr0.range.wpe = true; | ||
| 1436 | ew32flash(ICH_FLASH_PR0, pr0.regval); | ||
| 1437 | |||
| 1438 | /* | ||
| 1439 | * Lock down a subset of GbE Flash Control Registers, e.g. | ||
| 1440 | * PR0 to prevent the write-protection from being lifted. | ||
| 1441 | * Once FLOCKDN is set, the registers protected by it cannot | ||
| 1442 | * be written until FLOCKDN is cleared by a hardware reset. | ||
| 1443 | */ | ||
| 1444 | hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); | ||
| 1445 | hsfsts.hsf_status.flockdn = true; | ||
| 1446 | ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); | ||
| 1447 | |||
| 1448 | e1000_release_swflag_ich8lan(hw); | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | /** | ||
| 1377 | * e1000_write_flash_data_ich8lan - Writes bytes to the NVM | 1452 | * e1000_write_flash_data_ich8lan - Writes bytes to the NVM |
| 1378 | * @hw: pointer to the HW structure | 1453 | * @hw: pointer to the HW structure |
| 1379 | * @offset: The offset (in bytes) of the byte/word to read. | 1454 | * @offset: The offset (in bytes) of the byte/word to read. |
| @@ -1720,6 +1795,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
| 1720 | ew32(CTRL, (ctrl | E1000_CTRL_RST)); | 1795 | ew32(CTRL, (ctrl | E1000_CTRL_RST)); |
| 1721 | msleep(20); | 1796 | msleep(20); |
| 1722 | 1797 | ||
| 1798 | /* release the swflag because it is not reset by hardware reset */ | ||
| 1799 | e1000_release_swflag_ich8lan(hw); | ||
| 1800 | |||
| 1723 | ret_val = e1000e_get_auto_rd_done(hw); | 1801 | ret_val = e1000e_get_auto_rd_done(hw); |
| 1724 | if (ret_val) { | 1802 | if (ret_val) { |
| 1725 | /* | 1803 | /* |
