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.

Merge branch 'octeontx2-pf-extend-link-modes-support'

Hariprasad Kelam says:

====================
Octeontx2-pf: extend link modes support

This series of patches adds multi advertise mode support along with
other improvements in link mode management code flow.

Patch1: Currently all SGMII modes 10/100/1000baseT are mapped with
single firmware mode. This patch updates these link modes
with corresponding firmware modes.

Patch2: Due to limitation in current kernel <-> firmware communication,
link modes are divided into multiple groups, and identified
with their group index.

Patch3: Adds support for multi advertise mode.
====================

Link: https://patch.msgid.link/20250625092107.9746-1-hkelam@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+113 -56
+37 -18
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
··· 1182 1182 static void set_mod_args(struct cgx_set_link_mode_args *args, 1183 1183 u32 speed, u8 duplex, u8 autoneg, u64 mode) 1184 1184 { 1185 - /* Fill default values incase of user did not pass 1186 - * valid parameters 1185 + int mode_baseidx; 1186 + u8 cgx_mode; 1187 + 1188 + if (args->multimode) { 1189 + args->mode |= mode; 1190 + return; 1191 + } 1192 + 1193 + /* Derive mode_base_idx and mode fields based 1194 + * on cgx_mode value 1187 1195 */ 1188 - if (args->duplex == DUPLEX_UNKNOWN) 1189 - args->duplex = duplex; 1190 - if (args->speed == SPEED_UNKNOWN) 1191 - args->speed = speed; 1192 - if (args->an == AUTONEG_UNKNOWN) 1193 - args->an = autoneg; 1196 + cgx_mode = find_first_bit((unsigned long *)&mode, 1197 + CGX_MODE_MAX); 1194 1198 args->mode = mode; 1195 - args->ports = 0; 1199 + mode_baseidx = cgx_mode - 41; 1200 + if (mode_baseidx > 0) { 1201 + args->mode_baseidx = 1; 1202 + args->mode = BIT_ULL(mode_baseidx); 1203 + } 1196 1204 } 1197 1205 1198 1206 static void otx2_map_ethtool_link_modes(u64 bitmask, ··· 1208 1200 { 1209 1201 switch (bitmask) { 1210 1202 case ETHTOOL_LINK_MODE_10baseT_Half_BIT: 1211 - set_mod_args(args, 10, 1, 1, BIT_ULL(CGX_MODE_SGMII)); 1203 + set_mod_args(args, 10, 1, 1, BIT_ULL(CGX_MODE_SGMII_10M_BIT)); 1212 1204 break; 1213 1205 case ETHTOOL_LINK_MODE_10baseT_Full_BIT: 1214 - set_mod_args(args, 10, 0, 1, BIT_ULL(CGX_MODE_SGMII)); 1206 + set_mod_args(args, 10, 0, 1, BIT_ULL(CGX_MODE_SGMII_10M_BIT)); 1215 1207 break; 1216 1208 case ETHTOOL_LINK_MODE_100baseT_Half_BIT: 1217 - set_mod_args(args, 100, 1, 1, BIT_ULL(CGX_MODE_SGMII)); 1209 + set_mod_args(args, 100, 1, 1, BIT_ULL(CGX_MODE_SGMII_100M_BIT)); 1218 1210 break; 1219 1211 case ETHTOOL_LINK_MODE_100baseT_Full_BIT: 1220 - set_mod_args(args, 100, 0, 1, BIT_ULL(CGX_MODE_SGMII)); 1212 + set_mod_args(args, 100, 0, 1, BIT_ULL(CGX_MODE_SGMII_100M_BIT)); 1221 1213 break; 1222 1214 case ETHTOOL_LINK_MODE_1000baseT_Half_BIT: 1223 1215 set_mod_args(args, 1000, 1, 1, BIT_ULL(CGX_MODE_SGMII)); ··· 1489 1481 } 1490 1482 1491 1483 int cgx_set_link_mode(void *cgxd, struct cgx_set_link_mode_args args, 1484 + struct cgx_lmac_fwdata_s *linkmodes, 1492 1485 int cgx_id, int lmac_id) 1493 1486 { 1494 1487 struct cgx *cgx = cgxd; 1495 1488 u64 req = 0, resp; 1489 + u8 bit; 1496 1490 1497 1491 if (!cgx) 1498 1492 return -ENODEV; 1499 1493 1500 - if (args.mode) 1501 - otx2_map_ethtool_link_modes(args.mode, &args); 1502 - if (!args.speed && args.duplex && !args.an) 1503 - return -EINVAL; 1494 + for_each_set_bit(bit, args.advertising, 1495 + __ETHTOOL_LINK_MODE_MASK_NBITS) 1496 + otx2_map_ethtool_link_modes(bit, &args); 1497 + 1498 + if (args.multimode) { 1499 + if (linkmodes->advertised_link_modes_own != CGX_CMD_OWN_NS) 1500 + return -EBUSY; 1501 + 1502 + linkmodes->advertised_link_modes = args.mode; 1503 + /* Update ownership */ 1504 + linkmodes->advertised_link_modes_own = CGX_CMD_OWN_FIRMWARE; 1505 + args.mode = GENMASK_ULL(41, 0); 1506 + } 1504 1507 1505 1508 req = FIELD_SET(CMDREG_ID, CGX_CMD_MODE_CHANGE, req); 1506 1509 req = FIELD_SET(CMDMODECHANGE_SPEED, 1507 1510 cgx_link_usertable_index_map(args.speed), req); 1508 1511 req = FIELD_SET(CMDMODECHANGE_DUPLEX, args.duplex, req); 1509 1512 req = FIELD_SET(CMDMODECHANGE_AN, args.an, req); 1510 - req = FIELD_SET(CMDMODECHANGE_PORT, args.ports, req); 1513 + req = FIELD_SET(CMDMODECHANGE_MODE_BASEIDX, args.mode_baseidx, req); 1511 1514 req = FIELD_SET(CMDMODECHANGE_FLAGS, args.mode, req); 1512 1515 1513 1516 return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
+1
drivers/net/ethernet/marvell/octeontx2/af/cgx.h
··· 171 171 int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp); 172 172 int cgx_get_phy_fec_stats(void *cgxd, int lmac_id); 173 173 int cgx_set_link_mode(void *cgxd, struct cgx_set_link_mode_args args, 174 + struct cgx_lmac_fwdata_s *linkmodes, 174 175 int cgx_id, int lmac_id); 175 176 u64 cgx_features_get(void *cgxd); 176 177 struct mac_ops *get_mac_ops(void *cgxd);
+31 -2
drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
··· 95 95 CGX_MODE_100G_C2M, 96 96 CGX_MODE_100G_CR4, 97 97 CGX_MODE_100G_KR4, 98 - CGX_MODE_MAX /* = 29 */ 98 + CGX_MODE_LAUI_2_C2C_BIT, 99 + CGX_MODE_LAUI_2_C2M_BIT, 100 + CGX_MODE_50GBASE_CR2_C_BIT, 101 + CGX_MODE_50GBASE_KR2_C_BIT, /* = 30 */ 102 + CGX_MODE_100GAUI_2_C2C_BIT, 103 + CGX_MODE_100GAUI_2_C2M_BIT, 104 + CGX_MODE_100GBASE_CR2_BIT, 105 + CGX_MODE_100GBASE_KR2_BIT, 106 + CGX_MODE_SFI_1G_BIT, 107 + CGX_MODE_25GBASE_CR_C_BIT, 108 + CGX_MODE_25GBASE_KR_C_BIT, 109 + CGX_MODE_SGMII_10M_BIT, 110 + CGX_MODE_SGMII_100M_BIT, /* = 39 */ 111 + CGX_MODE_2500_BASEX_BIT = 42, /* Mode group 1 */ 112 + CGX_MODE_5000_BASEX_BIT, 113 + CGX_MODE_O_USGMII_BIT, 114 + CGX_MODE_Q_USGMII_BIT, 115 + CGX_MODE_2_5G_USXGMII_BIT, 116 + CGX_MODE_5G_USXGMII_BIT, 117 + CGX_MODE_10G_SXGMII_BIT, 118 + CGX_MODE_10G_DXGMII_BIT, 119 + CGX_MODE_10G_QXGMII_BIT, 120 + CGX_MODE_TP_BIT, 121 + CGX_MODE_FIBER_BIT, 122 + CGX_MODE_MAX /* = 53 */ 99 123 }; 100 124 /* REQUEST ID types. Input to firmware */ 101 125 enum cgx_cmd_id { ··· 282 258 #define CMDMODECHANGE_SPEED GENMASK_ULL(11, 8) 283 259 #define CMDMODECHANGE_DUPLEX GENMASK_ULL(12, 12) 284 260 #define CMDMODECHANGE_AN GENMASK_ULL(13, 13) 285 - #define CMDMODECHANGE_PORT GENMASK_ULL(21, 14) 261 + /* this field categorize the mode ID(FLAGS) range to accommodate 262 + * more modes. 263 + * To specify mode ID range of 0 - 41, this field will be 0. 264 + * To specify mode ID range of 42 - 83, this field will be 1. 265 + */ 266 + #define CMDMODECHANGE_MODE_BASEIDX GENMASK_ULL(21, 20) 286 267 #define CMDMODECHANGE_FLAGS GENMASK_ULL(63, 22) 287 268 288 269 /* LINK_BRING_UP command timeout */
+6 -3
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
··· 10 10 11 11 #include <linux/etherdevice.h> 12 12 #include <linux/sizes.h> 13 + #include <linux/ethtool.h> 13 14 14 15 #include "rvu_struct.h" 15 16 #include "common.h" ··· 659 658 u64 supported_link_modes; 660 659 /* only applicable if AN is supported */ 661 660 u64 advertised_fec; 662 - u64 advertised_link_modes; 661 + u64 advertised_link_modes_own:1; /* CGX_CMD_OWN */ 662 + u64 advertised_link_modes:63; 663 663 /* Only applicable if SFP/QSFP slot is present */ 664 664 struct sfp_eeprom_s sfp_eeprom; 665 665 struct phy_s phy; ··· 677 675 u32 speed; 678 676 u8 duplex; 679 677 u8 an; 680 - u8 ports; 678 + u8 mode_baseidx; 679 + u8 multimode; 681 680 u64 mode; 681 + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); 682 682 }; 683 683 684 684 struct cgx_set_link_mode_req { 685 - #define AUTONEG_UNKNOWN 0xff 686 685 struct mbox_msghdr hdr; 687 686 struct cgx_set_link_mode_args args; 688 687 };
+8 -1
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
··· 1223 1223 struct cgx_set_link_mode_rsp *rsp) 1224 1224 { 1225 1225 int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc); 1226 + struct cgx_lmac_fwdata_s *linkmodes; 1226 1227 u8 cgx_idx, lmac; 1227 1228 void *cgxd; 1228 1229 ··· 1232 1231 1233 1232 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac); 1234 1233 cgxd = rvu_cgx_pdata(cgx_idx, rvu); 1235 - rsp->status = cgx_set_link_mode(cgxd, req->args, cgx_idx, lmac); 1234 + if (rvu->hw->lmac_per_cgx == CGX_LMACS_USX) 1235 + linkmodes = &rvu->fwdata->cgx_fw_data_usx[cgx_idx][lmac]; 1236 + else 1237 + linkmodes = &rvu->fwdata->cgx_fw_data[cgx_idx][lmac]; 1238 + 1239 + rsp->status = cgx_set_link_mode(cgxd, req->args, linkmodes, 1240 + cgx_idx, lmac); 1236 1241 return 0; 1237 1242 } 1238 1243
+30 -32
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
··· 15 15 16 16 #include "otx2_common.h" 17 17 #include "otx2_ptp.h" 18 + #include <cgx_fw_if.h> 18 19 19 20 #define DRV_NAME "rvu-nicpf" 20 21 #define DRV_VF_NAME "rvu-nicvf" ··· 1127 1126 *link_ksettings) 1128 1127 { 1129 1128 __ETHTOOL_DECLARE_LINK_MODE_MASK(otx2_link_modes) = { 0, }; 1130 - const int otx2_sgmii_features[6] = { 1131 - ETHTOOL_LINK_MODE_10baseT_Half_BIT, 1132 - ETHTOOL_LINK_MODE_10baseT_Full_BIT, 1133 - ETHTOOL_LINK_MODE_100baseT_Half_BIT, 1134 - ETHTOOL_LINK_MODE_100baseT_Full_BIT, 1135 - ETHTOOL_LINK_MODE_1000baseT_Half_BIT, 1136 - ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 1137 - }; 1138 1129 /* CGX link modes to Ethtool link mode mapping */ 1139 - const int cgx_link_mode[27] = { 1140 - 0, /* SGMII Mode */ 1130 + const int cgx_link_mode[CGX_MODE_MAX] = { 1131 + 0, /* SGMII 1000baseT */ 1141 1132 ETHTOOL_LINK_MODE_1000baseX_Full_BIT, 1142 1133 ETHTOOL_LINK_MODE_10000baseT_Full_BIT, 1143 1134 ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, ··· 1159 1166 }; 1160 1167 u8 bit; 1161 1168 1162 - for_each_set_bit(bit, (unsigned long *)&link_mode_bmap, 27) { 1163 - /* SGMII mode is set */ 1164 - if (bit == 0) 1165 - linkmode_set_bit_array(otx2_sgmii_features, 1166 - ARRAY_SIZE(otx2_sgmii_features), 1167 - otx2_link_modes); 1168 - else 1169 + for_each_set_bit(bit, (unsigned long *)&link_mode_bmap, ARRAY_SIZE(cgx_link_mode)) { 1170 + if (bit == CGX_MODE_SGMII_10M_BIT) { 1171 + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, otx2_link_modes); 1172 + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, otx2_link_modes); 1173 + } else if (bit == CGX_MODE_SGMII_100M_BIT) { 1174 + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, otx2_link_modes); 1175 + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, otx2_link_modes); 1176 + } else if (bit == CGX_MODE_SGMII) { 1177 + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, otx2_link_modes); 1178 + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, otx2_link_modes); 1179 + } else { 1169 1180 linkmode_set_bit(cgx_link_mode[bit], otx2_link_modes); 1181 + } 1170 1182 } 1171 1183 1172 1184 if (req_mode == OTX2_MODE_ADVERTISED) ··· 1212 1214 return 0; 1213 1215 } 1214 1216 1215 - static void otx2_get_advertised_mode(const struct ethtool_link_ksettings *cmd, 1216 - u64 *mode) 1217 - { 1218 - u32 bit_pos; 1219 - 1220 - /* Firmware does not support requesting multiple advertised modes 1221 - * return first set bit 1222 - */ 1223 - bit_pos = find_first_bit(cmd->link_modes.advertising, 1224 - __ETHTOOL_LINK_MODE_MASK_NBITS); 1225 - if (bit_pos != __ETHTOOL_LINK_MODE_MASK_NBITS) 1226 - *mode = bit_pos; 1227 - } 1228 - 1229 1217 static int otx2_set_link_ksettings(struct net_device *netdev, 1230 1218 const struct ethtool_link_ksettings *cmd) 1231 1219 { 1220 + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 1232 1221 struct otx2_nic *pf = netdev_priv(netdev); 1233 1222 struct ethtool_link_ksettings cur_ks; 1234 1223 struct cgx_set_link_mode_req *req; ··· 1252 1267 */ 1253 1268 req->args.duplex = cmd->base.duplex ^ 0x1; 1254 1269 req->args.an = cmd->base.autoneg; 1255 - otx2_get_advertised_mode(cmd, &req->args.mode); 1270 + /* Mask unsupported modes and send message to AF */ 1271 + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, mask); 1272 + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, mask); 1273 + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, mask); 1274 + 1275 + linkmode_copy(req->args.advertising, 1276 + cmd->link_modes.advertising); 1277 + linkmode_andnot(req->args.advertising, 1278 + req->args.advertising, mask); 1279 + 1280 + /* inform AF that we need parse this differently */ 1281 + if (bitmap_weight(req->args.advertising, 1282 + __ETHTOOL_LINK_MODE_MASK_NBITS) >= 2) 1283 + req->args.multimode = true; 1256 1284 1257 1285 err = otx2_sync_mbox_msg(&pf->mbox); 1258 1286 end: