aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r--drivers/net/e1000e/netdev.c206
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
4404static 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");
4473out:
4474 hw->phy.ops.release_phy(hw);
4475
4476 return retval;
4477}
4478
4345static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) 4479static 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};
5200MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); 5380MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);