Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: e6f44ed6d04d ("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>

authored by

DelphineCCChiu and committed by
Jakub Kicinski
e85e271d 8105378c

+42 -39
+2
net/ncsi/internal.h
··· 325 325 spinlock_t lock; /* Protect the NCSI device */ 326 326 unsigned int package_probe_id;/* Current ID during probe */ 327 327 unsigned int package_num; /* Number of packages */ 328 + unsigned int channel_probe_id;/* Current cahnnel ID during probe */ 328 329 struct list_head packages; /* List of packages */ 329 330 struct ncsi_channel *hot_channel; /* Channel was ever active */ 330 331 struct ncsi_request requests[256]; /* Request table */ ··· 344 343 bool multi_package; /* Enable multiple packages */ 345 344 bool mlx_multi_host; /* Enable multi host Mellanox */ 346 345 u32 package_whitelist; /* Packages to configure */ 346 + unsigned char channel_count; /* Num of channels to probe */ 347 347 }; 348 348 349 349 struct ncsi_cmd_arg {
+37 -38
net/ncsi/ncsi-manage.c
··· 510 510 511 511 break; 512 512 case ncsi_dev_state_suspend_gls: 513 - ndp->pending_req_num = np->channel_num; 513 + ndp->pending_req_num = 1; 514 514 515 515 nca.type = NCSI_PKT_CMD_GLS; 516 516 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++; 517 522 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; 524 526 } 525 527 526 528 break; ··· 1347 1345 { 1348 1346 struct ncsi_dev *nd = &ndp->ndev; 1349 1347 struct ncsi_package *np; 1350 - struct ncsi_channel *nc; 1351 1348 struct ncsi_cmd_arg nca; 1352 1349 unsigned char index; 1353 1350 int ret; ··· 1424 1423 1425 1424 nd->state = ncsi_dev_state_probe_cis; 1426 1425 break; 1427 - case ncsi_dev_state_probe_cis: 1428 - ndp->pending_req_num = NCSI_RESERVED_CHANNEL; 1429 - 1430 - /* Clear initial state */ 1431 - nca.type = NCSI_PKT_CMD_CIS; 1432 - nca.package = ndp->active_package->id; 1433 - for (index = 0; index < NCSI_RESERVED_CHANNEL; index++) { 1434 - nca.channel = index; 1435 - ret = ncsi_xmit_cmd(&nca); 1436 - if (ret) 1437 - goto error; 1438 - } 1439 - 1440 - nd->state = ncsi_dev_state_probe_gvi; 1441 - if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)) 1442 - nd->state = ncsi_dev_state_probe_keep_phy; 1443 - break; 1444 1426 case ncsi_dev_state_probe_keep_phy: 1445 1427 ndp->pending_req_num = 1; 1446 1428 ··· 1436 1452 1437 1453 nd->state = ncsi_dev_state_probe_gvi; 1438 1454 break; 1455 + case ncsi_dev_state_probe_cis: 1439 1456 case ncsi_dev_state_probe_gvi: 1440 1457 case ncsi_dev_state_probe_gc: 1441 1458 case ncsi_dev_state_probe_gls: 1442 1459 np = ndp->active_package; 1443 - ndp->pending_req_num = np->channel_num; 1460 + ndp->pending_req_num = 1; 1444 1461 1445 - /* Retrieve version, capability or link status */ 1446 - if (nd->state == ncsi_dev_state_probe_gvi) 1462 + /* Clear initial state Retrieve version, capability or link status */ 1463 + if (nd->state == ncsi_dev_state_probe_cis) 1464 + nca.type = NCSI_PKT_CMD_CIS; 1465 + else if (nd->state == ncsi_dev_state_probe_gvi) 1447 1466 nca.type = NCSI_PKT_CMD_GVI; 1448 1467 else if (nd->state == ncsi_dev_state_probe_gc) 1449 1468 nca.type = NCSI_PKT_CMD_GC; ··· 1454 1467 nca.type = NCSI_PKT_CMD_GLS; 1455 1468 1456 1469 nca.package = np->id; 1457 - NCSI_FOR_EACH_CHANNEL(np, nc) { 1458 - nca.channel = nc->id; 1459 - ret = ncsi_xmit_cmd(&nca); 1460 - if (ret) 1461 - goto error; 1470 + nca.channel = ndp->channel_probe_id; 1471 + 1472 + ret = ncsi_xmit_cmd(&nca); 1473 + if (ret) 1474 + goto error; 1475 + 1476 + if (nd->state == ncsi_dev_state_probe_cis) { 1477 + nd->state = ncsi_dev_state_probe_gvi; 1478 + if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) && ndp->channel_probe_id == 0) 1479 + nd->state = ncsi_dev_state_probe_keep_phy; 1480 + } else if (nd->state == ncsi_dev_state_probe_gvi) { 1481 + nd->state = ncsi_dev_state_probe_gc; 1482 + } else if (nd->state == ncsi_dev_state_probe_gc) { 1483 + nd->state = ncsi_dev_state_probe_gls; 1484 + } else { 1485 + nd->state = ncsi_dev_state_probe_cis; 1486 + ndp->channel_probe_id++; 1462 1487 } 1463 1488 1464 - if (nd->state == ncsi_dev_state_probe_gvi) 1465 - nd->state = ncsi_dev_state_probe_gc; 1466 - else if (nd->state == ncsi_dev_state_probe_gc) 1467 - nd->state = ncsi_dev_state_probe_gls; 1468 - else 1489 + if (ndp->channel_probe_id == ndp->channel_count) { 1490 + ndp->channel_probe_id = 0; 1469 1491 nd->state = ncsi_dev_state_probe_dp; 1492 + } 1470 1493 break; 1471 1494 case ncsi_dev_state_probe_dp: 1472 1495 ndp->pending_req_num = 1; ··· 1777 1780 ndp->requests[i].ndp = ndp; 1778 1781 timer_setup(&ndp->requests[i].timer, ncsi_request_timeout, 0); 1779 1782 } 1783 + ndp->channel_count = NCSI_RESERVED_CHANNEL; 1780 1784 1781 1785 spin_lock_irqsave(&ncsi_dev_lock, flags); 1782 1786 list_add_tail_rcu(&ndp->node, &ncsi_dev_list); ··· 1811 1813 1812 1814 if (!(ndp->flags & NCSI_DEV_PROBED)) { 1813 1815 ndp->package_probe_id = 0; 1816 + ndp->channel_probe_id = 0; 1814 1817 nd->state = ncsi_dev_state_probe; 1815 1818 schedule_work(&ndp->work); 1816 1819 return 0;
+3 -1
net/ncsi/ncsi-rsp.c
··· 795 795 struct ncsi_rsp_gc_pkt *rsp; 796 796 struct ncsi_dev_priv *ndp = nr->ndp; 797 797 struct ncsi_channel *nc; 798 + struct ncsi_package *np; 798 799 size_t size; 799 800 800 801 /* Find the channel */ 801 802 rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp); 802 803 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, 803 - NULL, &nc); 804 + &np, &nc); 804 805 if (!nc) 805 806 return -ENODEV; 806 807 ··· 836 835 */ 837 836 nc->vlan_filter.bitmap = U64_MAX; 838 837 nc->vlan_filter.n_vids = rsp->vlan_cnt; 838 + np->ndp->channel_count = rsp->channel_cnt; 839 839 840 840 return 0; 841 841 }