Skip to content

Commit 228ea8c

Browse files
Edwin Peerdavem330
authored andcommitted
bnxt_en: implement devlink dev reload driver_reinit
The RTNL lock must be held between down and up to prevent interleaving state changes, especially since external state changes might release and allocate different driver resource subsets that would otherwise need to be tracked and carefully handled. If the down function fails, then devlink will not call the corresponding up function, thus the lock is released in the down error paths. v2: Don't use devlink_reload_disable() and devlink_reload_enable(). Instead, check that the netdev is not in unregistered state before proceeding with reload. Signed-off-by: Edwin Peer <edwin.peer@broadcom.com> Signed-Off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d900aad commit 228ea8c

File tree

5 files changed

+110
-11
lines changed

5 files changed

+110
-11
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@
4949
#include <linux/log2.h>
5050
#include <linux/aer.h>
5151
#include <linux/bitmap.h>
52-
#include <linux/ptp_clock_kernel.h>
53-
#include <linux/timecounter.h>
5452
#include <linux/cpu_rmap.h>
5553
#include <linux/cpumask.h>
5654
#include <net/pkt_cls.h>
@@ -4603,7 +4601,7 @@ int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, int bmap_size,
46034601
return rc;
46044602
}
46054603

4606-
static int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp)
4604+
int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp)
46074605
{
46084606
struct hwrm_func_drv_unrgtr_input *req;
46094607
int rc;
@@ -7144,7 +7142,7 @@ static void bnxt_free_ctx_pg_tbls(struct bnxt *bp,
71447142
ctx_pg->nr_pages = 0;
71457143
}
71467144

7147-
static void bnxt_free_ctx_mem(struct bnxt *bp)
7145+
void bnxt_free_ctx_mem(struct bnxt *bp)
71487146
{
71497147
struct bnxt_ctx_mem_info *ctx = bp->ctx;
71507148
int i;
@@ -9198,7 +9196,7 @@ static char *bnxt_report_fec(struct bnxt_link_info *link_info)
91989196
}
91999197
}
92009198

9201-
static void bnxt_report_link(struct bnxt *bp)
9199+
void bnxt_report_link(struct bnxt *bp)
92029200
{
92039201
if (bp->link_info.link_up) {
92049202
const char *signal = "";
@@ -9643,8 +9641,6 @@ static int bnxt_hwrm_shutdown_link(struct bnxt *bp)
96439641
return hwrm_req_send(bp, req);
96449642
}
96459643

9646-
static int bnxt_fw_init_one(struct bnxt *bp);
9647-
96489644
static int bnxt_fw_reset_via_optee(struct bnxt *bp)
96499645
{
96509646
#ifdef CONFIG_TEE_BNXT_FW
@@ -10279,7 +10275,7 @@ void bnxt_half_close_nic(struct bnxt *bp)
1027910275
bnxt_free_mem(bp, false);
1028010276
}
1028110277

10282-
static void bnxt_reenable_sriov(struct bnxt *bp)
10278+
void bnxt_reenable_sriov(struct bnxt *bp)
1028310279
{
1028410280
if (BNXT_PF(bp)) {
1028510281
struct bnxt_pf_info *pf = &bp->pf;
@@ -11950,7 +11946,7 @@ static void bnxt_fw_init_one_p3(struct bnxt *bp)
1195011946

1195111947
static int bnxt_probe_phy(struct bnxt *bp, bool fw_dflt);
1195211948

11953-
static int bnxt_fw_init_one(struct bnxt *bp)
11949+
int bnxt_fw_init_one(struct bnxt *bp)
1195411950
{
1195511951
int rc;
1195611952

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,11 +2230,13 @@ void bnxt_set_ring_params(struct bnxt *);
22302230
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
22312231
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
22322232
int bmap_size, bool async_only);
2233+
int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp);
22332234
int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
22342235
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
22352236
int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
22362237
int bnxt_nq_rings_in_use(struct bnxt *bp);
22372238
int bnxt_hwrm_set_coal(struct bnxt *);
2239+
void bnxt_free_ctx_mem(struct bnxt *bp);
22382240
unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp);
22392241
unsigned int bnxt_get_avail_stat_ctxs_for_en(struct bnxt *bp);
22402242
unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
@@ -2243,6 +2245,7 @@ int bnxt_get_avail_msix(struct bnxt *bp, int num);
22432245
int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
22442246
void bnxt_tx_disable(struct bnxt *bp);
22452247
void bnxt_tx_enable(struct bnxt *bp);
2248+
void bnxt_report_link(struct bnxt *bp);
22462249
int bnxt_update_link(struct bnxt *bp, bool chng_link_state);
22472250
int bnxt_hwrm_set_pause(struct bnxt *);
22482251
int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool);
@@ -2255,13 +2258,15 @@ int bnxt_hwrm_fw_set_time(struct bnxt *);
22552258
int bnxt_open_nic(struct bnxt *, bool, bool);
22562259
int bnxt_half_open_nic(struct bnxt *bp);
22572260
void bnxt_half_close_nic(struct bnxt *bp);
2261+
void bnxt_reenable_sriov(struct bnxt *bp);
22582262
int bnxt_close_nic(struct bnxt *, bool, bool);
22592263
int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
22602264
u32 *reg_buf);
22612265
void bnxt_fw_exception(struct bnxt *bp);
22622266
void bnxt_fw_reset(struct bnxt *bp);
22632267
int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
22642268
int tx_xdp);
2269+
int bnxt_fw_init_one(struct bnxt *bp);
22652270
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
22662271
int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
22672272
int bnxt_restore_pf_fw_resources(struct bnxt *bp);

drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "bnxt_vfr.h"
1717
#include "bnxt_devlink.h"
1818
#include "bnxt_ethtool.h"
19+
#include "bnxt_ulp.h"
20+
#include "bnxt_ptp.h"
1921

2022
static int
2123
bnxt_dl_flash_update(struct devlink *dl,
@@ -280,13 +282,108 @@ void bnxt_dl_health_recovery_done(struct bnxt *bp)
280282
static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
281283
struct netlink_ext_ack *extack);
282284

285+
static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change,
286+
enum devlink_reload_action action,
287+
enum devlink_reload_limit limit,
288+
struct netlink_ext_ack *extack)
289+
{
290+
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
291+
int rc = 0;
292+
293+
switch (action) {
294+
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
295+
if (BNXT_PF(bp) && bp->pf.active_vfs) {
296+
NL_SET_ERR_MSG_MOD(extack,
297+
"reload is unsupported when VFs are allocated\n");
298+
return -EOPNOTSUPP;
299+
}
300+
rtnl_lock();
301+
if (bp->dev->reg_state == NETREG_UNREGISTERED) {
302+
rtnl_unlock();
303+
return -ENODEV;
304+
}
305+
bnxt_ulp_stop(bp);
306+
if (netif_running(bp->dev)) {
307+
rc = bnxt_close_nic(bp, true, true);
308+
if (rc) {
309+
NL_SET_ERR_MSG_MOD(extack, "Failed to close");
310+
dev_close(bp->dev);
311+
rtnl_unlock();
312+
break;
313+
}
314+
}
315+
bnxt_vf_reps_free(bp);
316+
rc = bnxt_hwrm_func_drv_unrgtr(bp);
317+
if (rc) {
318+
NL_SET_ERR_MSG_MOD(extack, "Failed to deregister");
319+
if (netif_running(bp->dev))
320+
dev_close(bp->dev);
321+
rtnl_unlock();
322+
break;
323+
}
324+
bnxt_cancel_reservations(bp, false);
325+
bnxt_free_ctx_mem(bp);
326+
kfree(bp->ctx);
327+
bp->ctx = NULL;
328+
break;
329+
}
330+
default:
331+
rc = -EOPNOTSUPP;
332+
}
333+
334+
return rc;
335+
}
336+
337+
static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action action,
338+
enum devlink_reload_limit limit, u32 *actions_performed,
339+
struct netlink_ext_ack *extack)
340+
{
341+
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
342+
int rc = 0;
343+
344+
*actions_performed = 0;
345+
switch (action) {
346+
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
347+
bnxt_fw_init_one(bp);
348+
bnxt_vf_reps_alloc(bp);
349+
if (netif_running(bp->dev))
350+
rc = bnxt_open_nic(bp, true, true);
351+
bnxt_ulp_start(bp, rc);
352+
if (!rc) {
353+
bnxt_reenable_sriov(bp);
354+
bnxt_ptp_reapply_pps(bp);
355+
}
356+
break;
357+
}
358+
default:
359+
return -EOPNOTSUPP;
360+
}
361+
362+
if (!rc) {
363+
bnxt_print_device_info(bp);
364+
if (netif_running(bp->dev)) {
365+
mutex_lock(&bp->link_lock);
366+
bnxt_report_link(bp);
367+
mutex_unlock(&bp->link_lock);
368+
}
369+
*actions_performed |= BIT(action);
370+
} else if (netif_running(bp->dev)) {
371+
dev_close(bp->dev);
372+
}
373+
rtnl_unlock();
374+
return rc;
375+
}
376+
283377
static const struct devlink_ops bnxt_dl_ops = {
284378
#ifdef CONFIG_BNXT_SRIOV
285379
.eswitch_mode_set = bnxt_dl_eswitch_mode_set,
286380
.eswitch_mode_get = bnxt_dl_eswitch_mode_get,
287381
#endif /* CONFIG_BNXT_SRIOV */
288382
.info_get = bnxt_dl_info_get,
289383
.flash_update = bnxt_dl_flash_update,
384+
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
385+
.reload_down = bnxt_dl_reload_down,
386+
.reload_up = bnxt_dl_reload_up,
290387
};
291388

292389
static const struct devlink_ops bnxt_vf_dl_ops;

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
#include <linux/pci.h>
1212
#include <linux/netdevice.h>
1313
#include <linux/etherdevice.h>
14-
#include <linux/ptp_clock_kernel.h>
1514
#include <linux/net_tstamp.h>
16-
#include <linux/timecounter.h>
1715
#include <linux/timekeeping.h>
1816
#include <linux/ptp_classify.h>
1917
#include "bnxt_hsi.h"

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#ifndef BNXT_PTP_H
1111
#define BNXT_PTP_H
1212

13+
#include <linux/ptp_clock_kernel.h>
14+
#include <linux/timecounter.h>
15+
1316
#define BNXT_PTP_GRC_WIN 6
1417
#define BNXT_PTP_GRC_WIN_BASE 0x6000
1518

0 commit comments

Comments
 (0)