1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2026 Broadcom. 3 4 #include <linux/linkmode.h> 5 6 #include "bnge.h" 7 #include "bnge_link.h" 8 #include "bnge_hwrm_lib.h" 9 10 enum bnge_media_type { 11 BNGE_MEDIA_UNKNOWN = 0, 12 BNGE_MEDIA_CR, 13 BNGE_MEDIA_SR, 14 BNGE_MEDIA_LR_ER_FR, 15 BNGE_MEDIA_KR, 16 __BNGE_MEDIA_END, 17 }; 18 19 static const enum bnge_media_type bnge_phy_types[] = { 20 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR4] = BNGE_MEDIA_CR, 21 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR4] = BNGE_MEDIA_SR, 22 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR4] = BNGE_MEDIA_LR_ER_FR, 23 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER4] = BNGE_MEDIA_LR_ER_FR, 24 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR10] = BNGE_MEDIA_SR, 25 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR4] = BNGE_MEDIA_CR, 26 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR4] = BNGE_MEDIA_SR, 27 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR4] = BNGE_MEDIA_LR_ER_FR, 28 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER4] = BNGE_MEDIA_LR_ER_FR, 29 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASECR] = BNGE_MEDIA_CR, 30 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASESR] = BNGE_MEDIA_SR, 31 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASELR] = BNGE_MEDIA_LR_ER_FR, 32 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASEER] = BNGE_MEDIA_LR_ER_FR, 33 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR2] = BNGE_MEDIA_CR, 34 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR2] = BNGE_MEDIA_SR, 35 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR2] = BNGE_MEDIA_LR_ER_FR, 36 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER2] = BNGE_MEDIA_LR_ER_FR, 37 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR] = BNGE_MEDIA_CR, 38 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR] = BNGE_MEDIA_SR, 39 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR] = BNGE_MEDIA_LR_ER_FR, 40 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER] = BNGE_MEDIA_LR_ER_FR, 41 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR2] = BNGE_MEDIA_CR, 42 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR2] = BNGE_MEDIA_SR, 43 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR2] = BNGE_MEDIA_LR_ER_FR, 44 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER2] = BNGE_MEDIA_LR_ER_FR, 45 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR8] = BNGE_MEDIA_CR, 46 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR8] = BNGE_MEDIA_SR, 47 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR8] = BNGE_MEDIA_LR_ER_FR, 48 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER8] = BNGE_MEDIA_LR_ER_FR, 49 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR4] = BNGE_MEDIA_CR, 50 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR4] = BNGE_MEDIA_SR, 51 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR4] = BNGE_MEDIA_LR_ER_FR, 52 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER4] = BNGE_MEDIA_LR_ER_FR, 53 }; 54 55 static u32 bnge_fw_to_ethtool_speed(u16 fw_link_speed) 56 { 57 switch (fw_link_speed) { 58 case BNGE_LINK_SPEED_50GB: 59 case BNGE_LINK_SPEED_50GB_PAM4: 60 return SPEED_50000; 61 case BNGE_LINK_SPEED_100GB: 62 case BNGE_LINK_SPEED_100GB_PAM4: 63 case BNGE_LINK_SPEED_100GB_PAM4_112: 64 return SPEED_100000; 65 case BNGE_LINK_SPEED_200GB: 66 case BNGE_LINK_SPEED_200GB_PAM4: 67 case BNGE_LINK_SPEED_200GB_PAM4_112: 68 return SPEED_200000; 69 case BNGE_LINK_SPEED_400GB: 70 case BNGE_LINK_SPEED_400GB_PAM4: 71 case BNGE_LINK_SPEED_400GB_PAM4_112: 72 return SPEED_400000; 73 case BNGE_LINK_SPEED_800GB: 74 case BNGE_LINK_SPEED_800GB_PAM4_112: 75 return SPEED_800000; 76 default: 77 return SPEED_UNKNOWN; 78 } 79 } 80 81 static void bnge_set_auto_speed(struct bnge_net *bn) 82 { 83 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 84 struct bnge_link_info *link_info; 85 86 link_info = &bn->bd->link_info; 87 elink_info->advertising = link_info->auto_link_speeds2; 88 } 89 90 static void bnge_set_force_speed(struct bnge_net *bn) 91 { 92 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 93 struct bnge_link_info *link_info; 94 95 link_info = &bn->bd->link_info; 96 elink_info->req_link_speed = link_info->force_link_speed2; 97 switch (elink_info->req_link_speed) { 98 case BNGE_LINK_SPEED_50GB_PAM4: 99 case BNGE_LINK_SPEED_100GB_PAM4: 100 case BNGE_LINK_SPEED_200GB_PAM4: 101 case BNGE_LINK_SPEED_400GB_PAM4: 102 elink_info->req_signal_mode = BNGE_SIG_MODE_PAM4; 103 break; 104 case BNGE_LINK_SPEED_100GB_PAM4_112: 105 case BNGE_LINK_SPEED_200GB_PAM4_112: 106 case BNGE_LINK_SPEED_400GB_PAM4_112: 107 case BNGE_LINK_SPEED_800GB_PAM4_112: 108 elink_info->req_signal_mode = BNGE_SIG_MODE_PAM4_112; 109 break; 110 default: 111 elink_info->req_signal_mode = BNGE_SIG_MODE_NRZ; 112 break; 113 } 114 } 115 116 void bnge_init_ethtool_link_settings(struct bnge_net *bn) 117 { 118 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 119 struct bnge_link_info *link_info; 120 struct bnge_dev *bd = bn->bd; 121 122 link_info = &bd->link_info; 123 124 if (BNGE_AUTO_MODE(link_info->auto_mode)) { 125 elink_info->autoneg = BNGE_AUTONEG_SPEED; 126 if (link_info->auto_pause_setting & 127 PORT_PHY_QCFG_RESP_AUTO_PAUSE_AUTONEG_PAUSE) 128 elink_info->autoneg |= BNGE_AUTONEG_FLOW_CTRL; 129 bnge_set_auto_speed(bn); 130 } else { 131 elink_info->autoneg = 0; 132 elink_info->advertising = 0; 133 bnge_set_force_speed(bn); 134 elink_info->req_duplex = link_info->duplex_setting; 135 } 136 if (elink_info->autoneg & BNGE_AUTONEG_FLOW_CTRL) 137 elink_info->req_flow_ctrl = 138 link_info->auto_pause_setting & BNGE_LINK_PAUSE_BOTH; 139 else 140 elink_info->req_flow_ctrl = link_info->force_pause_setting; 141 } 142 143 int bnge_probe_phy(struct bnge_net *bn, bool fw_dflt) 144 { 145 struct bnge_dev *bd = bn->bd; 146 int rc; 147 148 bd->phy_flags = 0; 149 rc = bnge_hwrm_phy_qcaps(bd); 150 if (rc) { 151 netdev_err(bn->netdev, 152 "Probe PHY can't get PHY qcaps (rc: %d)\n", rc); 153 return rc; 154 } 155 if (bd->phy_flags & BNGE_PHY_FL_NO_FCS) 156 bn->netdev->priv_flags |= IFF_SUPP_NOFCS; 157 else 158 bn->netdev->priv_flags &= ~IFF_SUPP_NOFCS; 159 if (!fw_dflt) 160 return 0; 161 162 rc = bnge_update_link(bn, false); 163 if (rc) { 164 netdev_err(bn->netdev, "Probe PHY can't update link (rc: %d)\n", 165 rc); 166 return rc; 167 } 168 bnge_init_ethtool_link_settings(bn); 169 170 return 0; 171 } 172 173 void bnge_hwrm_set_link_common(struct bnge_net *bn, 174 struct hwrm_port_phy_cfg_input *req) 175 { 176 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 177 178 if (elink_info->autoneg & BNGE_AUTONEG_SPEED) { 179 req->auto_mode |= PORT_PHY_CFG_REQ_AUTO_MODE_SPEED_MASK; 180 req->enables |= cpu_to_le32(BNGE_PHY_AUTO_SPEEDS2_MASK); 181 req->auto_link_speeds2_mask = 182 cpu_to_le16(elink_info->advertising); 183 req->enables |= cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_MODE); 184 req->flags |= cpu_to_le32(BNGE_PHY_FLAGS_RESTART_AUTO); 185 } else { 186 req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE); 187 req->force_link_speeds2 = 188 cpu_to_le16(elink_info->req_link_speed); 189 req->enables |= 190 cpu_to_le32(BNGE_PHY_FLAGS_ENA_FORCE_SPEEDS2); 191 netif_info(bn, link, bn->netdev, 192 "Forcing FW speed2: %d\n", 193 (u32)elink_info->req_link_speed); 194 } 195 196 /* tell FW that the setting takes effect immediately */ 197 req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_RESET_PHY); 198 } 199 200 static bool bnge_auto_speed_updated(struct bnge_net *bn) 201 { 202 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 203 struct bnge_link_info *link_info = &bn->bd->link_info; 204 205 return elink_info->advertising != link_info->auto_link_speeds2; 206 } 207 208 void bnge_hwrm_set_pause_common(struct bnge_net *bn, 209 struct hwrm_port_phy_cfg_input *req) 210 { 211 if (bn->eth_link_info.autoneg & BNGE_AUTONEG_FLOW_CTRL) { 212 req->auto_pause = PORT_PHY_CFG_REQ_AUTO_PAUSE_AUTONEG_PAUSE; 213 if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_RX) 214 req->auto_pause |= PORT_PHY_CFG_REQ_AUTO_PAUSE_RX; 215 if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_TX) 216 req->auto_pause |= PORT_PHY_CFG_REQ_AUTO_PAUSE_TX; 217 req->enables |= 218 cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_PAUSE); 219 } else { 220 if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_RX) 221 req->force_pause |= PORT_PHY_CFG_REQ_FORCE_PAUSE_RX; 222 if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_TX) 223 req->force_pause |= PORT_PHY_CFG_REQ_FORCE_PAUSE_TX; 224 req->enables |= 225 cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_FORCE_PAUSE); 226 req->auto_pause = req->force_pause; 227 req->enables |= 228 cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_PAUSE); 229 } 230 } 231 232 static bool bnge_force_speed_updated(struct bnge_net *bn) 233 { 234 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 235 struct bnge_link_info *link_info = &bn->bd->link_info; 236 237 return elink_info->req_link_speed != link_info->force_link_speed2; 238 } 239 240 int bnge_update_phy_setting(struct bnge_net *bn) 241 { 242 struct bnge_ethtool_link_info *elink_info; 243 struct bnge_link_info *link_info; 244 struct bnge_dev *bd = bn->bd; 245 bool update_pause = false; 246 bool update_link = false; 247 bool hw_pause_autoneg; 248 bool pause_autoneg; 249 int rc; 250 251 link_info = &bd->link_info; 252 elink_info = &bn->eth_link_info; 253 rc = bnge_update_link(bn, true); 254 if (rc) { 255 netdev_err(bn->netdev, "failed to update link (rc: %d)\n", 256 rc); 257 return rc; 258 } 259 260 pause_autoneg = !!(elink_info->autoneg & BNGE_AUTONEG_FLOW_CTRL); 261 hw_pause_autoneg = !!(link_info->auto_pause_setting & 262 PORT_PHY_QCFG_RESP_AUTO_PAUSE_AUTONEG_PAUSE); 263 264 /* Check if pause autonegotiation state has changed */ 265 if (pause_autoneg != hw_pause_autoneg) { 266 update_pause = true; 267 } else if (pause_autoneg) { 268 /* If pause autoneg is enabled, check if the 269 * requested RX/TX bits changed 270 */ 271 if ((link_info->auto_pause_setting & BNGE_LINK_PAUSE_BOTH) != 272 elink_info->req_flow_ctrl) 273 update_pause = true; 274 } else { 275 /* If pause autoneg is disabled, check if the 276 * forced RX/TX bits changed 277 */ 278 if (link_info->force_pause_setting != elink_info->req_flow_ctrl) 279 update_pause = true; 280 } 281 282 /* Force update if link change is requested */ 283 if (elink_info->force_link_chng) 284 update_pause = true; 285 286 /* Check if link speed or duplex settings have changed */ 287 if (!(elink_info->autoneg & BNGE_AUTONEG_SPEED)) { 288 if (BNGE_AUTO_MODE(link_info->auto_mode) || 289 bnge_force_speed_updated(bn) || 290 elink_info->req_duplex != link_info->duplex_setting) 291 update_link = true; 292 } else { 293 if (link_info->auto_mode == BNGE_LINK_AUTO_NONE || 294 bnge_auto_speed_updated(bn)) 295 update_link = true; 296 } 297 298 /* The last close may have shut down the link, so need to call 299 * PHY_CFG to bring it back up. 300 */ 301 if (!BNGE_LINK_IS_UP(bd)) 302 update_link = true; 303 304 if (update_link) 305 rc = bnge_hwrm_set_link_setting(bn, update_pause); 306 else if (update_pause) 307 rc = bnge_hwrm_set_pause(bn); 308 309 if (rc) { 310 netdev_err(bn->netdev, 311 "failed to update PHY setting (rc: %d)\n", rc); 312 return rc; 313 } 314 315 return 0; 316 } 317 318 void bnge_get_port_module_status(struct bnge_net *bn) 319 { 320 struct hwrm_port_phy_qcfg_output *resp; 321 struct bnge_link_info *link_info; 322 struct bnge_dev *bd = bn->bd; 323 u8 module_status; 324 325 link_info = &bd->link_info; 326 resp = &link_info->phy_qcfg_resp; 327 328 if (bnge_update_link(bn, true)) 329 return; 330 331 module_status = link_info->module_status; 332 switch (module_status) { 333 case PORT_PHY_QCFG_RESP_MODULE_STATUS_DISABLETX: 334 case PORT_PHY_QCFG_RESP_MODULE_STATUS_PWRDOWN: 335 case PORT_PHY_QCFG_RESP_MODULE_STATUS_WARNINGMSG: 336 netdev_warn(bn->netdev, 337 "Unqualified SFP+ module detected on port %d\n", 338 bd->pf.port_id); 339 netdev_warn(bn->netdev, "Module part number %.*s\n", 340 (int)sizeof(resp->phy_vendor_partnumber), 341 resp->phy_vendor_partnumber); 342 if (module_status == PORT_PHY_QCFG_RESP_MODULE_STATUS_DISABLETX) 343 netdev_warn(bn->netdev, "TX is disabled\n"); 344 if (module_status == PORT_PHY_QCFG_RESP_MODULE_STATUS_PWRDOWN) 345 netdev_warn(bn->netdev, "SFP+ module is shut down\n"); 346 break; 347 } 348 } 349 350 static void bnge_set_default_adv_speeds(struct bnge_net *bn) 351 { 352 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 353 struct bnge_link_info *link_info = &bn->bd->link_info; 354 355 elink_info->advertising = link_info->support_auto_speeds2; 356 } 357 358 static bool bnge_support_dropped(u16 advertising, u16 supported) 359 { 360 return (advertising & ~supported) != 0; 361 } 362 363 bool bnge_support_speed_dropped(struct bnge_net *bn) 364 { 365 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 366 struct bnge_link_info *link_info = &bn->bd->link_info; 367 368 /* Check if any advertised speeds are no longer supported. The caller 369 * holds the netdev instance lock, so we can modify link_info settings. 370 */ 371 if (bnge_support_dropped(elink_info->advertising, 372 link_info->support_auto_speeds2)) { 373 elink_info->advertising = link_info->support_auto_speeds2; 374 return true; 375 } 376 return false; 377 } 378 379 static char *bnge_report_fec(struct bnge_link_info *link_info) 380 { 381 u8 active_fec = link_info->active_fec_sig_mode & 382 PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK; 383 384 switch (active_fec) { 385 default: 386 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE: 387 return "None"; 388 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE: 389 return "Clause 74 BaseR"; 390 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE: 391 return "Clause 91 RS(528,514)"; 392 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE: 393 return "Clause 91 RS544_1XN"; 394 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE: 395 return "Clause 91 RS(544,514)"; 396 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE: 397 return "Clause 91 RS272_1XN"; 398 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE: 399 return "Clause 91 RS(272,257)"; 400 } 401 } 402 403 void bnge_report_link(struct bnge_dev *bd) 404 { 405 if (BNGE_LINK_IS_UP(bd)) { 406 const char *signal = ""; 407 const char *flow_ctrl; 408 const char *duplex; 409 u32 speed; 410 u16 fec; 411 412 netif_carrier_on(bd->netdev); 413 speed = bnge_fw_to_ethtool_speed(bd->link_info.link_speed); 414 if (speed == SPEED_UNKNOWN) { 415 netdev_info(bd->netdev, 416 "NIC Link is Up, speed unknown\n"); 417 return; 418 } 419 if (bd->link_info.duplex == BNGE_LINK_DUPLEX_FULL) 420 duplex = "full"; 421 else 422 duplex = "half"; 423 if (bd->link_info.pause == BNGE_LINK_PAUSE_BOTH) 424 flow_ctrl = "ON - receive & transmit"; 425 else if (bd->link_info.pause == BNGE_LINK_PAUSE_TX) 426 flow_ctrl = "ON - transmit"; 427 else if (bd->link_info.pause == BNGE_LINK_PAUSE_RX) 428 flow_ctrl = "ON - receive"; 429 else 430 flow_ctrl = "none"; 431 if (bd->link_info.phy_qcfg_resp.option_flags & 432 PORT_PHY_QCFG_RESP_OPTION_FLAGS_SIGNAL_MODE_KNOWN) { 433 u8 sig_mode = bd->link_info.active_fec_sig_mode & 434 PORT_PHY_QCFG_RESP_SIGNAL_MODE_MASK; 435 switch (sig_mode) { 436 case PORT_PHY_QCFG_RESP_SIGNAL_MODE_NRZ: 437 signal = "(NRZ) "; 438 break; 439 case PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4: 440 signal = "(PAM4 56Gbps) "; 441 break; 442 case PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4_112: 443 signal = "(PAM4 112Gbps) "; 444 break; 445 default: 446 break; 447 } 448 } 449 netdev_info(bd->netdev, "NIC Link is Up, %u Mbps %s%s duplex, Flow control: %s\n", 450 speed, signal, duplex, flow_ctrl); 451 fec = bd->link_info.fec_cfg; 452 if (!(fec & PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED)) 453 netdev_info(bd->netdev, "FEC autoneg %s encoding: %s\n", 454 (fec & BNGE_FEC_AUTONEG) ? "on" : "off", 455 bnge_report_fec(&bd->link_info)); 456 } else { 457 netif_carrier_off(bd->netdev); 458 netdev_info(bd->netdev, "NIC Link is Down\n"); 459 } 460 } 461 462 static void bnge_get_ethtool_modes(struct bnge_net *bn, 463 struct ethtool_link_ksettings *lk_ksettings) 464 { 465 struct bnge_ethtool_link_info *elink_info; 466 struct bnge_link_info *link_info; 467 struct bnge_dev *bd = bn->bd; 468 469 elink_info = &bn->eth_link_info; 470 link_info = &bd->link_info; 471 472 if (!(bd->phy_flags & BNGE_PHY_FL_NO_PAUSE)) { 473 linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, 474 lk_ksettings->link_modes.supported); 475 linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 476 lk_ksettings->link_modes.supported); 477 } 478 479 if (link_info->support_auto_speeds2) 480 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 481 lk_ksettings->link_modes.supported); 482 483 if (~elink_info->autoneg & BNGE_AUTONEG_FLOW_CTRL) 484 return; 485 486 if (link_info->auto_pause_setting & BNGE_LINK_PAUSE_RX) 487 linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, 488 lk_ksettings->link_modes.advertising); 489 if (hweight8(link_info->auto_pause_setting & BNGE_LINK_PAUSE_BOTH) == 1) 490 linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 491 lk_ksettings->link_modes.advertising); 492 if (link_info->lp_pause & BNGE_LINK_PAUSE_RX) 493 linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, 494 lk_ksettings->link_modes.lp_advertising); 495 if (hweight8(link_info->lp_pause & BNGE_LINK_PAUSE_BOTH) == 1) 496 linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 497 lk_ksettings->link_modes.lp_advertising); 498 } 499 500 u32 bnge_get_link(struct net_device *dev) 501 { 502 struct bnge_net *bn = netdev_priv(dev); 503 504 return BNGE_LINK_IS_UP(bn->bd); 505 } 506 507 static enum bnge_media_type 508 bnge_get_media(struct bnge_link_info *link_info) 509 { 510 switch (link_info->media_type) { 511 case PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC: 512 return BNGE_MEDIA_CR; 513 default: 514 if (link_info->phy_type < ARRAY_SIZE(bnge_phy_types)) 515 return bnge_phy_types[link_info->phy_type]; 516 return BNGE_MEDIA_UNKNOWN; 517 } 518 } 519 520 enum bnge_link_speed_indices { 521 BNGE_LINK_SPEED_UNKNOWN = 0, 522 BNGE_LINK_SPEED_50GB_IDX, 523 BNGE_LINK_SPEED_100GB_IDX, 524 BNGE_LINK_SPEED_200GB_IDX, 525 BNGE_LINK_SPEED_400GB_IDX, 526 BNGE_LINK_SPEED_800GB_IDX, 527 __BNGE_LINK_SPEED_END 528 }; 529 530 static enum bnge_link_speed_indices bnge_fw_speed_idx(u16 speed) 531 { 532 switch (speed) { 533 case BNGE_LINK_SPEED_50GB: 534 case BNGE_LINK_SPEED_50GB_PAM4: 535 return BNGE_LINK_SPEED_50GB_IDX; 536 case BNGE_LINK_SPEED_100GB: 537 case BNGE_LINK_SPEED_100GB_PAM4: 538 case BNGE_LINK_SPEED_100GB_PAM4_112: 539 return BNGE_LINK_SPEED_100GB_IDX; 540 case BNGE_LINK_SPEED_200GB: 541 case BNGE_LINK_SPEED_200GB_PAM4: 542 case BNGE_LINK_SPEED_200GB_PAM4_112: 543 return BNGE_LINK_SPEED_200GB_IDX; 544 case BNGE_LINK_SPEED_400GB: 545 case BNGE_LINK_SPEED_400GB_PAM4: 546 case BNGE_LINK_SPEED_400GB_PAM4_112: 547 return BNGE_LINK_SPEED_400GB_IDX; 548 case BNGE_LINK_SPEED_800GB: 549 case BNGE_LINK_SPEED_800GB_PAM4_112: 550 return BNGE_LINK_SPEED_800GB_IDX; 551 default: 552 return BNGE_LINK_SPEED_UNKNOWN; 553 } 554 } 555 556 /* Compile-time link mode mapping table. 557 * Indexed by [speed_idx][sig_mode][media]. 558 */ 559 #define BNGE_LINK_M(speed, sig, media, lm) \ 560 [BNGE_LINK_SPEED_##speed##_IDX] \ 561 [BNGE_SIG_MODE_##sig] \ 562 [BNGE_MEDIA_##media] = ETHTOOL_LINK_MODE_##lm##_Full_BIT 563 564 static const enum ethtool_link_mode_bit_indices 565 bnge_link_modes[__BNGE_LINK_SPEED_END] 566 [BNGE_SIG_MODE_MAX] 567 [__BNGE_MEDIA_END] = { 568 /* 50GB PAM4 */ 569 BNGE_LINK_M(50GB, PAM4, CR, 50000baseCR), 570 BNGE_LINK_M(50GB, PAM4, SR, 50000baseSR), 571 BNGE_LINK_M(50GB, PAM4, LR_ER_FR, 50000baseLR_ER_FR), 572 BNGE_LINK_M(50GB, PAM4, KR, 50000baseKR), 573 574 /* 100GB NRZ */ 575 BNGE_LINK_M(100GB, NRZ, CR, 100000baseCR4), 576 BNGE_LINK_M(100GB, NRZ, SR, 100000baseSR4), 577 BNGE_LINK_M(100GB, NRZ, LR_ER_FR, 100000baseLR4_ER4), 578 BNGE_LINK_M(100GB, NRZ, KR, 100000baseKR4), 579 580 /* 100GB PAM4 */ 581 BNGE_LINK_M(100GB, PAM4, CR, 100000baseCR2), 582 BNGE_LINK_M(100GB, PAM4, SR, 100000baseSR2), 583 BNGE_LINK_M(100GB, PAM4, LR_ER_FR, 100000baseLR2_ER2_FR2), 584 BNGE_LINK_M(100GB, PAM4, KR, 100000baseKR2), 585 586 /* 100GB PAM4_112 */ 587 BNGE_LINK_M(100GB, PAM4_112, CR, 100000baseCR), 588 BNGE_LINK_M(100GB, PAM4_112, SR, 100000baseSR), 589 BNGE_LINK_M(100GB, PAM4_112, LR_ER_FR, 100000baseLR_ER_FR), 590 BNGE_LINK_M(100GB, PAM4_112, KR, 100000baseKR), 591 592 /* 200GB PAM4 */ 593 BNGE_LINK_M(200GB, PAM4, CR, 200000baseCR4), 594 BNGE_LINK_M(200GB, PAM4, SR, 200000baseSR4), 595 BNGE_LINK_M(200GB, PAM4, LR_ER_FR, 200000baseLR4_ER4_FR4), 596 BNGE_LINK_M(200GB, PAM4, KR, 200000baseKR4), 597 598 /* 200GB PAM4_112 */ 599 BNGE_LINK_M(200GB, PAM4_112, CR, 200000baseCR2), 600 BNGE_LINK_M(200GB, PAM4_112, SR, 200000baseSR2), 601 BNGE_LINK_M(200GB, PAM4_112, LR_ER_FR, 200000baseLR2_ER2_FR2), 602 BNGE_LINK_M(200GB, PAM4_112, KR, 200000baseKR2), 603 604 /* 400GB PAM4 */ 605 BNGE_LINK_M(400GB, PAM4, CR, 400000baseCR8), 606 BNGE_LINK_M(400GB, PAM4, SR, 400000baseSR8), 607 BNGE_LINK_M(400GB, PAM4, LR_ER_FR, 400000baseLR8_ER8_FR8), 608 BNGE_LINK_M(400GB, PAM4, KR, 400000baseKR8), 609 610 /* 400GB PAM4_112 */ 611 BNGE_LINK_M(400GB, PAM4_112, CR, 400000baseCR4), 612 BNGE_LINK_M(400GB, PAM4_112, SR, 400000baseSR4), 613 BNGE_LINK_M(400GB, PAM4_112, LR_ER_FR, 400000baseLR4_ER4_FR4), 614 BNGE_LINK_M(400GB, PAM4_112, KR, 400000baseKR4), 615 616 /* 800GB PAM4_112 */ 617 BNGE_LINK_M(800GB, PAM4_112, CR, 800000baseCR8), 618 BNGE_LINK_M(800GB, PAM4_112, SR, 800000baseSR8), 619 BNGE_LINK_M(800GB, PAM4_112, KR, 800000baseKR8), 620 }; 621 622 #define BNGE_LINK_MODE_UNKNOWN -1 623 624 static enum ethtool_link_mode_bit_indices 625 bnge_get_link_mode(struct bnge_net *bn) 626 { 627 enum ethtool_link_mode_bit_indices link_mode; 628 struct bnge_ethtool_link_info *elink_info; 629 enum bnge_link_speed_indices speed; 630 struct bnge_link_info *link_info; 631 struct bnge_dev *bd = bn->bd; 632 enum bnge_media_type media; 633 u8 sig_mode; 634 635 elink_info = &bn->eth_link_info; 636 link_info = &bd->link_info; 637 638 if (link_info->phy_link_status != BNGE_LINK_LINK) 639 return BNGE_LINK_MODE_UNKNOWN; 640 641 media = bnge_get_media(link_info); 642 if (BNGE_AUTO_MODE(link_info->auto_mode)) { 643 speed = bnge_fw_speed_idx(link_info->link_speed); 644 sig_mode = link_info->active_fec_sig_mode & 645 PORT_PHY_QCFG_RESP_SIGNAL_MODE_MASK; 646 } else { 647 speed = bnge_fw_speed_idx(elink_info->req_link_speed); 648 sig_mode = elink_info->req_signal_mode; 649 } 650 if (sig_mode >= BNGE_SIG_MODE_MAX) 651 return BNGE_LINK_MODE_UNKNOWN; 652 653 /* Since ETHTOOL_LINK_MODE_10baseT_Half_BIT is defined as 0 and 654 * not actually supported, the zeroes in this map can be safely 655 * used to represent unknown link modes. 656 */ 657 link_mode = bnge_link_modes[speed][sig_mode][media]; 658 if (!link_mode) 659 return BNGE_LINK_MODE_UNKNOWN; 660 661 return link_mode; 662 } 663 664 static const u16 bnge_nrz_speeds2_masks[__BNGE_LINK_SPEED_END] = { 665 [BNGE_LINK_SPEED_100GB_IDX] = BNGE_LINK_SPEEDS2_MSK_100GB, 666 }; 667 668 static const u16 bnge_pam4_speeds2_masks[__BNGE_LINK_SPEED_END] = { 669 [BNGE_LINK_SPEED_50GB_IDX] = BNGE_LINK_SPEEDS2_MSK_50GB_PAM4, 670 [BNGE_LINK_SPEED_100GB_IDX] = BNGE_LINK_SPEEDS2_MSK_100GB_PAM4, 671 [BNGE_LINK_SPEED_200GB_IDX] = BNGE_LINK_SPEEDS2_MSK_200GB_PAM4, 672 [BNGE_LINK_SPEED_400GB_IDX] = BNGE_LINK_SPEEDS2_MSK_400GB_PAM4, 673 }; 674 675 static const u16 bnge_pam4_112_speeds2_masks[__BNGE_LINK_SPEED_END] = { 676 [BNGE_LINK_SPEED_100GB_IDX] = BNGE_LINK_SPEEDS2_MSK_100GB_PAM4_112, 677 [BNGE_LINK_SPEED_200GB_IDX] = BNGE_LINK_SPEEDS2_MSK_200GB_PAM4_112, 678 [BNGE_LINK_SPEED_400GB_IDX] = BNGE_LINK_SPEEDS2_MSK_400GB_PAM4_112, 679 [BNGE_LINK_SPEED_800GB_IDX] = BNGE_LINK_SPEEDS2_MSK_800GB_PAM4_112, 680 }; 681 682 static enum bnge_link_speed_indices 683 bnge_encoding_speed_idx(u8 sig_mode, u16 speed_msk) 684 { 685 const u16 *speeds; 686 int idx, len; 687 688 switch (sig_mode) { 689 case BNGE_SIG_MODE_NRZ: 690 speeds = bnge_nrz_speeds2_masks; 691 len = ARRAY_SIZE(bnge_nrz_speeds2_masks); 692 break; 693 case BNGE_SIG_MODE_PAM4: 694 speeds = bnge_pam4_speeds2_masks; 695 len = ARRAY_SIZE(bnge_pam4_speeds2_masks); 696 break; 697 case BNGE_SIG_MODE_PAM4_112: 698 speeds = bnge_pam4_112_speeds2_masks; 699 len = ARRAY_SIZE(bnge_pam4_112_speeds2_masks); 700 break; 701 default: 702 return BNGE_LINK_SPEED_UNKNOWN; 703 } 704 705 for (idx = 0; idx < len; idx++) { 706 if (speeds[idx] == speed_msk) 707 return idx; 708 } 709 710 return BNGE_LINK_SPEED_UNKNOWN; 711 } 712 713 #define BNGE_FW_SPEED_MSK_BITS 16 714 715 static void 716 __bnge_get_ethtool_speeds(unsigned long fw_mask, enum bnge_media_type media, 717 u8 sig_mode, unsigned long *et_mask) 718 { 719 enum ethtool_link_mode_bit_indices link_mode; 720 enum bnge_link_speed_indices speed; 721 u8 bit; 722 723 for_each_set_bit(bit, &fw_mask, BNGE_FW_SPEED_MSK_BITS) { 724 speed = bnge_encoding_speed_idx(sig_mode, 1 << bit); 725 if (!speed) 726 continue; 727 728 link_mode = bnge_link_modes[speed][sig_mode][media]; 729 if (!link_mode) 730 continue; 731 732 linkmode_set_bit(link_mode, et_mask); 733 } 734 } 735 736 static void 737 bnge_get_ethtool_speeds(unsigned long fw_mask, enum bnge_media_type media, 738 u8 sig_mode, unsigned long *et_mask) 739 { 740 if (media) { 741 __bnge_get_ethtool_speeds(fw_mask, media, sig_mode, et_mask); 742 return; 743 } 744 745 /* list speeds for all media if unknown */ 746 for (media = 1; media < __BNGE_MEDIA_END; media++) 747 __bnge_get_ethtool_speeds(fw_mask, media, sig_mode, et_mask); 748 } 749 750 static void 751 bnge_get_all_ethtool_support_speeds(struct bnge_dev *bd, 752 enum bnge_media_type media, 753 struct ethtool_link_ksettings *lk_ksettings) 754 { 755 u16 sp = bd->link_info.support_speeds2; 756 757 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_NRZ, 758 lk_ksettings->link_modes.supported); 759 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4, 760 lk_ksettings->link_modes.supported); 761 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4_112, 762 lk_ksettings->link_modes.supported); 763 } 764 765 static void 766 bnge_get_all_ethtool_adv_speeds(struct bnge_net *bn, 767 enum bnge_media_type media, 768 struct ethtool_link_ksettings *lk_ksettings) 769 { 770 u16 sp = bn->eth_link_info.advertising; 771 772 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_NRZ, 773 lk_ksettings->link_modes.advertising); 774 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4, 775 lk_ksettings->link_modes.advertising); 776 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4_112, 777 lk_ksettings->link_modes.advertising); 778 } 779 780 static void 781 bnge_get_all_ethtool_lp_speeds(struct bnge_dev *bd, 782 enum bnge_media_type media, 783 struct ethtool_link_ksettings *lk_ksettings) 784 { 785 u16 sp = bd->link_info.lp_auto_link_speeds; 786 787 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_NRZ, 788 lk_ksettings->link_modes.lp_advertising); 789 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4, 790 lk_ksettings->link_modes.lp_advertising); 791 bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4_112, 792 lk_ksettings->link_modes.lp_advertising); 793 } 794 795 static void bnge_update_speed(u32 *delta, bool installed_media, u16 *speeds, 796 u16 speed_msk, const unsigned long *et_mask, 797 enum ethtool_link_mode_bit_indices mode) 798 { 799 bool mode_desired = linkmode_test_bit(mode, et_mask); 800 801 if (!mode || !mode_desired) 802 return; 803 804 /* installed media takes priority; for non-installed media, only allow 805 * one change per fw_speed bit (many to one mapping). 806 */ 807 if (installed_media || !(*delta & speed_msk)) { 808 *speeds |= speed_msk; 809 *delta |= speed_msk; 810 } 811 } 812 813 static void bnge_set_ethtool_speeds(struct bnge_net *bn, 814 const unsigned long *et_mask) 815 { 816 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 817 enum bnge_media_type media; 818 u32 delta_pam4_112 = 0; 819 u32 delta_pam4 = 0; 820 u32 delta_nrz = 0; 821 int i, m; 822 823 elink_info->advertising = 0; 824 825 media = bnge_get_media(&bn->bd->link_info); 826 for (i = 1; i < __BNGE_LINK_SPEED_END; i++) { 827 /* accept any legal media from user */ 828 for (m = 1; m < __BNGE_MEDIA_END; m++) { 829 bnge_update_speed(&delta_nrz, m == media, 830 &elink_info->advertising, 831 bnge_nrz_speeds2_masks[i], et_mask, 832 bnge_link_modes[i][BNGE_SIG_MODE_NRZ][m]); 833 bnge_update_speed(&delta_pam4, m == media, 834 &elink_info->advertising, 835 bnge_pam4_speeds2_masks[i], et_mask, 836 bnge_link_modes[i][BNGE_SIG_MODE_PAM4][m]); 837 bnge_update_speed(&delta_pam4_112, m == media, 838 &elink_info->advertising, 839 bnge_pam4_112_speeds2_masks[i], 840 et_mask, 841 bnge_link_modes[i][BNGE_SIG_MODE_PAM4_112][m]); 842 } 843 } 844 } 845 846 static void 847 bnge_fw_to_ethtool_advertised_fec(struct bnge_link_info *link_info, 848 struct ethtool_link_ksettings *lk_ksettings) 849 { 850 u16 fec_cfg = link_info->fec_cfg; 851 852 if ((fec_cfg & BNGE_FEC_NONE) || !(fec_cfg & BNGE_FEC_AUTONEG)) { 853 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, 854 lk_ksettings->link_modes.advertising); 855 return; 856 } 857 if (fec_cfg & BNGE_FEC_ENC_BASE_R) 858 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, 859 lk_ksettings->link_modes.advertising); 860 if (fec_cfg & BNGE_FEC_ENC_RS) 861 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, 862 lk_ksettings->link_modes.advertising); 863 if (fec_cfg & BNGE_FEC_ENC_LLRS) 864 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, 865 lk_ksettings->link_modes.advertising); 866 } 867 868 static void 869 bnge_fw_to_ethtool_support_fec(struct bnge_link_info *link_info, 870 struct ethtool_link_ksettings *lk_ksettings) 871 { 872 u16 fec_cfg = link_info->fec_cfg; 873 874 if (fec_cfg & BNGE_FEC_NONE) { 875 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, 876 lk_ksettings->link_modes.supported); 877 return; 878 } 879 if (fec_cfg & BNGE_FEC_ENC_BASE_R_CAP) 880 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, 881 lk_ksettings->link_modes.supported); 882 if (fec_cfg & BNGE_FEC_ENC_RS_CAP) 883 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, 884 lk_ksettings->link_modes.supported); 885 if (fec_cfg & BNGE_FEC_ENC_LLRS_CAP) 886 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, 887 lk_ksettings->link_modes.supported); 888 } 889 890 static void bnge_get_default_speeds(struct bnge_net *bn, 891 struct ethtool_link_ksettings *lk_ksettings) 892 { 893 struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info; 894 struct ethtool_link_settings *base = &lk_ksettings->base; 895 struct bnge_link_info *link_info; 896 struct bnge_dev *bd = bn->bd; 897 898 link_info = &bd->link_info; 899 900 if (link_info->link_state == BNGE_LINK_STATE_UP) { 901 base->speed = bnge_fw_to_ethtool_speed(link_info->link_speed); 902 base->duplex = DUPLEX_HALF; 903 if (link_info->duplex & BNGE_LINK_DUPLEX_FULL) 904 base->duplex = DUPLEX_FULL; 905 lk_ksettings->lanes = link_info->active_lanes; 906 } else if (!elink_info->autoneg) { 907 base->speed = 908 bnge_fw_to_ethtool_speed(elink_info->req_link_speed); 909 base->duplex = DUPLEX_HALF; 910 if (elink_info->req_duplex == BNGE_LINK_DUPLEX_FULL) 911 base->duplex = DUPLEX_FULL; 912 } 913 } 914 915 int bnge_get_link_ksettings(struct net_device *dev, 916 struct ethtool_link_ksettings *lk_ksettings) 917 { 918 struct ethtool_link_settings *base = &lk_ksettings->base; 919 enum ethtool_link_mode_bit_indices link_mode; 920 struct bnge_net *bn = netdev_priv(dev); 921 struct bnge_link_info *link_info; 922 struct bnge_dev *bd = bn->bd; 923 enum bnge_media_type media; 924 925 ethtool_link_ksettings_zero_link_mode(lk_ksettings, lp_advertising); 926 ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising); 927 ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported); 928 base->duplex = DUPLEX_UNKNOWN; 929 base->speed = SPEED_UNKNOWN; 930 link_info = &bd->link_info; 931 932 bnge_get_ethtool_modes(bn, lk_ksettings); 933 media = bnge_get_media(link_info); 934 bnge_get_all_ethtool_support_speeds(bd, media, lk_ksettings); 935 bnge_fw_to_ethtool_support_fec(link_info, lk_ksettings); 936 link_mode = bnge_get_link_mode(bn); 937 if (link_mode != BNGE_LINK_MODE_UNKNOWN) 938 ethtool_params_from_link_mode(lk_ksettings, link_mode); 939 else 940 bnge_get_default_speeds(bn, lk_ksettings); 941 942 if (bn->eth_link_info.autoneg) { 943 bnge_fw_to_ethtool_advertised_fec(link_info, lk_ksettings); 944 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 945 lk_ksettings->link_modes.advertising); 946 base->autoneg = AUTONEG_ENABLE; 947 bnge_get_all_ethtool_adv_speeds(bn, media, lk_ksettings); 948 if (link_info->phy_link_status == BNGE_LINK_LINK) 949 bnge_get_all_ethtool_lp_speeds(bd, media, lk_ksettings); 950 } else { 951 base->autoneg = AUTONEG_DISABLE; 952 } 953 954 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 955 lk_ksettings->link_modes.supported); 956 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 957 lk_ksettings->link_modes.advertising); 958 959 if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC) 960 base->port = PORT_DA; 961 else 962 base->port = PORT_FIBRE; 963 base->phy_address = link_info->phy_addr; 964 965 return 0; 966 } 967 968 static bool bnge_lanes_match(u32 user_lanes, u32 supported_lanes) 969 { 970 /* 0 means lanes unspecified (auto) */ 971 return !user_lanes || user_lanes == supported_lanes; 972 } 973 974 static int 975 bnge_force_link_speed(struct net_device *dev, u32 ethtool_speed, u32 user_lanes) 976 { 977 struct bnge_ethtool_link_info *elink_info; 978 struct bnge_net *bn = netdev_priv(dev); 979 u8 sig_mode = BNGE_SIG_MODE_NRZ; 980 u16 support_spds2; 981 u16 fw_speed = 0; 982 983 elink_info = &bn->eth_link_info; 984 support_spds2 = bn->bd->link_info.support_speeds2; 985 986 switch (ethtool_speed) { 987 case SPEED_50000: 988 if (bnge_lanes_match(user_lanes, 1) && 989 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_50GB_PAM4)) { 990 fw_speed = BNGE_LINK_SPEED_50GB_PAM4; 991 sig_mode = BNGE_SIG_MODE_PAM4; 992 } 993 break; 994 case SPEED_100000: 995 if (bnge_lanes_match(user_lanes, 4) && 996 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_100GB)) { 997 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB; 998 } else if (bnge_lanes_match(user_lanes, 2) && 999 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_100GB_PAM4)) { 1000 fw_speed = BNGE_LINK_SPEED_100GB_PAM4; 1001 sig_mode = BNGE_SIG_MODE_PAM4; 1002 } else if (bnge_lanes_match(user_lanes, 1) && 1003 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_100GB_PAM4_112)) { 1004 fw_speed = BNGE_LINK_SPEED_100GB_PAM4_112; 1005 sig_mode = BNGE_SIG_MODE_PAM4_112; 1006 } 1007 break; 1008 case SPEED_200000: 1009 if (bnge_lanes_match(user_lanes, 4) && 1010 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_200GB_PAM4)) { 1011 fw_speed = BNGE_LINK_SPEED_200GB_PAM4; 1012 sig_mode = BNGE_SIG_MODE_PAM4; 1013 } else if (bnge_lanes_match(user_lanes, 2) && 1014 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_200GB_PAM4_112)) { 1015 fw_speed = BNGE_LINK_SPEED_200GB_PAM4_112; 1016 sig_mode = BNGE_SIG_MODE_PAM4_112; 1017 } 1018 break; 1019 case SPEED_400000: 1020 if (bnge_lanes_match(user_lanes, 8) && 1021 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_400GB_PAM4)) { 1022 fw_speed = BNGE_LINK_SPEED_400GB_PAM4; 1023 sig_mode = BNGE_SIG_MODE_PAM4; 1024 } else if (bnge_lanes_match(user_lanes, 4) && 1025 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_400GB_PAM4_112)) { 1026 fw_speed = BNGE_LINK_SPEED_400GB_PAM4_112; 1027 sig_mode = BNGE_SIG_MODE_PAM4_112; 1028 } 1029 break; 1030 case SPEED_800000: 1031 if (bnge_lanes_match(user_lanes, 8) && 1032 (support_spds2 & BNGE_LINK_SPEEDS2_MSK_800GB_PAM4_112)) { 1033 fw_speed = BNGE_LINK_SPEED_800GB_PAM4_112; 1034 sig_mode = BNGE_SIG_MODE_PAM4_112; 1035 } 1036 break; 1037 default: 1038 break; 1039 } 1040 1041 if (!fw_speed) { 1042 if (user_lanes) 1043 netdev_err(dev, "unsupported speed or number of lanes!\n"); 1044 else 1045 netdev_err(dev, "unsupported speed!\n"); 1046 return -EINVAL; 1047 } 1048 1049 if (elink_info->req_link_speed == fw_speed && 1050 elink_info->req_signal_mode == sig_mode && 1051 elink_info->autoneg == 0) 1052 return -EALREADY; 1053 1054 elink_info->req_link_speed = fw_speed; 1055 elink_info->req_signal_mode = sig_mode; 1056 elink_info->req_duplex = BNGE_LINK_DUPLEX_FULL; 1057 elink_info->autoneg = 0; 1058 elink_info->advertising = 0; 1059 1060 return 0; 1061 } 1062 1063 int bnge_set_link_ksettings(struct net_device *dev, 1064 const struct ethtool_link_ksettings *lk_ksettings) 1065 { 1066 const struct ethtool_link_settings *base = &lk_ksettings->base; 1067 struct bnge_ethtool_link_info old_elink_info; 1068 struct bnge_ethtool_link_info *elink_info; 1069 struct bnge_net *bn = netdev_priv(dev); 1070 struct bnge_dev *bd = bn->bd; 1071 bool set_pause = false; 1072 int rc = 0; 1073 1074 if (!BNGE_PHY_CFG_ABLE(bd)) 1075 return -EOPNOTSUPP; 1076 1077 elink_info = &bn->eth_link_info; 1078 old_elink_info = *elink_info; 1079 1080 if (base->autoneg == AUTONEG_ENABLE) { 1081 bnge_set_ethtool_speeds(bn, 1082 lk_ksettings->link_modes.advertising); 1083 elink_info->autoneg |= BNGE_AUTONEG_SPEED; 1084 if (!elink_info->advertising) 1085 bnge_set_default_adv_speeds(bn); 1086 /* any change to autoneg will cause link change, therefore the 1087 * driver should put back the original pause setting in autoneg 1088 */ 1089 if (!(bd->phy_flags & BNGE_PHY_FL_NO_PAUSE)) 1090 set_pause = true; 1091 } else { 1092 if (base->duplex == DUPLEX_HALF) { 1093 netdev_err(dev, "HALF DUPLEX is not supported!\n"); 1094 rc = -EINVAL; 1095 goto set_setting_exit; 1096 } 1097 rc = bnge_force_link_speed(dev, base->speed, 1098 lk_ksettings->lanes); 1099 if (rc) { 1100 if (rc == -EALREADY) 1101 rc = 0; 1102 goto set_setting_exit; 1103 } 1104 } 1105 1106 if (netif_running(dev)) { 1107 rc = bnge_hwrm_set_link_setting(bn, set_pause); 1108 if (rc) 1109 *elink_info = old_elink_info; 1110 } 1111 1112 set_setting_exit: 1113 return rc; 1114 } 1115 1116 void bnge_link_async_event_process(struct bnge_net *bn, u16 event_id) 1117 { 1118 switch (event_id) { 1119 case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE: 1120 set_bit(BNGE_LINK_SPEED_CHNG_SP_EVENT, &bn->sp_event); 1121 break; 1122 case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE: 1123 case ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE: 1124 set_bit(BNGE_LINK_CFG_CHANGE_SP_EVENT, &bn->sp_event); 1125 break; 1126 case ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE: 1127 set_bit(BNGE_LINK_CHNG_SP_EVENT, &bn->sp_event); 1128 break; 1129 default: 1130 break; 1131 } 1132 } 1133