diff options
| -rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 35 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/tg3.h | 5 |
2 files changed, 29 insertions, 11 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a77ee2f8fb8d..c1841db1b500 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -820,7 +820,7 @@ static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us) | |||
| 820 | 820 | ||
| 821 | tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); | 821 | tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); |
| 822 | 822 | ||
| 823 | udelay(10); | 823 | usleep_range(10, 20); |
| 824 | timeout_us -= (timeout_us > 10) ? 10 : timeout_us; | 824 | timeout_us -= (timeout_us > 10) ? 10 : timeout_us; |
| 825 | } | 825 | } |
| 826 | 826 | ||
| @@ -922,8 +922,8 @@ static int tg3_ape_send_event(struct tg3 *tp, u32 event) | |||
| 922 | if (!(apedata & APE_FW_STATUS_READY)) | 922 | if (!(apedata & APE_FW_STATUS_READY)) |
| 923 | return -EAGAIN; | 923 | return -EAGAIN; |
| 924 | 924 | ||
| 925 | /* Wait for up to 1 millisecond for APE to service previous event. */ | 925 | /* Wait for up to 20 millisecond for APE to service previous event. */ |
| 926 | err = tg3_ape_event_lock(tp, 1000); | 926 | err = tg3_ape_event_lock(tp, 20000); |
| 927 | if (err) | 927 | if (err) |
| 928 | return err; | 928 | return err; |
| 929 | 929 | ||
| @@ -946,6 +946,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) | |||
| 946 | 946 | ||
| 947 | switch (kind) { | 947 | switch (kind) { |
| 948 | case RESET_KIND_INIT: | 948 | case RESET_KIND_INIT: |
| 949 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++); | ||
| 949 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, | 950 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, |
| 950 | APE_HOST_SEG_SIG_MAGIC); | 951 | APE_HOST_SEG_SIG_MAGIC); |
| 951 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN, | 952 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN, |
| @@ -962,13 +963,6 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) | |||
| 962 | event = APE_EVENT_STATUS_STATE_START; | 963 | event = APE_EVENT_STATUS_STATE_START; |
| 963 | break; | 964 | break; |
| 964 | case RESET_KIND_SHUTDOWN: | 965 | case RESET_KIND_SHUTDOWN: |
| 965 | /* With the interface we are currently using, | ||
| 966 | * APE does not track driver state. Wiping | ||
| 967 | * out the HOST SEGMENT SIGNATURE forces | ||
| 968 | * the APE to assume OS absent status. | ||
| 969 | */ | ||
| 970 | tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0); | ||
| 971 | |||
| 972 | if (device_may_wakeup(&tp->pdev->dev) && | 966 | if (device_may_wakeup(&tp->pdev->dev) && |
| 973 | tg3_flag(tp, WOL_ENABLE)) { | 967 | tg3_flag(tp, WOL_ENABLE)) { |
| 974 | tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, | 968 | tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, |
| @@ -990,6 +984,18 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) | |||
| 990 | tg3_ape_send_event(tp, event); | 984 | tg3_ape_send_event(tp, event); |
| 991 | } | 985 | } |
| 992 | 986 | ||
| 987 | static void tg3_send_ape_heartbeat(struct tg3 *tp, | ||
| 988 | unsigned long interval) | ||
| 989 | { | ||
| 990 | /* Check if hb interval has exceeded */ | ||
| 991 | if (!tg3_flag(tp, ENABLE_APE) || | ||
| 992 | time_before(jiffies, tp->ape_hb_jiffies + interval)) | ||
| 993 | return; | ||
| 994 | |||
| 995 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++); | ||
| 996 | tp->ape_hb_jiffies = jiffies; | ||
| 997 | } | ||
| 998 | |||
| 993 | static void tg3_disable_ints(struct tg3 *tp) | 999 | static void tg3_disable_ints(struct tg3 *tp) |
| 994 | { | 1000 | { |
| 995 | int i; | 1001 | int i; |
| @@ -7262,6 +7268,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget) | |||
| 7262 | } | 7268 | } |
| 7263 | } | 7269 | } |
| 7264 | 7270 | ||
| 7271 | tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1); | ||
| 7265 | return work_done; | 7272 | return work_done; |
| 7266 | 7273 | ||
| 7267 | tx_recovery: | 7274 | tx_recovery: |
| @@ -7344,6 +7351,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) | |||
| 7344 | } | 7351 | } |
| 7345 | } | 7352 | } |
| 7346 | 7353 | ||
| 7354 | tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1); | ||
| 7347 | return work_done; | 7355 | return work_done; |
| 7348 | 7356 | ||
| 7349 | tx_recovery: | 7357 | tx_recovery: |
| @@ -10732,7 +10740,7 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) | |||
| 10732 | if (tg3_flag(tp, ENABLE_APE)) | 10740 | if (tg3_flag(tp, ENABLE_APE)) |
| 10733 | /* Write our heartbeat update interval to APE. */ | 10741 | /* Write our heartbeat update interval to APE. */ |
| 10734 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS, | 10742 | tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS, |
| 10735 | APE_HOST_HEARTBEAT_INT_DISABLE); | 10743 | APE_HOST_HEARTBEAT_INT_5SEC); |
| 10736 | 10744 | ||
| 10737 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); | 10745 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); |
| 10738 | 10746 | ||
| @@ -11077,6 +11085,9 @@ static void tg3_timer(struct timer_list *t) | |||
| 11077 | tp->asf_counter = tp->asf_multiplier; | 11085 | tp->asf_counter = tp->asf_multiplier; |
| 11078 | } | 11086 | } |
| 11079 | 11087 | ||
| 11088 | /* Update the APE heartbeat every 5 seconds.*/ | ||
| 11089 | tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL); | ||
| 11090 | |||
| 11080 | spin_unlock(&tp->lock); | 11091 | spin_unlock(&tp->lock); |
| 11081 | 11092 | ||
| 11082 | restart_timer: | 11093 | restart_timer: |
| @@ -16653,6 +16664,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) | |||
| 16653 | pci_state_reg); | 16664 | pci_state_reg); |
| 16654 | 16665 | ||
| 16655 | tg3_ape_lock_init(tp); | 16666 | tg3_ape_lock_init(tp); |
| 16667 | tp->ape_hb_interval = | ||
| 16668 | msecs_to_jiffies(APE_HOST_HEARTBEAT_INT_5SEC); | ||
| 16656 | } | 16669 | } |
| 16657 | 16670 | ||
| 16658 | /* Set up tp->grc_local_ctrl before calling | 16671 | /* Set up tp->grc_local_ctrl before calling |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 47f51cc0566d..1d61aa3efda1 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
| @@ -2508,6 +2508,7 @@ | |||
| 2508 | #define TG3_APE_LOCK_PHY3 5 | 2508 | #define TG3_APE_LOCK_PHY3 5 |
| 2509 | #define TG3_APE_LOCK_GPIO 7 | 2509 | #define TG3_APE_LOCK_GPIO 7 |
| 2510 | 2510 | ||
| 2511 | #define TG3_APE_HB_INTERVAL (tp->ape_hb_interval) | ||
| 2511 | #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 | 2512 | #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 |
| 2512 | 2513 | ||
| 2513 | 2514 | ||
| @@ -3423,6 +3424,10 @@ struct tg3 { | |||
| 3423 | struct device *hwmon_dev; | 3424 | struct device *hwmon_dev; |
| 3424 | bool link_up; | 3425 | bool link_up; |
| 3425 | bool pcierr_recovery; | 3426 | bool pcierr_recovery; |
| 3427 | |||
| 3428 | u32 ape_hb; | ||
| 3429 | unsigned long ape_hb_interval; | ||
| 3430 | unsigned long ape_hb_jiffies; | ||
| 3426 | }; | 3431 | }; |
| 3427 | 3432 | ||
| 3428 | /* Accessor macros for chip and asic attributes | 3433 | /* Accessor macros for chip and asic attributes |
