diff options
| -rw-r--r-- | drivers/net/e1000e/e1000.h | 2 | ||||
| -rw-r--r-- | drivers/net/e1000e/netdev.c | 31 |
2 files changed, 30 insertions, 3 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index f0c48a2a6799..8087bda97218 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 | ||
| 289 | struct e1000_info { | 291 | struct e1000_info { |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 1f767feda9a7..803545b2fc8c 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 | ||
| 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-- |
| @@ -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 | **/ | ||
| 2931 | static 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) | |||
| 2919 | static void e1000_update_phy_info(unsigned long data) | 2942 | static 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; |
