aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/e1000e/e1000.h2
-rw-r--r--drivers/net/e1000e/netdev.c31
2 files changed, 30 insertions, 3 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index f0c48a2a679..8087bda9721 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -284,6 +284,8 @@ struct e1000_adapter {
284 unsigned long led_status; 284 unsigned long led_status;
285 285
286 unsigned int flags; 286 unsigned int flags;
287 struct work_struct downshift_task;
288 struct work_struct update_phy_task;
287}; 289};
288 290
289struct e1000_info { 291struct e1000_info {
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 1f767feda9a..803545b2fc8 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -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
1118static 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--
@@ -2912,6 +2920,21 @@ static int e1000_set_mac(struct net_device *netdev, void *p)
2912 return 0; 2920 return 0;
2913} 2921}
2914 2922
2923/**
2924 * e1000e_update_phy_task - work thread to update phy
2925 * @work: pointer to our work struct
2926 *
2927 * this worker thread exists because we must acquire a
2928 * semaphore to read the phy, which we could msleep while
2929 * waiting for it, and we can't msleep in a timer.
2930 **/
2931static void e1000e_update_phy_task(struct work_struct *work)
2932{
2933 struct e1000_adapter *adapter = container_of(work,
2934 struct e1000_adapter, update_phy_task);
2935 e1000_get_phy_info(&adapter->hw);
2936}
2937
2915/* 2938/*
2916 * Need to wait a few seconds after link up to get diagnostic information from 2939 * Need to wait a few seconds after link up to get diagnostic information from
2917 * the phy 2940 * the phy
@@ -2919,7 +2942,7 @@ static int e1000_set_mac(struct net_device *netdev, void *p)
2919static void e1000_update_phy_info(unsigned long data) 2942static void e1000_update_phy_info(unsigned long data)
2920{ 2943{
2921 struct e1000_adapter *adapter = (struct e1000_adapter *) data; 2944 struct e1000_adapter *adapter = (struct e1000_adapter *) data;
2922 e1000_get_phy_info(&adapter->hw); 2945 schedule_work(&adapter->update_phy_task);
2923} 2946}
2924 2947
2925/** 2948/**
@@ -4578,6 +4601,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4578 4601
4579 INIT_WORK(&adapter->reset_task, e1000_reset_task); 4602 INIT_WORK(&adapter->reset_task, e1000_reset_task);
4580 INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); 4603 INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
4604 INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
4605 INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
4581 4606
4582 /* Initialize link parameters. User can change them with ethtool */ 4607 /* Initialize link parameters. User can change them with ethtool */
4583 adapter->hw.mac.autoneg = 1; 4608 adapter->hw.mac.autoneg = 1;