Skip to content

Commit 292fcbb

Browse files
SunilKumarKoriJerin Jacob
authored andcommitted
net/cnxk: support link mode configuration
As a port can be configured to operate on specific mode and speed via struct rte_eth_conf::link_speeds in rte_eth_dev_configure() API. Implement mentioned configuration passed by user. Signed-off-by: Sunil Kumar Kori <[email protected]> Signed-off-by: Nithin Dabilpuram <[email protected]>
1 parent 8cdd699 commit 292fcbb

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed

doc/guides/rel_notes/release_25_11.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ New Features
125125
Added support to set/get link configuration as mentioned below:
126126

127127
* Get speed capability from firmware.
128+
* Configure link mode.
128129

129130
* **Added Nebulamatrix nbl ethernet driver.**
130131

drivers/net/cnxk/cnxk_ethdev.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
#include <cnxk_ethdev.h>
55

6+
#include <rte_bitops.h>
67
#include <eal_export.h>
78
#include <rte_eventdev.h>
89
#include <rte_pmd_cnxk.h>
@@ -1612,6 +1613,11 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
16121613
eth_dev->data->port_id, ea_fmt, nb_rxq, nb_txq,
16131614
dev->rx_offloads, dev->tx_offloads);
16141615

1616+
/* Configure link parameters */
1617+
rc = cnxk_nix_link_info_configure(eth_dev);
1618+
if (rc)
1619+
plt_warn("Unable to configure requested link attributes, rc=%d continue...", rc);
1620+
16151621
/* All good */
16161622
dev->configured = 1;
16171623
dev->nb_rxq = data->nb_rx_queues;

drivers/net/cnxk/cnxk_ethdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ void cnxk_eth_dev_link_status_cb(struct roc_nix *nix,
678678
void cnxk_eth_dev_link_status_get_cb(struct roc_nix *nix,
679679
struct roc_nix_link_info *link);
680680
void cnxk_eth_dev_q_err_cb(struct roc_nix *nix, void *data);
681+
int cnxk_nix_link_info_configure(struct rte_eth_dev *eth_dev);
681682
int cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete);
682683
int cnxk_nix_queue_stats_mapping(struct rte_eth_dev *dev, uint16_t queue_id,
683684
uint8_t stat_idx, uint8_t is_rx);

drivers/net/cnxk/cnxk_link.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,74 @@
44

55
#include "cnxk_ethdev.h"
66

7+
const enum roc_nix_link_mode mac_to_ethtool_mode[CGX_LMAC_TYPE_MAX][2] = {
8+
[CGX_LMAC_TYPE_SGMII][ROC_NIX_LINK_DUPLEX_HALF] = ROC_NIX_LINK_MODE_1000BASET_HD,
9+
[CGX_LMAC_TYPE_SGMII][ROC_NIX_LINK_DUPLEX_FULL] = ROC_NIX_LINK_MODE_1000BASET_FD,
10+
[CGX_LMAC_TYPE_10G_R][ROC_NIX_LINK_DUPLEX_FULL] = ROC_NIX_LINK_MODE_10000BASESR_FD,
11+
[CGX_LMAC_TYPE_QSGMII][ROC_NIX_LINK_DUPLEX_HALF] = ROC_NIX_LINK_MODE_1000BASET_HD,
12+
[CGX_LMAC_TYPE_QSGMII][ROC_NIX_LINK_DUPLEX_FULL] = ROC_NIX_LINK_MODE_10000BASET_FD,
13+
};
14+
15+
const enum roc_nix_link_mode rte_to_ethtool_mode[ROC_NIX_LINK_SPEED_MAX] = {
16+
0,
17+
ROC_NIX_LINK_MODE_10BASET_HD,
18+
ROC_NIX_LINK_MODE_10BASET_FD,
19+
ROC_NIX_LINK_MODE_100BASET_HD,
20+
ROC_NIX_LINK_MODE_100BASET_FD,
21+
ROC_NIX_LINK_MODE_1000BASET_FD,
22+
ROC_NIX_LINK_MODE_2500BASEX_FD,
23+
0,
24+
ROC_NIX_LINK_MODE_10000BASESR_FD,
25+
0,
26+
ROC_NIX_LINK_MODE_25000BASESR_FD,
27+
ROC_NIX_LINK_MODE_40000BASELR4_FD,
28+
ROC_NIX_LINK_MODE_50000BASELR_ER_FR_FD,
29+
0,
30+
ROC_NIX_LINK_MODE_100000BASELR4_ER4_FD,
31+
0,
32+
0,
33+
};
34+
35+
static uint64_t
36+
nix_link_advertising_get(struct cnxk_eth_dev *dev, struct roc_nix_link_info *link_info)
37+
{
38+
struct roc_nix_mac_fwdata fwdata;
39+
struct roc_nix_link_info linfo;
40+
uint64_t advertise = 0;
41+
int bit, rc;
42+
43+
memset(&fwdata, 0, sizeof(fwdata));
44+
rc = roc_nix_mac_fwdata_get(&dev->nix, &fwdata);
45+
if (rc) {
46+
plt_err("Failed to get MAC firmware data");
47+
goto exit;
48+
}
49+
50+
memset(&linfo, 0, sizeof(linfo));
51+
rc = roc_nix_mac_link_info_get(&dev->nix, &linfo);
52+
if (rc) {
53+
plt_err("Failed to get MAC link info");
54+
goto exit;
55+
}
56+
57+
if (link_info->autoneg) {
58+
if (!fwdata.supported_an) {
59+
plt_err("Autoneg is not supported");
60+
goto exit;
61+
} else {
62+
for (bit = 0; bit < ROC_NIX_LINK_SPEED_MAX; bit++) {
63+
if (link_info->speed_bitmask & BIT_ULL(bit))
64+
advertise |= rte_to_ethtool_mode[bit];
65+
}
66+
goto exit;
67+
}
68+
}
69+
70+
advertise |= mac_to_ethtool_mode[linfo.lmac_type_id][link_info->full_duplex];
71+
exit:
72+
return advertise;
73+
}
74+
775
void
876
cnxk_nix_toggle_flag_link_cfg(struct cnxk_eth_dev *dev, bool set)
977
{
@@ -146,3 +214,67 @@ cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete)
146214

147215
return rte_eth_linkstatus_set(eth_dev, &link);
148216
}
217+
218+
int
219+
cnxk_nix_link_info_configure(struct rte_eth_dev *eth_dev)
220+
{
221+
uint32_t speed_map[] = {
222+
RTE_ETH_SPEED_NUM_NONE, RTE_ETH_SPEED_NUM_10M, RTE_ETH_SPEED_NUM_10M,
223+
RTE_ETH_SPEED_NUM_100M, RTE_ETH_SPEED_NUM_100M, RTE_ETH_SPEED_NUM_1G,
224+
RTE_ETH_SPEED_NUM_2_5G, RTE_ETH_SPEED_NUM_5G, RTE_ETH_SPEED_NUM_10G,
225+
RTE_ETH_SPEED_NUM_20G, RTE_ETH_SPEED_NUM_25G, RTE_ETH_SPEED_NUM_40G,
226+
RTE_ETH_SPEED_NUM_50G, RTE_ETH_SPEED_NUM_56G, RTE_ETH_SPEED_NUM_100G,
227+
RTE_ETH_SPEED_NUM_200G, RTE_ETH_SPEED_NUM_400G
228+
};
229+
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
230+
struct rte_eth_dev_data *data = eth_dev->data;
231+
struct rte_eth_conf *conf = &data->dev_conf;
232+
uint32_t link_speeds = conf->link_speeds;
233+
struct roc_nix_link_info link_info = {0};
234+
struct roc_nix *nix = &dev->nix;
235+
uint32_t speed = link_speeds;
236+
bool fixed;
237+
238+
plt_info("User passed link configuration: %x", link_speeds);
239+
240+
if (!roc_nix_is_pf(nix) || link_speeds == RTE_ETH_LINK_SPEED_AUTONEG)
241+
return 0;
242+
243+
fixed = link_speeds & RTE_ETH_LINK_SPEED_FIXED ? true : false;
244+
if (fixed) {
245+
if (rte_popcount32(link_speeds) == 1) {
246+
plt_err("Desired speed is not specified in FIXED mode");
247+
return -EINVAL;
248+
}
249+
250+
if (rte_popcount32(link_speeds) > 2) {
251+
plt_err("Multiple speeds can't be configured in FIXED mode");
252+
return -EINVAL;
253+
}
254+
255+
link_info.autoneg = 0;
256+
} else {
257+
link_info.autoneg = 1;
258+
}
259+
260+
speed >>= 1;
261+
link_info.speed = speed_map[rte_bsf32(speed) + 1];
262+
link_info.speed_bitmask = link_speeds & ~RTE_ETH_LINK_SPEED_FIXED;
263+
link_info.full_duplex = ((link_speeds & RTE_ETH_LINK_SPEED_10M_HD) ||
264+
(link_speeds & RTE_ETH_LINK_SPEED_100M_HD)) ?
265+
ROC_NIX_LINK_DUPLEX_HALF :
266+
ROC_NIX_LINK_DUPLEX_FULL;
267+
link_info.advertising = nix_link_advertising_get(dev, &link_info);
268+
if (link_info.advertising == 0) {
269+
plt_err("advertising bitmap is not set");
270+
return -EINVAL;
271+
}
272+
273+
plt_info("Following link settings are sent to firmware:");
274+
plt_info("Advertised modes: %" PRIX64, link_info.advertising);
275+
plt_info("speed: %u", link_info.speed);
276+
plt_info("duplex: %s", link_info.full_duplex == ROC_NIX_LINK_DUPLEX_HALF ?
277+
"half-duplex" : "full-duplex");
278+
plt_info("autoneg: %s", link_info.autoneg ? "enabled" : "disabled");
279+
return roc_nix_mac_link_info_set(nix, &link_info);
280+
}

0 commit comments

Comments
 (0)