Skip to content

Commit abd75d1

Browse files
emuslndavem330
authored andcommitted
ionic: better handling of RESET event
When IONIC_EVENT_RESET is received, we only need to start the fw_down process if we aren't already down, and we need to be sure to set the FW_STOPPING state on the way. If this is how we noticed that FW was stopped, it is most likely from a FW update, and we'll see a new FW generation. The update happens quickly enough that we might not see fw_status==0, so we need to be sure things get restarted when we see the fw_generation change. Fixes: d266207 ("ionic: monitor fw status generation") Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 398d1e3 commit abd75d1

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

drivers/net/ethernet/pensando/ionic/ionic_dev.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ static void ionic_watchdog_cb(struct timer_list *t)
3333
!test_bit(IONIC_LIF_F_FW_RESET, lif->state))
3434
ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
3535

36-
if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state)) {
36+
if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state) &&
37+
!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
3738
work = kzalloc(sizeof(*work), GFP_ATOMIC);
3839
if (!work) {
3940
netdev_err(lif->netdev, "rxmode change dropped\n");
@@ -148,8 +149,9 @@ bool ionic_is_fw_running(struct ionic_dev *idev)
148149

149150
int ionic_heartbeat_check(struct ionic *ionic)
150151
{
151-
struct ionic_dev *idev = &ionic->idev;
152152
unsigned long check_time, last_check_time;
153+
struct ionic_dev *idev = &ionic->idev;
154+
struct ionic_lif *lif = ionic->lif;
153155
bool fw_status_ready = true;
154156
bool fw_hb_ready;
155157
u8 fw_generation;
@@ -187,14 +189,21 @@ int ionic_heartbeat_check(struct ionic *ionic)
187189
* the down, the next watchdog will see the fw is up
188190
* and the generation value stable, so will trigger
189191
* the fw-up activity.
192+
*
193+
* If we had already moved to FW_RESET from a RESET event,
194+
* it is possible that we never saw the fw_status go to 0,
195+
* so we fake the current idev->fw_status_ready here to
196+
* force the transition and get FW up again.
190197
*/
191-
fw_status_ready = false;
198+
if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
199+
idev->fw_status_ready = false; /* go to running */
200+
else
201+
fw_status_ready = false; /* go to down */
192202
}
193203
}
194204

195205
/* is this a transition? */
196206
if (fw_status_ready != idev->fw_status_ready) {
197-
struct ionic_lif *lif = ionic->lif;
198207
bool trigger = false;
199208

200209
if (!fw_status_ready && lif &&

drivers/net/ethernet/pensando/ionic/ionic_lif.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,12 +1112,17 @@ static bool ionic_notifyq_service(struct ionic_cq *cq,
11121112
ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
11131113
break;
11141114
case IONIC_EVENT_RESET:
1115-
work = kzalloc(sizeof(*work), GFP_ATOMIC);
1116-
if (!work) {
1117-
netdev_err(lif->netdev, "Reset event dropped\n");
1118-
} else {
1119-
work->type = IONIC_DW_TYPE_LIF_RESET;
1120-
ionic_lif_deferred_enqueue(&lif->deferred, work);
1115+
if (lif->ionic->idev.fw_status_ready &&
1116+
!test_bit(IONIC_LIF_F_FW_RESET, lif->state) &&
1117+
!test_and_set_bit(IONIC_LIF_F_FW_STOPPING, lif->state)) {
1118+
work = kzalloc(sizeof(*work), GFP_ATOMIC);
1119+
if (!work) {
1120+
netdev_err(lif->netdev, "Reset event dropped\n");
1121+
clear_bit(IONIC_LIF_F_FW_STOPPING, lif->state);
1122+
} else {
1123+
work->type = IONIC_DW_TYPE_LIF_RESET;
1124+
ionic_lif_deferred_enqueue(&lif->deferred, work);
1125+
}
11211126
}
11221127
break;
11231128
default:

0 commit comments

Comments
 (0)