diff options
| -rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 553dcd8a9df2..96bf01ba32dd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -7413,6 +7413,8 @@ static inline void tg3_netif_start(struct tg3 *tp) | |||
| 7413 | } | 7413 | } |
| 7414 | 7414 | ||
| 7415 | static void tg3_irq_quiesce(struct tg3 *tp) | 7415 | static void tg3_irq_quiesce(struct tg3 *tp) |
| 7416 | __releases(tp->lock) | ||
| 7417 | __acquires(tp->lock) | ||
| 7416 | { | 7418 | { |
| 7417 | int i; | 7419 | int i; |
| 7418 | 7420 | ||
| @@ -7421,8 +7423,12 @@ static void tg3_irq_quiesce(struct tg3 *tp) | |||
| 7421 | tp->irq_sync = 1; | 7423 | tp->irq_sync = 1; |
| 7422 | smp_mb(); | 7424 | smp_mb(); |
| 7423 | 7425 | ||
| 7426 | spin_unlock_bh(&tp->lock); | ||
| 7427 | |||
| 7424 | for (i = 0; i < tp->irq_cnt; i++) | 7428 | for (i = 0; i < tp->irq_cnt; i++) |
| 7425 | synchronize_irq(tp->napi[i].irq_vec); | 7429 | synchronize_irq(tp->napi[i].irq_vec); |
| 7430 | |||
| 7431 | spin_lock_bh(&tp->lock); | ||
| 7426 | } | 7432 | } |
| 7427 | 7433 | ||
| 7428 | /* Fully shutdown all tg3 driver activity elsewhere in the system. | 7434 | /* Fully shutdown all tg3 driver activity elsewhere in the system. |
| @@ -9018,6 +9024,8 @@ static void tg3_restore_clk(struct tg3 *tp) | |||
| 9018 | 9024 | ||
| 9019 | /* tp->lock is held. */ | 9025 | /* tp->lock is held. */ |
| 9020 | static int tg3_chip_reset(struct tg3 *tp) | 9026 | static int tg3_chip_reset(struct tg3 *tp) |
| 9027 | __releases(tp->lock) | ||
| 9028 | __acquires(tp->lock) | ||
| 9021 | { | 9029 | { |
| 9022 | u32 val; | 9030 | u32 val; |
| 9023 | void (*write_op)(struct tg3 *, u32, u32); | 9031 | void (*write_op)(struct tg3 *, u32, u32); |
| @@ -9073,9 +9081,13 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
| 9073 | } | 9081 | } |
| 9074 | smp_mb(); | 9082 | smp_mb(); |
| 9075 | 9083 | ||
| 9084 | tg3_full_unlock(tp); | ||
| 9085 | |||
| 9076 | for (i = 0; i < tp->irq_cnt; i++) | 9086 | for (i = 0; i < tp->irq_cnt; i++) |
| 9077 | synchronize_irq(tp->napi[i].irq_vec); | 9087 | synchronize_irq(tp->napi[i].irq_vec); |
| 9078 | 9088 | ||
| 9089 | tg3_full_lock(tp, 0); | ||
| 9090 | |||
| 9079 | if (tg3_asic_rev(tp) == ASIC_REV_57780) { | 9091 | if (tg3_asic_rev(tp) == ASIC_REV_57780) { |
| 9080 | val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; | 9092 | val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; |
| 9081 | tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); | 9093 | tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); |
| @@ -10903,11 +10915,13 @@ static void tg3_timer(unsigned long __opaque) | |||
| 10903 | { | 10915 | { |
| 10904 | struct tg3 *tp = (struct tg3 *) __opaque; | 10916 | struct tg3 *tp = (struct tg3 *) __opaque; |
| 10905 | 10917 | ||
| 10906 | if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) | ||
| 10907 | goto restart_timer; | ||
| 10908 | |||
| 10909 | spin_lock(&tp->lock); | 10918 | spin_lock(&tp->lock); |
| 10910 | 10919 | ||
| 10920 | if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) { | ||
| 10921 | spin_unlock(&tp->lock); | ||
| 10922 | goto restart_timer; | ||
| 10923 | } | ||
| 10924 | |||
| 10911 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || | 10925 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || |
| 10912 | tg3_flag(tp, 57765_CLASS)) | 10926 | tg3_flag(tp, 57765_CLASS)) |
| 10913 | tg3_chk_missed_msi(tp); | 10927 | tg3_chk_missed_msi(tp); |
| @@ -11101,11 +11115,13 @@ static void tg3_reset_task(struct work_struct *work) | |||
| 11101 | struct tg3 *tp = container_of(work, struct tg3, reset_task); | 11115 | struct tg3 *tp = container_of(work, struct tg3, reset_task); |
| 11102 | int err; | 11116 | int err; |
| 11103 | 11117 | ||
| 11118 | rtnl_lock(); | ||
| 11104 | tg3_full_lock(tp, 0); | 11119 | tg3_full_lock(tp, 0); |
| 11105 | 11120 | ||
| 11106 | if (!netif_running(tp->dev)) { | 11121 | if (!netif_running(tp->dev)) { |
| 11107 | tg3_flag_clear(tp, RESET_TASK_PENDING); | 11122 | tg3_flag_clear(tp, RESET_TASK_PENDING); |
| 11108 | tg3_full_unlock(tp); | 11123 | tg3_full_unlock(tp); |
| 11124 | rtnl_unlock(); | ||
| 11109 | return; | 11125 | return; |
| 11110 | } | 11126 | } |
| 11111 | 11127 | ||
| @@ -11138,6 +11154,7 @@ out: | |||
| 11138 | tg3_phy_start(tp); | 11154 | tg3_phy_start(tp); |
| 11139 | 11155 | ||
| 11140 | tg3_flag_clear(tp, RESET_TASK_PENDING); | 11156 | tg3_flag_clear(tp, RESET_TASK_PENDING); |
| 11157 | rtnl_unlock(); | ||
| 11141 | } | 11158 | } |
| 11142 | 11159 | ||
| 11143 | static int tg3_request_irq(struct tg3 *tp, int irq_num) | 11160 | static int tg3_request_irq(struct tg3 *tp, int irq_num) |
