aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrashant Sreedharan <prashant.sreedharan@broadcom.com>2018-02-19 01:57:04 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-19 14:16:52 -0500
commit506b0a395f26e52b3f18827e0de1be051acb77ab (patch)
tree3b7c93d16550063c81359b9c8a383e1fc7269c69
parentd1c95af366961101819f07e3c64d44f3be7f0367 (diff)
tg3: APE heartbeat changes
In ungraceful host shutdown or driver crash case BMC connectivity is lost. APE firmware is missing the driver state in this case to keep the BMC connectivity alive. This patch has below change to address this issue. Heartbeat mechanism with APE firmware. This heartbeat mechanism is needed to notify the APE firmware about driver state. This patch also has the change in wait time for APE event from 1ms to 20ms as there can be some delay in getting response. v2: Drop inline keyword as per David suggestion. Signed-off-by: Prashant Sreedharan <prashant.sreedharan@broadcom.com> Signed-off-by: Satish Baddipadige <satish.baddipadige@broadcom.com> Signed-off-by: Siva Reddy Kallam <siva.kallam@broadcom.com> Acked-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c35
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h5
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
987static 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
993static void tg3_disable_ints(struct tg3 *tp) 999static 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
7267tx_recovery: 7274tx_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
7349tx_recovery: 7357tx_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
11082restart_timer: 11093restart_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