diff options
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/e1000e/e1000.h | 5 | ||||
| -rw-r--r-- | drivers/net/e1000e/ethtool.c | 9 | ||||
| -rw-r--r-- | drivers/net/e1000e/ich8lan.c | 78 | ||||
| -rw-r--r-- | drivers/net/e1000e/netdev.c | 72 | ||||
| -rw-r--r-- | drivers/net/e1000e/param.c | 30 |
5 files changed, 155 insertions, 39 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index ac4e506b4f88..5ea6b60fa377 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
| @@ -257,7 +257,6 @@ struct e1000_adapter { | |||
| 257 | struct net_device *netdev; | 257 | struct net_device *netdev; |
| 258 | struct pci_dev *pdev; | 258 | struct pci_dev *pdev; |
| 259 | struct net_device_stats net_stats; | 259 | struct net_device_stats net_stats; |
| 260 | spinlock_t stats_lock; /* prevent concurrent stats updates */ | ||
| 261 | 260 | ||
| 262 | /* structs defined in e1000_hw.h */ | 261 | /* structs defined in e1000_hw.h */ |
| 263 | struct e1000_hw hw; | 262 | struct e1000_hw hw; |
| @@ -284,6 +283,8 @@ struct e1000_adapter { | |||
| 284 | unsigned long led_status; | 283 | unsigned long led_status; |
| 285 | 284 | ||
| 286 | unsigned int flags; | 285 | unsigned int flags; |
| 286 | struct work_struct downshift_task; | ||
| 287 | struct work_struct update_phy_task; | ||
| 287 | }; | 288 | }; |
| 288 | 289 | ||
| 289 | struct e1000_info { | 290 | struct e1000_info { |
| @@ -305,6 +306,7 @@ struct e1000_info { | |||
| 305 | #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) | 306 | #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) |
| 306 | #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) | 307 | #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) |
| 307 | #define FLAG_HAS_JUMBO_FRAMES (1 << 7) | 308 | #define FLAG_HAS_JUMBO_FRAMES (1 << 7) |
| 309 | #define FLAG_READ_ONLY_NVM (1 << 8) | ||
| 308 | #define FLAG_IS_ICH (1 << 9) | 310 | #define FLAG_IS_ICH (1 << 9) |
| 309 | #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) | 311 | #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) |
| 310 | #define FLAG_IS_QUAD_PORT_A (1 << 12) | 312 | #define FLAG_IS_QUAD_PORT_A (1 << 12) |
| @@ -385,6 +387,7 @@ extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw); | |||
| 385 | extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw); | 387 | extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw); |
| 386 | extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state); | 388 | extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state); |
| 387 | 389 | ||
| 390 | extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw); | ||
| 388 | extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, | 391 | extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, |
| 389 | bool state); | 392 | bool state); |
| 390 | extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); | 393 | extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index e21c9e0f3738..33a3ff17b5d0 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
| @@ -432,6 +432,10 @@ static void e1000_get_regs(struct net_device *netdev, | |||
| 432 | regs_buff[11] = er32(TIDV); | 432 | regs_buff[11] = er32(TIDV); |
| 433 | 433 | ||
| 434 | regs_buff[12] = adapter->hw.phy.type; /* PHY type (IGP=1, M88=0) */ | 434 | regs_buff[12] = adapter->hw.phy.type; /* PHY type (IGP=1, M88=0) */ |
| 435 | |||
| 436 | /* ethtool doesn't use anything past this point, so all this | ||
| 437 | * code is likely legacy junk for apps that may or may not | ||
| 438 | * exist */ | ||
| 435 | if (hw->phy.type == e1000_phy_m88) { | 439 | if (hw->phy.type == e1000_phy_m88) { |
| 436 | e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); | 440 | e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); |
| 437 | regs_buff[13] = (u32)phy_data; /* cable length */ | 441 | regs_buff[13] = (u32)phy_data; /* cable length */ |
| @@ -447,7 +451,7 @@ static void e1000_get_regs(struct net_device *netdev, | |||
| 447 | regs_buff[22] = adapter->phy_stats.receive_errors; | 451 | regs_buff[22] = adapter->phy_stats.receive_errors; |
| 448 | regs_buff[23] = regs_buff[13]; /* mdix mode */ | 452 | regs_buff[23] = regs_buff[13]; /* mdix mode */ |
| 449 | } | 453 | } |
| 450 | regs_buff[21] = adapter->phy_stats.idle_errors; /* phy idle errors */ | 454 | regs_buff[21] = 0; /* was idle_errors */ |
| 451 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_data); | 455 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_data); |
| 452 | regs_buff[24] = (u32)phy_data; /* phy local receiver status */ | 456 | regs_buff[24] = (u32)phy_data; /* phy local receiver status */ |
| 453 | regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ | 457 | regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ |
| @@ -529,6 +533,9 @@ static int e1000_set_eeprom(struct net_device *netdev, | |||
| 529 | if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) | 533 | if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) |
| 530 | return -EFAULT; | 534 | return -EFAULT; |
| 531 | 535 | ||
| 536 | if (adapter->flags & FLAG_READ_ONLY_NVM) | ||
| 537 | return -EINVAL; | ||
| 538 | |||
| 532 | max_len = hw->nvm.word_size * 2; | 539 | max_len = hw->nvm.word_size * 2; |
| 533 | 540 | ||
| 534 | first_word = eeprom->offset >> 1; | 541 | first_word = eeprom->offset >> 1; |
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 | /* |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index d266510c8a94..b81c4237b5d3 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
| @@ -47,7 +47,7 @@ | |||
| 47 | 47 | ||
| 48 | #include "e1000.h" | 48 | #include "e1000.h" |
| 49 | 49 | ||
| 50 | #define DRV_VERSION "0.3.3.3-k2" | 50 | #define DRV_VERSION "0.3.3.3-k6" |
| 51 | char e1000e_driver_name[] = "e1000e"; | 51 | char e1000e_driver_name[] = "e1000e"; |
| 52 | const char e1000e_driver_version[] = DRV_VERSION; | 52 | const char e1000e_driver_version[] = DRV_VERSION; |
| 53 | 53 | ||
| @@ -1115,6 +1115,14 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) | |||
| 1115 | writel(0, adapter->hw.hw_addr + rx_ring->tail); | 1115 | writel(0, adapter->hw.hw_addr + rx_ring->tail); |
| 1116 | } | 1116 | } |
| 1117 | 1117 | ||
| 1118 | static void e1000e_downshift_workaround(struct work_struct *work) | ||
| 1119 | { | ||
| 1120 | struct e1000_adapter *adapter = container_of(work, | ||
| 1121 | struct e1000_adapter, downshift_task); | ||
| 1122 | |||
| 1123 | e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); | ||
| 1124 | } | ||
| 1125 | |||
| 1118 | /** | 1126 | /** |
| 1119 | * e1000_intr_msi - Interrupt Handler | 1127 | * e1000_intr_msi - Interrupt Handler |
| 1120 | * @irq: interrupt number | 1128 | * @irq: interrupt number |
| @@ -1139,7 +1147,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data) | |||
| 1139 | */ | 1147 | */ |
| 1140 | if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && | 1148 | if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && |
| 1141 | (!(er32(STATUS) & E1000_STATUS_LU))) | 1149 | (!(er32(STATUS) & E1000_STATUS_LU))) |
| 1142 | e1000e_gig_downshift_workaround_ich8lan(hw); | 1150 | schedule_work(&adapter->downshift_task); |
| 1143 | 1151 | ||
| 1144 | /* | 1152 | /* |
| 1145 | * 80003ES2LAN workaround-- For packet buffer work-around on | 1153 | * 80003ES2LAN workaround-- For packet buffer work-around on |
| @@ -1205,7 +1213,7 @@ static irqreturn_t e1000_intr(int irq, void *data) | |||
| 1205 | */ | 1213 | */ |
| 1206 | if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && | 1214 | if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && |
| 1207 | (!(er32(STATUS) & E1000_STATUS_LU))) | 1215 | (!(er32(STATUS) & E1000_STATUS_LU))) |
| 1208 | e1000e_gig_downshift_workaround_ich8lan(hw); | 1216 | schedule_work(&adapter->downshift_task); |
| 1209 | 1217 | ||
| 1210 | /* | 1218 | /* |
| 1211 | * 80003ES2LAN workaround-- | 1219 | * 80003ES2LAN workaround-- |
| @@ -2592,8 +2600,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) | |||
| 2592 | /* Explicitly disable IRQ since the NIC can be in any state. */ | 2600 | /* Explicitly disable IRQ since the NIC can be in any state. */ |
| 2593 | e1000_irq_disable(adapter); | 2601 | e1000_irq_disable(adapter); |
| 2594 | 2602 | ||
| 2595 | spin_lock_init(&adapter->stats_lock); | ||
| 2596 | |||
| 2597 | set_bit(__E1000_DOWN, &adapter->state); | 2603 | set_bit(__E1000_DOWN, &adapter->state); |
| 2598 | return 0; | 2604 | return 0; |
| 2599 | 2605 | ||
| @@ -2912,6 +2918,21 @@ static int e1000_set_mac(struct net_device *netdev, void *p) | |||
| 2912 | return 0; | 2918 | return 0; |
| 2913 | } | 2919 | } |
| 2914 | 2920 | ||
| 2921 | /** | ||
| 2922 | * e1000e_update_phy_task - work thread to update phy | ||
| 2923 | * @work: pointer to our work struct | ||
| 2924 | * | ||
| 2925 | * this worker thread exists because we must acquire a | ||
| 2926 | * semaphore to read the phy, which we could msleep while | ||
| 2927 | * waiting for it, and we can't msleep in a timer. | ||
| 2928 | **/ | ||
| 2929 | static void e1000e_update_phy_task(struct work_struct *work) | ||
| 2930 | { | ||
| 2931 | struct e1000_adapter *adapter = container_of(work, | ||
| 2932 | struct e1000_adapter, update_phy_task); | ||
| 2933 | e1000_get_phy_info(&adapter->hw); | ||
| 2934 | } | ||
| 2935 | |||
| 2915 | /* | 2936 | /* |
| 2916 | * Need to wait a few seconds after link up to get diagnostic information from | 2937 | * Need to wait a few seconds after link up to get diagnostic information from |
| 2917 | * the phy | 2938 | * the phy |
| @@ -2919,7 +2940,7 @@ static int e1000_set_mac(struct net_device *netdev, void *p) | |||
| 2919 | static void e1000_update_phy_info(unsigned long data) | 2940 | static void e1000_update_phy_info(unsigned long data) |
| 2920 | { | 2941 | { |
| 2921 | struct e1000_adapter *adapter = (struct e1000_adapter *) data; | 2942 | struct e1000_adapter *adapter = (struct e1000_adapter *) data; |
| 2922 | e1000_get_phy_info(&adapter->hw); | 2943 | schedule_work(&adapter->update_phy_task); |
| 2923 | } | 2944 | } |
| 2924 | 2945 | ||
| 2925 | /** | 2946 | /** |
| @@ -2930,10 +2951,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
| 2930 | { | 2951 | { |
| 2931 | struct e1000_hw *hw = &adapter->hw; | 2952 | struct e1000_hw *hw = &adapter->hw; |
| 2932 | struct pci_dev *pdev = adapter->pdev; | 2953 | struct pci_dev *pdev = adapter->pdev; |
| 2933 | unsigned long irq_flags; | ||
| 2934 | u16 phy_tmp; | ||
| 2935 | |||
| 2936 | #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF | ||
| 2937 | 2954 | ||
| 2938 | /* | 2955 | /* |
| 2939 | * Prevent stats update while adapter is being reset, or if the pci | 2956 | * Prevent stats update while adapter is being reset, or if the pci |
| @@ -2944,14 +2961,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
| 2944 | if (pci_channel_offline(pdev)) | 2961 | if (pci_channel_offline(pdev)) |
| 2945 | return; | 2962 | return; |
| 2946 | 2963 | ||
| 2947 | spin_lock_irqsave(&adapter->stats_lock, irq_flags); | ||
| 2948 | |||
| 2949 | /* | ||
| 2950 | * these counters are modified from e1000_adjust_tbi_stats, | ||
| 2951 | * called from the interrupt context, so they must only | ||
| 2952 | * be written while holding adapter->stats_lock | ||
| 2953 | */ | ||
| 2954 | |||
| 2955 | adapter->stats.crcerrs += er32(CRCERRS); | 2964 | adapter->stats.crcerrs += er32(CRCERRS); |
| 2956 | adapter->stats.gprc += er32(GPRC); | 2965 | adapter->stats.gprc += er32(GPRC); |
| 2957 | adapter->stats.gorc += er32(GORCL); | 2966 | adapter->stats.gorc += er32(GORCL); |
| @@ -3022,21 +3031,10 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
| 3022 | 3031 | ||
| 3023 | /* Tx Dropped needs to be maintained elsewhere */ | 3032 | /* Tx Dropped needs to be maintained elsewhere */ |
| 3024 | 3033 | ||
| 3025 | /* Phy Stats */ | ||
| 3026 | if (hw->phy.media_type == e1000_media_type_copper) { | ||
| 3027 | if ((adapter->link_speed == SPEED_1000) && | ||
| 3028 | (!e1e_rphy(hw, PHY_1000T_STATUS, &phy_tmp))) { | ||
| 3029 | phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK; | ||
| 3030 | adapter->phy_stats.idle_errors += phy_tmp; | ||
| 3031 | } | ||
| 3032 | } | ||
| 3033 | |||
| 3034 | /* Management Stats */ | 3034 | /* Management Stats */ |
| 3035 | adapter->stats.mgptc += er32(MGTPTC); | 3035 | adapter->stats.mgptc += er32(MGTPTC); |
| 3036 | adapter->stats.mgprc += er32(MGTPRC); | 3036 | adapter->stats.mgprc += er32(MGTPRC); |
| 3037 | adapter->stats.mgpdc += er32(MGTPDC); | 3037 | adapter->stats.mgpdc += er32(MGTPDC); |
| 3038 | |||
| 3039 | spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); | ||
| 3040 | } | 3038 | } |
| 3041 | 3039 | ||
| 3042 | /** | 3040 | /** |
| @@ -3048,10 +3046,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) | |||
| 3048 | struct e1000_hw *hw = &adapter->hw; | 3046 | struct e1000_hw *hw = &adapter->hw; |
| 3049 | struct e1000_phy_regs *phy = &adapter->phy_regs; | 3047 | struct e1000_phy_regs *phy = &adapter->phy_regs; |
| 3050 | int ret_val; | 3048 | int ret_val; |
| 3051 | unsigned long irq_flags; | ||
| 3052 | |||
| 3053 | |||
| 3054 | spin_lock_irqsave(&adapter->stats_lock, irq_flags); | ||
| 3055 | 3049 | ||
| 3056 | if ((er32(STATUS) & E1000_STATUS_LU) && | 3050 | if ((er32(STATUS) & E1000_STATUS_LU) && |
| 3057 | (adapter->hw.phy.media_type == e1000_media_type_copper)) { | 3051 | (adapter->hw.phy.media_type == e1000_media_type_copper)) { |
| @@ -3082,8 +3076,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) | |||
| 3082 | phy->stat1000 = 0; | 3076 | phy->stat1000 = 0; |
| 3083 | phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF); | 3077 | phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF); |
| 3084 | } | 3078 | } |
| 3085 | |||
| 3086 | spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); | ||
| 3087 | } | 3079 | } |
| 3088 | 3080 | ||
| 3089 | static void e1000_print_link_info(struct e1000_adapter *adapter) | 3081 | static void e1000_print_link_info(struct e1000_adapter *adapter) |
| @@ -4467,6 +4459,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
| 4467 | 4459 | ||
| 4468 | adapter->bd_number = cards_found++; | 4460 | adapter->bd_number = cards_found++; |
| 4469 | 4461 | ||
| 4462 | e1000e_check_options(adapter); | ||
| 4463 | |||
| 4470 | /* setup adapter struct */ | 4464 | /* setup adapter struct */ |
| 4471 | err = e1000_sw_init(adapter); | 4465 | err = e1000_sw_init(adapter); |
| 4472 | if (err) | 4466 | if (err) |
| @@ -4482,6 +4476,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
| 4482 | if (err) | 4476 | if (err) |
| 4483 | goto err_hw_init; | 4477 | goto err_hw_init; |
| 4484 | 4478 | ||
| 4479 | if ((adapter->flags & FLAG_IS_ICH) && | ||
| 4480 | (adapter->flags & FLAG_READ_ONLY_NVM)) | ||
| 4481 | e1000e_write_protect_nvm_ich8lan(&adapter->hw); | ||
| 4482 | |||
| 4485 | hw->mac.ops.get_bus_info(&adapter->hw); | 4483 | hw->mac.ops.get_bus_info(&adapter->hw); |
| 4486 | 4484 | ||
| 4487 | adapter->hw.phy.autoneg_wait_to_complete = 0; | 4485 | adapter->hw.phy.autoneg_wait_to_complete = 0; |
| @@ -4572,8 +4570,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
| 4572 | 4570 | ||
| 4573 | INIT_WORK(&adapter->reset_task, e1000_reset_task); | 4571 | INIT_WORK(&adapter->reset_task, e1000_reset_task); |
| 4574 | INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); | 4572 | INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); |
| 4575 | 4573 | INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround); | |
| 4576 | e1000e_check_options(adapter); | 4574 | INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task); |
| 4577 | 4575 | ||
| 4578 | /* Initialize link parameters. User can change them with ethtool */ | 4576 | /* Initialize link parameters. User can change them with ethtool */ |
| 4579 | adapter->hw.mac.autoneg = 1; | 4577 | adapter->hw.mac.autoneg = 1; |
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index ed912e023a72..d91dbf7ba434 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c | |||
| @@ -133,6 +133,15 @@ E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); | |||
| 133 | */ | 133 | */ |
| 134 | E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); | 134 | E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); |
| 135 | 135 | ||
| 136 | /* | ||
| 137 | * Write Protect NVM | ||
| 138 | * | ||
| 139 | * Valid Range: 0, 1 | ||
| 140 | * | ||
| 141 | * Default Value: 1 (enabled) | ||
| 142 | */ | ||
| 143 | E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); | ||
| 144 | |||
| 136 | struct e1000_option { | 145 | struct e1000_option { |
| 137 | enum { enable_option, range_option, list_option } type; | 146 | enum { enable_option, range_option, list_option } type; |
| 138 | const char *name; | 147 | const char *name; |
| @@ -388,4 +397,25 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) | |||
| 388 | opt.def); | 397 | opt.def); |
| 389 | } | 398 | } |
| 390 | } | 399 | } |
| 400 | { /* Write-protect NVM */ | ||
| 401 | const struct e1000_option opt = { | ||
| 402 | .type = enable_option, | ||
| 403 | .name = "Write-protect NVM", | ||
| 404 | .err = "defaulting to Enabled", | ||
| 405 | .def = OPTION_ENABLED | ||
| 406 | }; | ||
| 407 | |||
| 408 | if (adapter->flags & FLAG_IS_ICH) { | ||
| 409 | if (num_WriteProtectNVM > bd) { | ||
| 410 | unsigned int write_protect_nvm = WriteProtectNVM[bd]; | ||
| 411 | e1000_validate_option(&write_protect_nvm, &opt, | ||
| 412 | adapter); | ||
| 413 | if (write_protect_nvm) | ||
| 414 | adapter->flags |= FLAG_READ_ONLY_NVM; | ||
| 415 | } else { | ||
| 416 | if (opt.def) | ||
| 417 | adapter->flags |= FLAG_READ_ONLY_NVM; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 391 | } | 421 | } |
