Skip to content

Commit 506b0a3

Browse files
Prashant Sreedharandavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Satish Baddipadige <[email protected]> Signed-off-by: Siva Reddy Kallam <[email protected]> Acked-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d1c95af commit 506b0a3

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

drivers/net/ethernet/broadcom/tg3.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us)
820820

821821
tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
822822

823-
udelay(10);
823+
usleep_range(10, 20);
824824
timeout_us -= (timeout_us > 10) ? 10 : timeout_us;
825825
}
826826

@@ -922,8 +922,8 @@ static int tg3_ape_send_event(struct tg3 *tp, u32 event)
922922
if (!(apedata & APE_FW_STATUS_READY))
923923
return -EAGAIN;
924924

925-
/* Wait for up to 1 millisecond for APE to service previous event. */
926-
err = tg3_ape_event_lock(tp, 1000);
925+
/* Wait for up to 20 millisecond for APE to service previous event. */
926+
err = tg3_ape_event_lock(tp, 20000);
927927
if (err)
928928
return err;
929929

@@ -946,6 +946,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
946946

947947
switch (kind) {
948948
case RESET_KIND_INIT:
949+
tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++);
949950
tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG,
950951
APE_HOST_SEG_SIG_MAGIC);
951952
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)
962963
event = APE_EVENT_STATUS_STATE_START;
963964
break;
964965
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-
972966
if (device_may_wakeup(&tp->pdev->dev) &&
973967
tg3_flag(tp, WOL_ENABLE)) {
974968
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)
990984
tg3_ape_send_event(tp, event);
991985
}
992986

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+
993999
static void tg3_disable_ints(struct tg3 *tp)
9941000
{
9951001
int i;
@@ -7262,6 +7268,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)
72627268
}
72637269
}
72647270

7271+
tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1);
72657272
return work_done;
72667273

72677274
tx_recovery:
@@ -7344,6 +7351,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
73447351
}
73457352
}
73467353

7354+
tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1);
73477355
return work_done;
73487356

73497357
tx_recovery:
@@ -10732,7 +10740,7 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
1073210740
if (tg3_flag(tp, ENABLE_APE))
1073310741
/* Write our heartbeat update interval to APE. */
1073410742
tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS,
10735-
APE_HOST_HEARTBEAT_INT_DISABLE);
10743+
APE_HOST_HEARTBEAT_INT_5SEC);
1073610744

1073710745
tg3_write_sig_post_reset(tp, RESET_KIND_INIT);
1073810746

@@ -11077,6 +11085,9 @@ static void tg3_timer(struct timer_list *t)
1107711085
tp->asf_counter = tp->asf_multiplier;
1107811086
}
1107911087

11088+
/* Update the APE heartbeat every 5 seconds.*/
11089+
tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL);
11090+
1108011091
spin_unlock(&tp->lock);
1108111092

1108211093
restart_timer:
@@ -16653,6 +16664,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
1665316664
pci_state_reg);
1665416665

1665516666
tg3_ape_lock_init(tp);
16667+
tp->ape_hb_interval =
16668+
msecs_to_jiffies(APE_HOST_HEARTBEAT_INT_5SEC);
1665616669
}
1665716670

1665816671
/* Set up tp->grc_local_ctrl before calling

drivers/net/ethernet/broadcom/tg3.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,6 +2508,7 @@
25082508
#define TG3_APE_LOCK_PHY3 5
25092509
#define TG3_APE_LOCK_GPIO 7
25102510

2511+
#define TG3_APE_HB_INTERVAL (tp->ape_hb_interval)
25112512
#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10
25122513

25132514

@@ -3423,6 +3424,10 @@ struct tg3 {
34233424
struct device *hwmon_dev;
34243425
bool link_up;
34253426
bool pcierr_recovery;
3427+
3428+
u32 ape_hb;
3429+
unsigned long ape_hb_interval;
3430+
unsigned long ape_hb_jiffies;
34263431
};
34273432

34283433
/* Accessor macros for chip and asic attributes

0 commit comments

Comments
 (0)