Skip to content

Commit e85e271

Browse files
DelphineCCChiukuba-moo
authored andcommitted
net/ncsi: Fix the multi thread manner of NCSI driver
Currently NCSI driver will send several NCSI commands back to back without waiting the response of previous NCSI command or timeout in some state when NIC have multi channel. This operation against the single thread manner defined by NCSI SPEC(section 6.3.2.3 in DSP0222_1.1.1) According to NCSI SPEC(section 6.2.13.1 in DSP0222_1.1.1), we should probe one channel at a time by sending NCSI commands (Clear initial state, Get version ID, Get capabilities...), than repeat this steps until the max number of channels which we got from NCSI command (Get capabilities) has been probed. Fixes: e6f44ed ("net/ncsi: Package and channel management") Signed-off-by: DelphineCCChiu <delphine_cc_chiu@wiwynn.com> Link: https://lore.kernel.org/r/20240529065856.825241-1-delphine_cc_chiu@wiwynn.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 8105378 commit e85e271

3 files changed

Lines changed: 41 additions & 38 deletions

File tree

net/ncsi/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ struct ncsi_dev_priv {
325325
spinlock_t lock; /* Protect the NCSI device */
326326
unsigned int package_probe_id;/* Current ID during probe */
327327
unsigned int package_num; /* Number of packages */
328+
unsigned int channel_probe_id;/* Current cahnnel ID during probe */
328329
struct list_head packages; /* List of packages */
329330
struct ncsi_channel *hot_channel; /* Channel was ever active */
330331
struct ncsi_request requests[256]; /* Request table */
@@ -343,6 +344,7 @@ struct ncsi_dev_priv {
343344
bool multi_package; /* Enable multiple packages */
344345
bool mlx_multi_host; /* Enable multi host Mellanox */
345346
u32 package_whitelist; /* Packages to configure */
347+
unsigned char channel_count; /* Num of channels to probe */
346348
};
347349

348350
struct ncsi_cmd_arg {

net/ncsi/ncsi-manage.c

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -510,17 +510,19 @@ static void ncsi_suspend_channel(struct ncsi_dev_priv *ndp)
510510

511511
break;
512512
case ncsi_dev_state_suspend_gls:
513-
ndp->pending_req_num = np->channel_num;
513+
ndp->pending_req_num = 1;
514514

515515
nca.type = NCSI_PKT_CMD_GLS;
516516
nca.package = np->id;
517+
nca.channel = ndp->channel_probe_id;
518+
ret = ncsi_xmit_cmd(&nca);
519+
if (ret)
520+
goto error;
521+
ndp->channel_probe_id++;
517522

518-
nd->state = ncsi_dev_state_suspend_dcnt;
519-
NCSI_FOR_EACH_CHANNEL(np, nc) {
520-
nca.channel = nc->id;
521-
ret = ncsi_xmit_cmd(&nca);
522-
if (ret)
523-
goto error;
523+
if (ndp->channel_probe_id == ndp->channel_count) {
524+
ndp->channel_probe_id = 0;
525+
nd->state = ncsi_dev_state_suspend_dcnt;
524526
}
525527

526528
break;
@@ -1345,7 +1347,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
13451347
{
13461348
struct ncsi_dev *nd = &ndp->ndev;
13471349
struct ncsi_package *np;
1348-
struct ncsi_channel *nc;
13491350
struct ncsi_cmd_arg nca;
13501351
unsigned char index;
13511352
int ret;
@@ -1423,23 +1424,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
14231424

14241425
nd->state = ncsi_dev_state_probe_cis;
14251426
break;
1426-
case ncsi_dev_state_probe_cis:
1427-
ndp->pending_req_num = NCSI_RESERVED_CHANNEL;
1428-
1429-
/* Clear initial state */
1430-
nca.type = NCSI_PKT_CMD_CIS;
1431-
nca.package = ndp->active_package->id;
1432-
for (index = 0; index < NCSI_RESERVED_CHANNEL; index++) {
1433-
nca.channel = index;
1434-
ret = ncsi_xmit_cmd(&nca);
1435-
if (ret)
1436-
goto error;
1437-
}
1438-
1439-
nd->state = ncsi_dev_state_probe_gvi;
1440-
if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY))
1441-
nd->state = ncsi_dev_state_probe_keep_phy;
1442-
break;
14431427
case ncsi_dev_state_probe_keep_phy:
14441428
ndp->pending_req_num = 1;
14451429

@@ -1452,34 +1436,47 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
14521436

14531437
nd->state = ncsi_dev_state_probe_gvi;
14541438
break;
1439+
case ncsi_dev_state_probe_cis:
14551440
case ncsi_dev_state_probe_gvi:
14561441
case ncsi_dev_state_probe_gc:
14571442
case ncsi_dev_state_probe_gls:
14581443
np = ndp->active_package;
1459-
ndp->pending_req_num = np->channel_num;
1444+
ndp->pending_req_num = 1;
14601445

1461-
/* Retrieve version, capability or link status */
1462-
if (nd->state == ncsi_dev_state_probe_gvi)
1446+
/* Clear initial state Retrieve version, capability or link status */
1447+
if (nd->state == ncsi_dev_state_probe_cis)
1448+
nca.type = NCSI_PKT_CMD_CIS;
1449+
else if (nd->state == ncsi_dev_state_probe_gvi)
14631450
nca.type = NCSI_PKT_CMD_GVI;
14641451
else if (nd->state == ncsi_dev_state_probe_gc)
14651452
nca.type = NCSI_PKT_CMD_GC;
14661453
else
14671454
nca.type = NCSI_PKT_CMD_GLS;
14681455

14691456
nca.package = np->id;
1470-
NCSI_FOR_EACH_CHANNEL(np, nc) {
1471-
nca.channel = nc->id;
1472-
ret = ncsi_xmit_cmd(&nca);
1473-
if (ret)
1474-
goto error;
1475-
}
1457+
nca.channel = ndp->channel_probe_id;
14761458

1477-
if (nd->state == ncsi_dev_state_probe_gvi)
1459+
ret = ncsi_xmit_cmd(&nca);
1460+
if (ret)
1461+
goto error;
1462+
1463+
if (nd->state == ncsi_dev_state_probe_cis) {
1464+
nd->state = ncsi_dev_state_probe_gvi;
1465+
if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) && ndp->channel_probe_id == 0)
1466+
nd->state = ncsi_dev_state_probe_keep_phy;
1467+
} else if (nd->state == ncsi_dev_state_probe_gvi) {
14781468
nd->state = ncsi_dev_state_probe_gc;
1479-
else if (nd->state == ncsi_dev_state_probe_gc)
1469+
} else if (nd->state == ncsi_dev_state_probe_gc) {
14801470
nd->state = ncsi_dev_state_probe_gls;
1481-
else
1471+
} else {
1472+
nd->state = ncsi_dev_state_probe_cis;
1473+
ndp->channel_probe_id++;
1474+
}
1475+
1476+
if (ndp->channel_probe_id == ndp->channel_count) {
1477+
ndp->channel_probe_id = 0;
14821478
nd->state = ncsi_dev_state_probe_dp;
1479+
}
14831480
break;
14841481
case ncsi_dev_state_probe_dp:
14851482
ndp->pending_req_num = 1;
@@ -1780,6 +1777,7 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
17801777
ndp->requests[i].ndp = ndp;
17811778
timer_setup(&ndp->requests[i].timer, ncsi_request_timeout, 0);
17821779
}
1780+
ndp->channel_count = NCSI_RESERVED_CHANNEL;
17831781

17841782
spin_lock_irqsave(&ncsi_dev_lock, flags);
17851783
list_add_tail_rcu(&ndp->node, &ncsi_dev_list);
@@ -1813,6 +1811,7 @@ int ncsi_start_dev(struct ncsi_dev *nd)
18131811

18141812
if (!(ndp->flags & NCSI_DEV_PROBED)) {
18151813
ndp->package_probe_id = 0;
1814+
ndp->channel_probe_id = 0;
18161815
nd->state = ncsi_dev_state_probe;
18171816
schedule_work(&ndp->work);
18181817
return 0;

net/ncsi/ncsi-rsp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,12 +795,13 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
795795
struct ncsi_rsp_gc_pkt *rsp;
796796
struct ncsi_dev_priv *ndp = nr->ndp;
797797
struct ncsi_channel *nc;
798+
struct ncsi_package *np;
798799
size_t size;
799800

800801
/* Find the channel */
801802
rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
802803
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
803-
NULL, &nc);
804+
&np, &nc);
804805
if (!nc)
805806
return -ENODEV;
806807

@@ -835,6 +836,7 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
835836
*/
836837
nc->vlan_filter.bitmap = U64_MAX;
837838
nc->vlan_filter.n_vids = rsp->vlan_cnt;
839+
np->ndp->channel_count = rsp->channel_cnt;
838840

839841
return 0;
840842
}

0 commit comments

Comments
 (0)