diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 206 |
1 files changed, 193 insertions, 13 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4072fbb6493d..2cb704dd9546 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -62,6 +62,7 @@ static const struct e1000_info *e1000_info_tbl[] = { | |||
62 | [board_ich8lan] = &e1000_ich8_info, | 62 | [board_ich8lan] = &e1000_ich8_info, |
63 | [board_ich9lan] = &e1000_ich9_info, | 63 | [board_ich9lan] = &e1000_ich9_info, |
64 | [board_ich10lan] = &e1000_ich10_info, | 64 | [board_ich10lan] = &e1000_ich10_info, |
65 | [board_pchlan] = &e1000_pch_info, | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | #ifdef DEBUG | 68 | #ifdef DEBUG |
@@ -2308,6 +2309,23 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2308 | if (adapter->flags2 & FLAG2_CRC_STRIPPING) | 2309 | if (adapter->flags2 & FLAG2_CRC_STRIPPING) |
2309 | rctl |= E1000_RCTL_SECRC; | 2310 | rctl |= E1000_RCTL_SECRC; |
2310 | 2311 | ||
2312 | /* Workaround Si errata on 82577 PHY - configure IPG for jumbos */ | ||
2313 | if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) { | ||
2314 | u16 phy_data; | ||
2315 | |||
2316 | e1e_rphy(hw, PHY_REG(770, 26), &phy_data); | ||
2317 | phy_data &= 0xfff8; | ||
2318 | phy_data |= (1 << 2); | ||
2319 | e1e_wphy(hw, PHY_REG(770, 26), phy_data); | ||
2320 | |||
2321 | e1e_rphy(hw, 22, &phy_data); | ||
2322 | phy_data &= 0x0fff; | ||
2323 | phy_data |= (1 << 14); | ||
2324 | e1e_wphy(hw, 0x10, 0x2823); | ||
2325 | e1e_wphy(hw, 0x11, 0x0003); | ||
2326 | e1e_wphy(hw, 22, phy_data); | ||
2327 | } | ||
2328 | |||
2311 | /* Setup buffer sizes */ | 2329 | /* Setup buffer sizes */ |
2312 | rctl &= ~E1000_RCTL_SZ_4096; | 2330 | rctl &= ~E1000_RCTL_SZ_4096; |
2313 | rctl |= E1000_RCTL_BSEX; | 2331 | rctl |= E1000_RCTL_BSEX; |
@@ -2789,6 +2807,8 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2789 | e1000_get_hw_control(adapter); | 2807 | e1000_get_hw_control(adapter); |
2790 | 2808 | ||
2791 | ew32(WUC, 0); | 2809 | ew32(WUC, 0); |
2810 | if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) | ||
2811 | e1e_wphy(&adapter->hw, BM_WUC, 0); | ||
2792 | 2812 | ||
2793 | if (mac->ops.init_hw(hw)) | 2813 | if (mac->ops.init_hw(hw)) |
2794 | e_err("Hardware Error\n"); | 2814 | e_err("Hardware Error\n"); |
@@ -3269,6 +3289,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
3269 | { | 3289 | { |
3270 | struct e1000_hw *hw = &adapter->hw; | 3290 | struct e1000_hw *hw = &adapter->hw; |
3271 | struct pci_dev *pdev = adapter->pdev; | 3291 | struct pci_dev *pdev = adapter->pdev; |
3292 | u16 phy_data; | ||
3272 | 3293 | ||
3273 | /* | 3294 | /* |
3274 | * Prevent stats update while adapter is being reset, or if the pci | 3295 | * Prevent stats update while adapter is being reset, or if the pci |
@@ -3288,11 +3309,34 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
3288 | adapter->stats.roc += er32(ROC); | 3309 | adapter->stats.roc += er32(ROC); |
3289 | 3310 | ||
3290 | adapter->stats.mpc += er32(MPC); | 3311 | adapter->stats.mpc += er32(MPC); |
3291 | adapter->stats.scc += er32(SCC); | 3312 | if ((hw->phy.type == e1000_phy_82578) || |
3292 | adapter->stats.ecol += er32(ECOL); | 3313 | (hw->phy.type == e1000_phy_82577)) { |
3293 | adapter->stats.mcc += er32(MCC); | 3314 | e1e_rphy(hw, HV_SCC_UPPER, &phy_data); |
3294 | adapter->stats.latecol += er32(LATECOL); | 3315 | e1e_rphy(hw, HV_SCC_LOWER, &phy_data); |
3295 | adapter->stats.dc += er32(DC); | 3316 | adapter->stats.scc += phy_data; |
3317 | |||
3318 | e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); | ||
3319 | e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); | ||
3320 | adapter->stats.ecol += phy_data; | ||
3321 | |||
3322 | e1e_rphy(hw, HV_MCC_UPPER, &phy_data); | ||
3323 | e1e_rphy(hw, HV_MCC_LOWER, &phy_data); | ||
3324 | adapter->stats.mcc += phy_data; | ||
3325 | |||
3326 | e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); | ||
3327 | e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); | ||
3328 | adapter->stats.latecol += phy_data; | ||
3329 | |||
3330 | e1e_rphy(hw, HV_DC_UPPER, &phy_data); | ||
3331 | e1e_rphy(hw, HV_DC_LOWER, &phy_data); | ||
3332 | adapter->stats.dc += phy_data; | ||
3333 | } else { | ||
3334 | adapter->stats.scc += er32(SCC); | ||
3335 | adapter->stats.ecol += er32(ECOL); | ||
3336 | adapter->stats.mcc += er32(MCC); | ||
3337 | adapter->stats.latecol += er32(LATECOL); | ||
3338 | adapter->stats.dc += er32(DC); | ||
3339 | } | ||
3296 | adapter->stats.xonrxc += er32(XONRXC); | 3340 | adapter->stats.xonrxc += er32(XONRXC); |
3297 | adapter->stats.xontxc += er32(XONTXC); | 3341 | adapter->stats.xontxc += er32(XONTXC); |
3298 | adapter->stats.xoffrxc += er32(XOFFRXC); | 3342 | adapter->stats.xoffrxc += er32(XOFFRXC); |
@@ -3310,13 +3354,28 @@ void e1000e_update_stats(struct e1000_adapter *adapter) | |||
3310 | 3354 | ||
3311 | hw->mac.tx_packet_delta = er32(TPT); | 3355 | hw->mac.tx_packet_delta = er32(TPT); |
3312 | adapter->stats.tpt += hw->mac.tx_packet_delta; | 3356 | adapter->stats.tpt += hw->mac.tx_packet_delta; |
3313 | hw->mac.collision_delta = er32(COLC); | 3357 | if ((hw->phy.type == e1000_phy_82578) || |
3358 | (hw->phy.type == e1000_phy_82577)) { | ||
3359 | e1e_rphy(hw, HV_COLC_UPPER, &phy_data); | ||
3360 | e1e_rphy(hw, HV_COLC_LOWER, &phy_data); | ||
3361 | hw->mac.collision_delta = phy_data; | ||
3362 | } else { | ||
3363 | hw->mac.collision_delta = er32(COLC); | ||
3364 | } | ||
3314 | adapter->stats.colc += hw->mac.collision_delta; | 3365 | adapter->stats.colc += hw->mac.collision_delta; |
3315 | 3366 | ||
3316 | adapter->stats.algnerrc += er32(ALGNERRC); | 3367 | adapter->stats.algnerrc += er32(ALGNERRC); |
3317 | adapter->stats.rxerrc += er32(RXERRC); | 3368 | adapter->stats.rxerrc += er32(RXERRC); |
3318 | if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583)) | 3369 | if ((hw->phy.type == e1000_phy_82578) || |
3319 | adapter->stats.tncrs += er32(TNCRS); | 3370 | (hw->phy.type == e1000_phy_82577)) { |
3371 | e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); | ||
3372 | e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); | ||
3373 | adapter->stats.tncrs += phy_data; | ||
3374 | } else { | ||
3375 | if ((hw->mac.type != e1000_82574) && | ||
3376 | (hw->mac.type != e1000_82583)) | ||
3377 | adapter->stats.tncrs += er32(TNCRS); | ||
3378 | } | ||
3320 | adapter->stats.cexterr += er32(CEXTERR); | 3379 | adapter->stats.cexterr += er32(CEXTERR); |
3321 | adapter->stats.tsctc += er32(TSCTC); | 3380 | adapter->stats.tsctc += er32(TSCTC); |
3322 | adapter->stats.tsctfc += er32(TSCTFC); | 3381 | adapter->stats.tsctfc += er32(TSCTFC); |
@@ -4342,6 +4401,81 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
4342 | } | 4401 | } |
4343 | } | 4402 | } |
4344 | 4403 | ||
4404 | static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) | ||
4405 | { | ||
4406 | struct e1000_hw *hw = &adapter->hw; | ||
4407 | u32 i, mac_reg; | ||
4408 | u16 phy_reg; | ||
4409 | int retval = 0; | ||
4410 | |||
4411 | /* copy MAC RARs to PHY RARs */ | ||
4412 | for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) { | ||
4413 | mac_reg = er32(RAL(i)); | ||
4414 | e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF)); | ||
4415 | e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF)); | ||
4416 | mac_reg = er32(RAH(i)); | ||
4417 | e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF)); | ||
4418 | e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF)); | ||
4419 | } | ||
4420 | |||
4421 | /* copy MAC MTA to PHY MTA */ | ||
4422 | for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) { | ||
4423 | mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i); | ||
4424 | e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF)); | ||
4425 | e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF)); | ||
4426 | } | ||
4427 | |||
4428 | /* configure PHY Rx Control register */ | ||
4429 | e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg); | ||
4430 | mac_reg = er32(RCTL); | ||
4431 | if (mac_reg & E1000_RCTL_UPE) | ||
4432 | phy_reg |= BM_RCTL_UPE; | ||
4433 | if (mac_reg & E1000_RCTL_MPE) | ||
4434 | phy_reg |= BM_RCTL_MPE; | ||
4435 | phy_reg &= ~(BM_RCTL_MO_MASK); | ||
4436 | if (mac_reg & E1000_RCTL_MO_3) | ||
4437 | phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT) | ||
4438 | << BM_RCTL_MO_SHIFT); | ||
4439 | if (mac_reg & E1000_RCTL_BAM) | ||
4440 | phy_reg |= BM_RCTL_BAM; | ||
4441 | if (mac_reg & E1000_RCTL_PMCF) | ||
4442 | phy_reg |= BM_RCTL_PMCF; | ||
4443 | mac_reg = er32(CTRL); | ||
4444 | if (mac_reg & E1000_CTRL_RFCE) | ||
4445 | phy_reg |= BM_RCTL_RFCE; | ||
4446 | e1e_wphy(&adapter->hw, BM_RCTL, phy_reg); | ||
4447 | |||
4448 | /* enable PHY wakeup in MAC register */ | ||
4449 | ew32(WUFC, wufc); | ||
4450 | ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); | ||
4451 | |||
4452 | /* configure and enable PHY wakeup in PHY registers */ | ||
4453 | e1e_wphy(&adapter->hw, BM_WUFC, wufc); | ||
4454 | e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); | ||
4455 | |||
4456 | /* activate PHY wakeup */ | ||
4457 | retval = hw->phy.ops.acquire_phy(hw); | ||
4458 | if (retval) { | ||
4459 | e_err("Could not acquire PHY\n"); | ||
4460 | return retval; | ||
4461 | } | ||
4462 | e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, | ||
4463 | (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); | ||
4464 | retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); | ||
4465 | if (retval) { | ||
4466 | e_err("Could not read PHY page 769\n"); | ||
4467 | goto out; | ||
4468 | } | ||
4469 | phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; | ||
4470 | retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); | ||
4471 | if (retval) | ||
4472 | e_err("Could not set PHY Host Wakeup bit\n"); | ||
4473 | out: | ||
4474 | hw->phy.ops.release_phy(hw); | ||
4475 | |||
4476 | return retval; | ||
4477 | } | ||
4478 | |||
4345 | static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) | 4479 | static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) |
4346 | { | 4480 | { |
4347 | struct net_device *netdev = pci_get_drvdata(pdev); | 4481 | struct net_device *netdev = pci_get_drvdata(pdev); |
@@ -4384,8 +4518,9 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
4384 | #define E1000_CTRL_ADVD3WUC 0x00100000 | 4518 | #define E1000_CTRL_ADVD3WUC 0x00100000 |
4385 | /* phy power management enable */ | 4519 | /* phy power management enable */ |
4386 | #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 | 4520 | #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 |
4387 | ctrl |= E1000_CTRL_ADVD3WUC | | 4521 | ctrl |= E1000_CTRL_ADVD3WUC; |
4388 | E1000_CTRL_EN_PHY_PWR_MGMT; | 4522 | if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)) |
4523 | ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT; | ||
4389 | ew32(CTRL, ctrl); | 4524 | ew32(CTRL, ctrl); |
4390 | 4525 | ||
4391 | if (adapter->hw.phy.media_type == e1000_media_type_fiber || | 4526 | if (adapter->hw.phy.media_type == e1000_media_type_fiber || |
@@ -4403,8 +4538,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
4403 | /* Allow time for pending master requests to run */ | 4538 | /* Allow time for pending master requests to run */ |
4404 | e1000e_disable_pcie_master(&adapter->hw); | 4539 | e1000e_disable_pcie_master(&adapter->hw); |
4405 | 4540 | ||
4406 | ew32(WUC, E1000_WUC_PME_EN); | 4541 | if ((adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) && |
4407 | ew32(WUFC, wufc); | 4542 | !(hw->mac.ops.check_mng_mode(hw))) { |
4543 | /* enable wakeup by the PHY */ | ||
4544 | retval = e1000_init_phy_wakeup(adapter, wufc); | ||
4545 | if (retval) | ||
4546 | return retval; | ||
4547 | } else { | ||
4548 | /* enable wakeup by the MAC */ | ||
4549 | ew32(WUFC, wufc); | ||
4550 | ew32(WUC, E1000_WUC_PME_EN); | ||
4551 | } | ||
4408 | } else { | 4552 | } else { |
4409 | ew32(WUC, 0); | 4553 | ew32(WUC, 0); |
4410 | ew32(WUFC, 0); | 4554 | ew32(WUFC, 0); |
@@ -4547,8 +4691,37 @@ static int e1000_resume(struct pci_dev *pdev) | |||
4547 | } | 4691 | } |
4548 | 4692 | ||
4549 | e1000e_power_up_phy(adapter); | 4693 | e1000e_power_up_phy(adapter); |
4694 | |||
4695 | /* report the system wakeup cause from S3/S4 */ | ||
4696 | if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) { | ||
4697 | u16 phy_data; | ||
4698 | |||
4699 | e1e_rphy(&adapter->hw, BM_WUS, &phy_data); | ||
4700 | if (phy_data) { | ||
4701 | e_info("PHY Wakeup cause - %s\n", | ||
4702 | phy_data & E1000_WUS_EX ? "Unicast Packet" : | ||
4703 | phy_data & E1000_WUS_MC ? "Multicast Packet" : | ||
4704 | phy_data & E1000_WUS_BC ? "Broadcast Packet" : | ||
4705 | phy_data & E1000_WUS_MAG ? "Magic Packet" : | ||
4706 | phy_data & E1000_WUS_LNKC ? "Link Status " | ||
4707 | " Change" : "other"); | ||
4708 | } | ||
4709 | e1e_wphy(&adapter->hw, BM_WUS, ~0); | ||
4710 | } else { | ||
4711 | u32 wus = er32(WUS); | ||
4712 | if (wus) { | ||
4713 | e_info("MAC Wakeup cause - %s\n", | ||
4714 | wus & E1000_WUS_EX ? "Unicast Packet" : | ||
4715 | wus & E1000_WUS_MC ? "Multicast Packet" : | ||
4716 | wus & E1000_WUS_BC ? "Broadcast Packet" : | ||
4717 | wus & E1000_WUS_MAG ? "Magic Packet" : | ||
4718 | wus & E1000_WUS_LNKC ? "Link Status Change" : | ||
4719 | "other"); | ||
4720 | } | ||
4721 | ew32(WUS, ~0); | ||
4722 | } | ||
4723 | |||
4550 | e1000e_reset(adapter); | 4724 | e1000e_reset(adapter); |
4551 | ew32(WUS, ~0); | ||
4552 | 4725 | ||
4553 | e1000_init_manageability(adapter); | 4726 | e1000_init_manageability(adapter); |
4554 | 4727 | ||
@@ -4994,6 +5167,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
4994 | /* APME bit in EEPROM is mapped to WUC.APME */ | 5167 | /* APME bit in EEPROM is mapped to WUC.APME */ |
4995 | eeprom_data = er32(WUC); | 5168 | eeprom_data = er32(WUC); |
4996 | eeprom_apme_mask = E1000_WUC_APME; | 5169 | eeprom_apme_mask = E1000_WUC_APME; |
5170 | if (eeprom_data & E1000_WUC_PHY_WAKE) | ||
5171 | adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP; | ||
4997 | } else if (adapter->flags & FLAG_APME_IN_CTRL3) { | 5172 | } else if (adapter->flags & FLAG_APME_IN_CTRL3) { |
4998 | if (adapter->flags & FLAG_APME_CHECK_PORT_B && | 5173 | if (adapter->flags & FLAG_APME_CHECK_PORT_B && |
4999 | (adapter->hw.bus.func == 1)) | 5174 | (adapter->hw.bus.func == 1)) |
@@ -5195,6 +5370,11 @@ static struct pci_device_id e1000_pci_tbl[] = { | |||
5195 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan }, | 5370 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan }, |
5196 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan }, | 5371 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan }, |
5197 | 5372 | ||
5373 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan }, | ||
5374 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan }, | ||
5375 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan }, | ||
5376 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan }, | ||
5377 | |||
5198 | { } /* terminate list */ | 5378 | { } /* terminate list */ |
5199 | }; | 5379 | }; |
5200 | MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); | 5380 | MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); |