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 'bnxt_en-next'

Michael Chan says:

====================
bnxt_en: Update for net-next

The first 2 patches are fixes for the recently added hwmon changes.
The next 6 patches are enhancements to support ethtool lanes and
all the proper supported and advertised link modes. Before these
patches, the driver was only supporting the link modes for copper
media.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+572 -230
+87 -38
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 2129 2129 return INVALID_HW_RING_ID; 2130 2130 } 2131 2131 2132 + static u16 bnxt_get_force_speed(struct bnxt_link_info *link_info) 2133 + { 2134 + if (link_info->req_signal_mode == BNXT_SIG_MODE_PAM4) 2135 + return link_info->force_pam4_link_speed; 2136 + return link_info->force_link_speed; 2137 + } 2138 + 2139 + static void bnxt_set_force_speed(struct bnxt_link_info *link_info) 2140 + { 2141 + link_info->req_link_speed = link_info->force_link_speed; 2142 + link_info->req_signal_mode = BNXT_SIG_MODE_NRZ; 2143 + if (link_info->force_pam4_link_speed) { 2144 + link_info->req_link_speed = link_info->force_pam4_link_speed; 2145 + link_info->req_signal_mode = BNXT_SIG_MODE_PAM4; 2146 + } 2147 + } 2148 + 2149 + static void bnxt_set_auto_speed(struct bnxt_link_info *link_info) 2150 + { 2151 + link_info->advertising = link_info->auto_link_speeds; 2152 + link_info->advertising_pam4 = link_info->auto_pam4_link_speeds; 2153 + } 2154 + 2155 + static bool bnxt_force_speed_updated(struct bnxt_link_info *link_info) 2156 + { 2157 + if (link_info->req_signal_mode == BNXT_SIG_MODE_NRZ && 2158 + link_info->req_link_speed != link_info->force_link_speed) 2159 + return true; 2160 + if (link_info->req_signal_mode == BNXT_SIG_MODE_PAM4 && 2161 + link_info->req_link_speed != link_info->force_pam4_link_speed) 2162 + return true; 2163 + return false; 2164 + } 2165 + 2166 + static bool bnxt_auto_speed_updated(struct bnxt_link_info *link_info) 2167 + { 2168 + if (link_info->advertising != link_info->auto_link_speeds || 2169 + link_info->advertising_pam4 != link_info->auto_pam4_link_speeds) 2170 + return true; 2171 + return false; 2172 + } 2173 + 2132 2174 #define BNXT_EVENT_THERMAL_CURRENT_TEMP(data2) \ 2133 2175 ((data2) & \ 2134 2176 ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA2_CURRENT_TEMP_MASK) ··· 2189 2147 ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA1_TRANSITION_DIR) ==\ 2190 2148 ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA1_TRANSITION_DIR_INCREASING) 2191 2149 2192 - static void bnxt_event_error_report(struct bnxt *bp, u32 data1, u32 data2) 2150 + /* Return true if the workqueue has to be scheduled */ 2151 + static bool bnxt_event_error_report(struct bnxt *bp, u32 data1, u32 data2) 2193 2152 { 2194 2153 u32 err_type = BNXT_EVENT_ERROR_REPORT_TYPE(data1); 2195 2154 ··· 2208 2165 case ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_THERMAL_THRESHOLD: { 2209 2166 u32 type = EVENT_DATA1_THERMAL_THRESHOLD_TYPE(data1); 2210 2167 char *threshold_type; 2168 + bool notify = false; 2211 2169 char *dir_str; 2212 2170 2213 2171 switch (type) { ··· 2226 2182 break; 2227 2183 default: 2228 2184 netdev_err(bp->dev, "Unknown Thermal threshold type event\n"); 2229 - return; 2185 + return false; 2230 2186 } 2231 - if (EVENT_DATA1_THERMAL_THRESHOLD_DIR_INCREASING(data1)) 2187 + if (EVENT_DATA1_THERMAL_THRESHOLD_DIR_INCREASING(data1)) { 2232 2188 dir_str = "above"; 2233 - else 2189 + notify = true; 2190 + } else { 2234 2191 dir_str = "below"; 2192 + } 2235 2193 netdev_warn(bp->dev, "Chip temperature has gone %s the %s thermal threshold!\n", 2236 2194 dir_str, threshold_type); 2237 2195 netdev_warn(bp->dev, "Temperature (In Celsius), Current: %lu, threshold: %lu\n", 2238 2196 BNXT_EVENT_THERMAL_CURRENT_TEMP(data2), 2239 2197 BNXT_EVENT_THERMAL_THRESHOLD_TEMP(data2)); 2240 - bnxt_hwmon_notify_event(bp, type); 2241 - break; 2198 + if (notify) { 2199 + bp->thermal_threshold_type = type; 2200 + set_bit(BNXT_THERMAL_THRESHOLD_SP_EVENT, &bp->sp_event); 2201 + return true; 2202 + } 2203 + return false; 2242 2204 } 2243 2205 default: 2244 2206 netdev_err(bp->dev, "FW reported unknown error type %u\n", 2245 2207 err_type); 2246 2208 break; 2247 2209 } 2210 + return false; 2248 2211 } 2249 2212 2250 2213 #define BNXT_GET_EVENT_PORT(data) \ ··· 2297 2246 /* print unsupported speed warning in forced speed mode only */ 2298 2247 if (!(link_info->autoneg & BNXT_AUTONEG_SPEED) && 2299 2248 (data1 & 0x20000)) { 2300 - u16 fw_speed = link_info->force_link_speed; 2249 + u16 fw_speed = bnxt_get_force_speed(link_info); 2301 2250 u32 speed = bnxt_fw_to_ethtool_speed(fw_speed); 2302 2251 2303 2252 if (speed != SPEED_UNKNOWN) ··· 2452 2401 goto async_event_process_exit; 2453 2402 } 2454 2403 case ASYNC_EVENT_CMPL_EVENT_ID_ERROR_REPORT: { 2455 - bnxt_event_error_report(bp, data1, data2); 2404 + if (bnxt_event_error_report(bp, data1, data2)) 2405 + break; 2456 2406 goto async_event_process_exit; 2457 2407 } 2458 2408 case ASYNC_EVENT_CMPL_EVENT_ID_PHC_UPDATE: { ··· 9731 9679 return ((supported | diff) != supported); 9732 9680 } 9733 9681 9682 + static bool bnxt_support_speed_dropped(struct bnxt_link_info *link_info) 9683 + { 9684 + /* Check if any advertised speeds are no longer supported. The caller 9685 + * holds the link_lock mutex, so we can modify link_info settings. 9686 + */ 9687 + if (bnxt_support_dropped(link_info->advertising, 9688 + link_info->support_auto_speeds)) { 9689 + link_info->advertising = link_info->support_auto_speeds; 9690 + return true; 9691 + } 9692 + if (bnxt_support_dropped(link_info->advertising_pam4, 9693 + link_info->support_pam4_auto_speeds)) { 9694 + link_info->advertising_pam4 = link_info->support_pam4_auto_speeds; 9695 + return true; 9696 + } 9697 + return false; 9698 + } 9699 + 9734 9700 int bnxt_update_link(struct bnxt *bp, bool chng_link_state) 9735 9701 { 9736 9702 struct bnxt_link_info *link_info = &bp->link_info; 9737 9703 struct hwrm_port_phy_qcfg_output *resp; 9738 9704 struct hwrm_port_phy_qcfg_input *req; 9739 9705 u8 link_state = link_info->link_state; 9740 - bool support_changed = false; 9706 + bool support_changed; 9741 9707 int rc; 9742 9708 9743 9709 rc = hwrm_req_init(bp, req, HWRM_PORT_PHY_QCFG); ··· 9869 9799 if (!BNXT_PHY_CFG_ABLE(bp)) 9870 9800 return 0; 9871 9801 9872 - /* Check if any advertised speeds are no longer supported. The caller 9873 - * holds the link_lock mutex, so we can modify link_info settings. 9874 - */ 9875 - if (bnxt_support_dropped(link_info->advertising, 9876 - link_info->support_auto_speeds)) { 9877 - link_info->advertising = link_info->support_auto_speeds; 9878 - support_changed = true; 9879 - } 9880 - if (bnxt_support_dropped(link_info->advertising_pam4, 9881 - link_info->support_pam4_auto_speeds)) { 9882 - link_info->advertising_pam4 = link_info->support_pam4_auto_speeds; 9883 - support_changed = true; 9884 - } 9802 + support_changed = bnxt_support_speed_dropped(link_info); 9885 9803 if (support_changed && (link_info->autoneg & BNXT_AUTONEG_SPEED)) 9886 9804 bnxt_hwrm_set_link_setting(bp, true, false); 9887 9805 return 0; ··· 10410 10352 if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) { 10411 10353 if (BNXT_AUTO_MODE(link_info->auto_mode)) 10412 10354 update_link = true; 10413 - if (link_info->req_signal_mode == BNXT_SIG_MODE_NRZ && 10414 - link_info->req_link_speed != link_info->force_link_speed) 10415 - update_link = true; 10416 - else if (link_info->req_signal_mode == BNXT_SIG_MODE_PAM4 && 10417 - link_info->req_link_speed != link_info->force_pam4_link_speed) 10355 + if (bnxt_force_speed_updated(link_info)) 10418 10356 update_link = true; 10419 10357 if (link_info->req_duplex != link_info->duplex_setting) 10420 10358 update_link = true; 10421 10359 } else { 10422 10360 if (link_info->auto_mode == BNXT_LINK_AUTO_NONE) 10423 10361 update_link = true; 10424 - if (link_info->advertising != link_info->auto_link_speeds || 10425 - link_info->advertising_pam4 != link_info->auto_pam4_link_speeds) 10362 + if (bnxt_auto_speed_updated(link_info)) 10426 10363 update_link = true; 10427 10364 } 10428 10365 ··· 12035 11982 } else { 12036 11983 link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL; 12037 11984 } 12038 - link_info->advertising = link_info->auto_link_speeds; 12039 - link_info->advertising_pam4 = link_info->auto_pam4_link_speeds; 11985 + bnxt_set_auto_speed(link_info); 12040 11986 } else { 12041 - link_info->req_link_speed = link_info->force_link_speed; 12042 - link_info->req_signal_mode = BNXT_SIG_MODE_NRZ; 12043 - if (link_info->force_pam4_link_speed) { 12044 - link_info->req_link_speed = 12045 - link_info->force_pam4_link_speed; 12046 - link_info->req_signal_mode = BNXT_SIG_MODE_PAM4; 12047 - } 11987 + bnxt_set_force_speed(link_info); 12048 11988 link_info->req_duplex = link_info->duplex_setting; 12049 11989 } 12050 11990 if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) ··· 12130 12084 12131 12085 if (test_and_clear_bit(BNXT_FW_ECHO_REQUEST_SP_EVENT, &bp->sp_event)) 12132 12086 bnxt_fw_echo_reply(bp); 12087 + 12088 + if (test_and_clear_bit(BNXT_THERMAL_THRESHOLD_SP_EVENT, &bp->sp_event)) 12089 + bnxt_hwmon_notify_event(bp); 12133 12090 12134 12091 /* These functions below will clear BNXT_STATE_IN_SP_TASK. They 12135 12092 * must be the last functions to be called before exiting.
+3
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 1295 1295 u8 req_signal_mode; 1296 1296 #define BNXT_SIG_MODE_NRZ PORT_PHY_QCFG_RESP_SIGNAL_MODE_NRZ 1297 1297 #define BNXT_SIG_MODE_PAM4 PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4 1298 + #define BNXT_SIG_MODE_MAX (PORT_PHY_QCFG_RESP_SIGNAL_MODE_LAST + 1) 1298 1299 u8 req_duplex; 1299 1300 u8 req_flow_ctrl; 1300 1301 u16 req_link_speed; ··· 2095 2094 #define BNXT_FW_RESET_NOTIFY_SP_EVENT 18 2096 2095 #define BNXT_FW_EXCEPTION_SP_EVENT 19 2097 2096 #define BNXT_LINK_CFG_CHANGE_SP_EVENT 21 2097 + #define BNXT_THERMAL_THRESHOLD_SP_EVENT 22 2098 2098 #define BNXT_FW_ECHO_REQUEST_SP_EVENT 23 2099 2099 2100 2100 struct delayed_work fw_reset_task; ··· 2198 2196 u8 fatal_thresh_temp; 2199 2197 u8 shutdown_thresh_temp; 2200 2198 #endif 2199 + u32 thermal_threshold_type; 2201 2200 enum board_idx board_idx; 2202 2201 }; 2203 2202
+478 -188
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
··· 8 8 * the Free Software Foundation. 9 9 */ 10 10 11 + #include <linux/bitops.h> 11 12 #include <linux/ctype.h> 12 13 #include <linux/stringify.h> 13 14 #include <linux/ethtool.h> ··· 1507 1506 return speed_mask; 1508 1507 } 1509 1508 1510 - #define BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, name)\ 1511 - { \ 1512 - if ((fw_speeds) & BNXT_LINK_SPEED_MSK_100MB) \ 1513 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1514 - 100baseT_Full); \ 1515 - if ((fw_speeds) & BNXT_LINK_SPEED_MSK_1GB) \ 1516 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1517 - 1000baseT_Full); \ 1518 - if ((fw_speeds) & BNXT_LINK_SPEED_MSK_10GB) \ 1519 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1520 - 10000baseT_Full); \ 1521 - if ((fw_speeds) & BNXT_LINK_SPEED_MSK_25GB) \ 1522 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1523 - 25000baseCR_Full); \ 1524 - if ((fw_speeds) & BNXT_LINK_SPEED_MSK_40GB) \ 1525 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1526 - 40000baseCR4_Full);\ 1527 - if ((fw_speeds) & BNXT_LINK_SPEED_MSK_50GB) \ 1528 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1529 - 50000baseCR2_Full);\ 1530 - if ((fw_speeds) & BNXT_LINK_SPEED_MSK_100GB) \ 1531 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1532 - 100000baseCR4_Full);\ 1533 - if ((fw_pause) & BNXT_LINK_PAUSE_RX) { \ 1534 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1535 - Pause); \ 1536 - if (!((fw_pause) & BNXT_LINK_PAUSE_TX)) \ 1537 - ethtool_link_ksettings_add_link_mode( \ 1538 - lk_ksettings, name, Asym_Pause);\ 1539 - } else if ((fw_pause) & BNXT_LINK_PAUSE_TX) { \ 1540 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1541 - Asym_Pause); \ 1542 - } \ 1509 + enum bnxt_media_type { 1510 + BNXT_MEDIA_UNKNOWN = 0, 1511 + BNXT_MEDIA_TP, 1512 + BNXT_MEDIA_CR, 1513 + BNXT_MEDIA_SR, 1514 + BNXT_MEDIA_LR_ER_FR, 1515 + BNXT_MEDIA_KR, 1516 + BNXT_MEDIA_KX, 1517 + BNXT_MEDIA_X, 1518 + __BNXT_MEDIA_END, 1519 + }; 1520 + 1521 + static const enum bnxt_media_type bnxt_phy_types[] = { 1522 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASECR] = BNXT_MEDIA_CR, 1523 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKR4] = BNXT_MEDIA_KR, 1524 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASELR] = BNXT_MEDIA_LR_ER_FR, 1525 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASESR] = BNXT_MEDIA_SR, 1526 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKR2] = BNXT_MEDIA_KR, 1527 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKX] = BNXT_MEDIA_KX, 1528 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKR] = BNXT_MEDIA_KR, 1529 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASET] = BNXT_MEDIA_TP, 1530 + [PORT_PHY_QCFG_RESP_PHY_TYPE_BASETE] = BNXT_MEDIA_TP, 1531 + [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASECR_CA_L] = BNXT_MEDIA_CR, 1532 + [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASECR_CA_S] = BNXT_MEDIA_CR, 1533 + [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASECR_CA_N] = BNXT_MEDIA_CR, 1534 + [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASESR] = BNXT_MEDIA_SR, 1535 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR4] = BNXT_MEDIA_CR, 1536 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR4] = BNXT_MEDIA_SR, 1537 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR4] = BNXT_MEDIA_LR_ER_FR, 1538 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER4] = BNXT_MEDIA_LR_ER_FR, 1539 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR10] = BNXT_MEDIA_SR, 1540 + [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASECR4] = BNXT_MEDIA_CR, 1541 + [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASESR4] = BNXT_MEDIA_SR, 1542 + [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASELR4] = BNXT_MEDIA_LR_ER_FR, 1543 + [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASEER4] = BNXT_MEDIA_LR_ER_FR, 1544 + [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_ACTIVE_CABLE] = BNXT_MEDIA_SR, 1545 + [PORT_PHY_QCFG_RESP_PHY_TYPE_1G_BASET] = BNXT_MEDIA_TP, 1546 + [PORT_PHY_QCFG_RESP_PHY_TYPE_1G_BASESX] = BNXT_MEDIA_X, 1547 + [PORT_PHY_QCFG_RESP_PHY_TYPE_1G_BASECX] = BNXT_MEDIA_X, 1548 + [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR4] = BNXT_MEDIA_CR, 1549 + [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR4] = BNXT_MEDIA_SR, 1550 + [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR4] = BNXT_MEDIA_LR_ER_FR, 1551 + [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER4] = BNXT_MEDIA_LR_ER_FR, 1552 + [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASECR] = BNXT_MEDIA_CR, 1553 + [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASESR] = BNXT_MEDIA_SR, 1554 + [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASELR] = BNXT_MEDIA_LR_ER_FR, 1555 + [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASEER] = BNXT_MEDIA_LR_ER_FR, 1556 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR2] = BNXT_MEDIA_CR, 1557 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR2] = BNXT_MEDIA_SR, 1558 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR2] = BNXT_MEDIA_LR_ER_FR, 1559 + [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER2] = BNXT_MEDIA_LR_ER_FR, 1560 + }; 1561 + 1562 + static enum bnxt_media_type 1563 + bnxt_get_media(struct bnxt_link_info *link_info) 1564 + { 1565 + switch (link_info->media_type) { 1566 + case PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP: 1567 + return BNXT_MEDIA_TP; 1568 + case PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC: 1569 + return BNXT_MEDIA_CR; 1570 + default: 1571 + if (link_info->phy_type < ARRAY_SIZE(bnxt_phy_types)) 1572 + return bnxt_phy_types[link_info->phy_type]; 1573 + return BNXT_MEDIA_UNKNOWN; 1574 + } 1543 1575 } 1544 1576 1545 - #define BNXT_ETHTOOL_TO_FW_SPDS(fw_speeds, lk_ksettings, name) \ 1546 - { \ 1547 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1548 - 100baseT_Full) || \ 1549 - ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1550 - 100baseT_Half)) \ 1551 - (fw_speeds) |= BNXT_LINK_SPEED_MSK_100MB; \ 1552 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1553 - 1000baseT_Full) || \ 1554 - ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1555 - 1000baseT_Half)) \ 1556 - (fw_speeds) |= BNXT_LINK_SPEED_MSK_1GB; \ 1557 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1558 - 10000baseT_Full)) \ 1559 - (fw_speeds) |= BNXT_LINK_SPEED_MSK_10GB; \ 1560 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1561 - 25000baseCR_Full)) \ 1562 - (fw_speeds) |= BNXT_LINK_SPEED_MSK_25GB; \ 1563 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1564 - 40000baseCR4_Full)) \ 1565 - (fw_speeds) |= BNXT_LINK_SPEED_MSK_40GB; \ 1566 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1567 - 50000baseCR2_Full)) \ 1568 - (fw_speeds) |= BNXT_LINK_SPEED_MSK_50GB; \ 1569 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1570 - 100000baseCR4_Full)) \ 1571 - (fw_speeds) |= BNXT_LINK_SPEED_MSK_100GB; \ 1577 + enum bnxt_link_speed_indices { 1578 + BNXT_LINK_SPEED_UNKNOWN = 0, 1579 + BNXT_LINK_SPEED_100MB_IDX, 1580 + BNXT_LINK_SPEED_1GB_IDX, 1581 + BNXT_LINK_SPEED_10GB_IDX, 1582 + BNXT_LINK_SPEED_25GB_IDX, 1583 + BNXT_LINK_SPEED_40GB_IDX, 1584 + BNXT_LINK_SPEED_50GB_IDX, 1585 + BNXT_LINK_SPEED_100GB_IDX, 1586 + BNXT_LINK_SPEED_200GB_IDX, 1587 + __BNXT_LINK_SPEED_END 1588 + }; 1589 + 1590 + static enum bnxt_link_speed_indices bnxt_fw_speed_idx(u16 speed) 1591 + { 1592 + switch (speed) { 1593 + case BNXT_LINK_SPEED_100MB: return BNXT_LINK_SPEED_100MB_IDX; 1594 + case BNXT_LINK_SPEED_1GB: return BNXT_LINK_SPEED_1GB_IDX; 1595 + case BNXT_LINK_SPEED_10GB: return BNXT_LINK_SPEED_10GB_IDX; 1596 + case BNXT_LINK_SPEED_25GB: return BNXT_LINK_SPEED_25GB_IDX; 1597 + case BNXT_LINK_SPEED_40GB: return BNXT_LINK_SPEED_40GB_IDX; 1598 + case BNXT_LINK_SPEED_50GB: return BNXT_LINK_SPEED_50GB_IDX; 1599 + case BNXT_LINK_SPEED_100GB: return BNXT_LINK_SPEED_100GB_IDX; 1600 + case BNXT_LINK_SPEED_200GB: return BNXT_LINK_SPEED_200GB_IDX; 1601 + default: return BNXT_LINK_SPEED_UNKNOWN; 1602 + } 1572 1603 } 1573 1604 1574 - #define BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, name) \ 1575 - { \ 1576 - if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_50GB) \ 1577 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1578 - 50000baseCR_Full); \ 1579 - if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_100GB) \ 1580 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1581 - 100000baseCR2_Full);\ 1582 - if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_200GB) \ 1583 - ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ 1584 - 200000baseCR4_Full);\ 1605 + static const enum ethtool_link_mode_bit_indices 1606 + bnxt_link_modes[__BNXT_LINK_SPEED_END][BNXT_SIG_MODE_MAX][__BNXT_MEDIA_END] = { 1607 + [BNXT_LINK_SPEED_100MB_IDX] = { 1608 + { 1609 + [BNXT_MEDIA_TP] = ETHTOOL_LINK_MODE_100baseT_Full_BIT, 1610 + }, 1611 + }, 1612 + [BNXT_LINK_SPEED_1GB_IDX] = { 1613 + { 1614 + [BNXT_MEDIA_TP] = ETHTOOL_LINK_MODE_1000baseT_Full_BIT, 1615 + /* historically baseT, but DAC is more correctly baseX */ 1616 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_1000baseX_Full_BIT, 1617 + [BNXT_MEDIA_KX] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, 1618 + [BNXT_MEDIA_X] = ETHTOOL_LINK_MODE_1000baseX_Full_BIT, 1619 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, 1620 + }, 1621 + }, 1622 + [BNXT_LINK_SPEED_10GB_IDX] = { 1623 + { 1624 + [BNXT_MEDIA_TP] = ETHTOOL_LINK_MODE_10000baseT_Full_BIT, 1625 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, 1626 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, 1627 + [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, 1628 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, 1629 + [BNXT_MEDIA_KX] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, 1630 + }, 1631 + }, 1632 + [BNXT_LINK_SPEED_25GB_IDX] = { 1633 + { 1634 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, 1635 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, 1636 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, 1637 + }, 1638 + }, 1639 + [BNXT_LINK_SPEED_40GB_IDX] = { 1640 + { 1641 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, 1642 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, 1643 + [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, 1644 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, 1645 + }, 1646 + }, 1647 + [BNXT_LINK_SPEED_50GB_IDX] = { 1648 + [BNXT_SIG_MODE_NRZ] = { 1649 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, 1650 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, 1651 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, 1652 + }, 1653 + [BNXT_SIG_MODE_PAM4] = { 1654 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, 1655 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, 1656 + [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, 1657 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, 1658 + }, 1659 + }, 1660 + [BNXT_LINK_SPEED_100GB_IDX] = { 1661 + [BNXT_SIG_MODE_NRZ] = { 1662 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, 1663 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, 1664 + [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, 1665 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, 1666 + }, 1667 + [BNXT_SIG_MODE_PAM4] = { 1668 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, 1669 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, 1670 + [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, 1671 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, 1672 + }, 1673 + }, 1674 + [BNXT_LINK_SPEED_200GB_IDX] = { 1675 + [BNXT_SIG_MODE_PAM4] = { 1676 + [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, 1677 + [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, 1678 + [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, 1679 + [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, 1680 + }, 1681 + }, 1682 + }; 1683 + 1684 + #define BNXT_LINK_MODE_UNKNOWN -1 1685 + 1686 + static enum ethtool_link_mode_bit_indices 1687 + bnxt_get_link_mode(struct bnxt_link_info *link_info) 1688 + { 1689 + enum ethtool_link_mode_bit_indices link_mode; 1690 + enum bnxt_link_speed_indices speed; 1691 + enum bnxt_media_type media; 1692 + u8 sig_mode; 1693 + 1694 + if (link_info->phy_link_status != BNXT_LINK_LINK) 1695 + return BNXT_LINK_MODE_UNKNOWN; 1696 + 1697 + media = bnxt_get_media(link_info); 1698 + if (BNXT_AUTO_MODE(link_info->auto_mode)) { 1699 + speed = bnxt_fw_speed_idx(link_info->link_speed); 1700 + sig_mode = link_info->active_fec_sig_mode & 1701 + PORT_PHY_QCFG_RESP_SIGNAL_MODE_MASK; 1702 + } else { 1703 + speed = bnxt_fw_speed_idx(link_info->req_link_speed); 1704 + sig_mode = link_info->req_signal_mode; 1705 + } 1706 + if (sig_mode >= BNXT_SIG_MODE_MAX) 1707 + return BNXT_LINK_MODE_UNKNOWN; 1708 + 1709 + /* Note ETHTOOL_LINK_MODE_10baseT_Half_BIT == 0 is a legal Linux 1710 + * link mode, but since no such devices exist, the zeroes in the 1711 + * map can be conveniently used to represent unknown link modes. 1712 + */ 1713 + link_mode = bnxt_link_modes[speed][sig_mode][media]; 1714 + if (!link_mode) 1715 + return BNXT_LINK_MODE_UNKNOWN; 1716 + 1717 + switch (link_mode) { 1718 + case ETHTOOL_LINK_MODE_100baseT_Full_BIT: 1719 + if (~link_info->duplex & BNXT_LINK_DUPLEX_FULL) 1720 + link_mode = ETHTOOL_LINK_MODE_100baseT_Half_BIT; 1721 + break; 1722 + case ETHTOOL_LINK_MODE_1000baseT_Full_BIT: 1723 + if (~link_info->duplex & BNXT_LINK_DUPLEX_FULL) 1724 + link_mode = ETHTOOL_LINK_MODE_1000baseT_Half_BIT; 1725 + break; 1726 + default: 1727 + break; 1728 + } 1729 + 1730 + return link_mode; 1585 1731 } 1586 1732 1587 - #define BNXT_ETHTOOL_TO_FW_PAM4_SPDS(fw_speeds, lk_ksettings, name) \ 1588 - { \ 1589 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1590 - 50000baseCR_Full)) \ 1591 - (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_50GB; \ 1592 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1593 - 100000baseCR2_Full)) \ 1594 - (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_100GB; \ 1595 - if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ 1596 - 200000baseCR4_Full)) \ 1597 - (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_200GB; \ 1733 + static void bnxt_get_ethtool_modes(struct bnxt_link_info *link_info, 1734 + struct ethtool_link_ksettings *lk_ksettings) 1735 + { 1736 + struct bnxt *bp = container_of(link_info, struct bnxt, link_info); 1737 + 1738 + if (!(bp->phy_flags & BNXT_PHY_FL_NO_PAUSE)) { 1739 + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, 1740 + lk_ksettings->link_modes.supported); 1741 + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 1742 + lk_ksettings->link_modes.supported); 1743 + } 1744 + 1745 + if (link_info->support_auto_speeds || link_info->support_pam4_auto_speeds) 1746 + linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 1747 + lk_ksettings->link_modes.supported); 1748 + 1749 + if (~link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) 1750 + return; 1751 + 1752 + if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_RX) 1753 + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, 1754 + lk_ksettings->link_modes.advertising); 1755 + if (hweight8(link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) == 1) 1756 + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 1757 + lk_ksettings->link_modes.advertising); 1758 + if (link_info->lp_pause & BNXT_LINK_PAUSE_RX) 1759 + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, 1760 + lk_ksettings->link_modes.lp_advertising); 1761 + if (hweight8(link_info->lp_pause & BNXT_LINK_PAUSE_BOTH) == 1) 1762 + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 1763 + lk_ksettings->link_modes.lp_advertising); 1764 + } 1765 + 1766 + static const u16 bnxt_nrz_speed_masks[] = { 1767 + [BNXT_LINK_SPEED_100MB_IDX] = BNXT_LINK_SPEED_MSK_100MB, 1768 + [BNXT_LINK_SPEED_1GB_IDX] = BNXT_LINK_SPEED_MSK_1GB, 1769 + [BNXT_LINK_SPEED_10GB_IDX] = BNXT_LINK_SPEED_MSK_10GB, 1770 + [BNXT_LINK_SPEED_25GB_IDX] = BNXT_LINK_SPEED_MSK_25GB, 1771 + [BNXT_LINK_SPEED_40GB_IDX] = BNXT_LINK_SPEED_MSK_40GB, 1772 + [BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_SPEED_MSK_50GB, 1773 + [BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEED_MSK_100GB, 1774 + [__BNXT_LINK_SPEED_END - 1] = 0 /* make any legal speed a valid index */ 1775 + }; 1776 + 1777 + static const u16 bnxt_pam4_speed_masks[] = { 1778 + [BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_50GB, 1779 + [BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_100GB, 1780 + [BNXT_LINK_SPEED_200GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_200GB, 1781 + }; 1782 + 1783 + static enum bnxt_link_speed_indices 1784 + bnxt_encoding_speed_idx(u8 sig_mode, u16 speed_msk) 1785 + { 1786 + const u16 *speeds; 1787 + int idx, len; 1788 + 1789 + switch (sig_mode) { 1790 + case BNXT_SIG_MODE_NRZ: 1791 + speeds = bnxt_nrz_speed_masks; 1792 + len = ARRAY_SIZE(bnxt_nrz_speed_masks); 1793 + break; 1794 + case BNXT_SIG_MODE_PAM4: 1795 + speeds = bnxt_pam4_speed_masks; 1796 + len = ARRAY_SIZE(bnxt_pam4_speed_masks); 1797 + break; 1798 + default: 1799 + return BNXT_LINK_SPEED_UNKNOWN; 1800 + } 1801 + 1802 + for (idx = 0; idx < len; idx++) { 1803 + if (speeds[idx] == speed_msk) 1804 + return idx; 1805 + } 1806 + 1807 + return BNXT_LINK_SPEED_UNKNOWN; 1808 + } 1809 + 1810 + #define BNXT_FW_SPEED_MSK_BITS 16 1811 + 1812 + static void 1813 + __bnxt_get_ethtool_speeds(unsigned long fw_mask, enum bnxt_media_type media, 1814 + u8 sig_mode, unsigned long *et_mask) 1815 + { 1816 + enum ethtool_link_mode_bit_indices link_mode; 1817 + enum bnxt_link_speed_indices speed; 1818 + u8 bit; 1819 + 1820 + for_each_set_bit(bit, &fw_mask, BNXT_FW_SPEED_MSK_BITS) { 1821 + speed = bnxt_encoding_speed_idx(sig_mode, 1 << bit); 1822 + if (!speed) 1823 + continue; 1824 + 1825 + link_mode = bnxt_link_modes[speed][sig_mode][media]; 1826 + if (!link_mode) 1827 + continue; 1828 + 1829 + linkmode_set_bit(link_mode, et_mask); 1830 + } 1831 + } 1832 + 1833 + static void 1834 + bnxt_get_ethtool_speeds(unsigned long fw_mask, enum bnxt_media_type media, 1835 + u8 sig_mode, unsigned long *et_mask) 1836 + { 1837 + if (media) { 1838 + __bnxt_get_ethtool_speeds(fw_mask, media, sig_mode, et_mask); 1839 + return; 1840 + } 1841 + 1842 + /* list speeds for all media if unknown */ 1843 + for (media = 1; media < __BNXT_MEDIA_END; media++) 1844 + __bnxt_get_ethtool_speeds(fw_mask, media, sig_mode, et_mask); 1845 + } 1846 + 1847 + static void bnxt_update_speed(u32 *delta, bool installed_media, u16 *speeds, 1848 + u16 speed_msk, const unsigned long *et_mask, 1849 + enum ethtool_link_mode_bit_indices mode) 1850 + { 1851 + bool mode_desired = linkmode_test_bit(mode, et_mask); 1852 + 1853 + if (!mode) 1854 + return; 1855 + 1856 + /* enabled speeds for installed media should override */ 1857 + if (installed_media && mode_desired) { 1858 + *speeds |= speed_msk; 1859 + *delta |= speed_msk; 1860 + return; 1861 + } 1862 + 1863 + /* many to one mapping, only allow one change per fw_speed bit */ 1864 + if (!(*delta & speed_msk) && (mode_desired == !(*speeds & speed_msk))) { 1865 + *speeds ^= speed_msk; 1866 + *delta |= speed_msk; 1867 + } 1868 + } 1869 + 1870 + static void bnxt_set_ethtool_speeds(struct bnxt_link_info *link_info, 1871 + const unsigned long *et_mask) 1872 + { 1873 + enum bnxt_media_type media = bnxt_get_media(link_info); 1874 + u32 delta_pam4 = 0; 1875 + u32 delta_nrz = 0; 1876 + int i, m; 1877 + 1878 + for (i = 1; i < __BNXT_LINK_SPEED_END; i++) { 1879 + /* accept any legal media from user */ 1880 + for (m = 1; m < __BNXT_MEDIA_END; m++) { 1881 + bnxt_update_speed(&delta_nrz, m == media, 1882 + &link_info->advertising, 1883 + bnxt_nrz_speed_masks[i], et_mask, 1884 + bnxt_link_modes[i][BNXT_SIG_MODE_NRZ][m]); 1885 + bnxt_update_speed(&delta_pam4, m == media, 1886 + &link_info->advertising_pam4, 1887 + bnxt_pam4_speed_masks[i], et_mask, 1888 + bnxt_link_modes[i][BNXT_SIG_MODE_PAM4][m]); 1889 + } 1890 + } 1598 1891 } 1599 1892 1600 1893 static void bnxt_fw_to_ethtool_advertised_fec(struct bnxt_link_info *link_info, ··· 1912 1617 lk_ksettings->link_modes.advertising); 1913 1618 } 1914 1619 1915 - static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info, 1916 - struct ethtool_link_ksettings *lk_ksettings) 1917 - { 1918 - u16 fw_speeds = link_info->advertising; 1919 - u8 fw_pause = 0; 1920 - 1921 - if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) 1922 - fw_pause = link_info->auto_pause_setting; 1923 - 1924 - BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, advertising); 1925 - fw_speeds = link_info->advertising_pam4; 1926 - BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, advertising); 1927 - bnxt_fw_to_ethtool_advertised_fec(link_info, lk_ksettings); 1928 - } 1929 - 1930 - static void bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info, 1931 - struct ethtool_link_ksettings *lk_ksettings) 1932 - { 1933 - u16 fw_speeds = link_info->lp_auto_link_speeds; 1934 - u8 fw_pause = 0; 1935 - 1936 - if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) 1937 - fw_pause = link_info->lp_pause; 1938 - 1939 - BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, 1940 - lp_advertising); 1941 - fw_speeds = link_info->lp_auto_pam4_link_speeds; 1942 - BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, lp_advertising); 1943 - } 1944 - 1945 1620 static void bnxt_fw_to_ethtool_support_fec(struct bnxt_link_info *link_info, 1946 1621 struct ethtool_link_ksettings *lk_ksettings) 1947 1622 { ··· 1931 1666 if (fec_cfg & BNXT_FEC_ENC_LLRS_CAP) 1932 1667 linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, 1933 1668 lk_ksettings->link_modes.supported); 1934 - } 1935 - 1936 - static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info, 1937 - struct ethtool_link_ksettings *lk_ksettings) 1938 - { 1939 - struct bnxt *bp = container_of(link_info, struct bnxt, link_info); 1940 - u16 fw_speeds = link_info->support_speeds; 1941 - 1942 - BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, 0, lk_ksettings, supported); 1943 - fw_speeds = link_info->support_pam4_speeds; 1944 - BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, supported); 1945 - 1946 - if (!(bp->phy_flags & BNXT_PHY_FL_NO_PAUSE)) { 1947 - ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, 1948 - Pause); 1949 - ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, 1950 - Asym_Pause); 1951 - } 1952 - 1953 - if (link_info->support_auto_speeds || 1954 - link_info->support_pam4_auto_speeds) 1955 - ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, 1956 - Autoneg); 1957 - bnxt_fw_to_ethtool_support_fec(link_info, lk_ksettings); 1958 1669 } 1959 1670 1960 1671 u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed) ··· 1961 1720 } 1962 1721 } 1963 1722 1964 - static int bnxt_get_link_ksettings(struct net_device *dev, 1965 - struct ethtool_link_ksettings *lk_ksettings) 1723 + static void bnxt_get_default_speeds(struct ethtool_link_ksettings *lk_ksettings, 1724 + struct bnxt_link_info *link_info) 1966 1725 { 1967 - struct bnxt *bp = netdev_priv(dev); 1968 - struct bnxt_link_info *link_info = &bp->link_info; 1969 1726 struct ethtool_link_settings *base = &lk_ksettings->base; 1970 - u32 ethtool_speed; 1971 1727 1972 - ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported); 1973 - mutex_lock(&bp->link_lock); 1974 - bnxt_fw_to_ethtool_support_spds(link_info, lk_ksettings); 1975 - 1976 - ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising); 1977 - if (link_info->autoneg) { 1978 - bnxt_fw_to_ethtool_advertised_spds(link_info, lk_ksettings); 1979 - ethtool_link_ksettings_add_link_mode(lk_ksettings, 1980 - advertising, Autoneg); 1981 - base->autoneg = AUTONEG_ENABLE; 1982 - base->duplex = DUPLEX_UNKNOWN; 1983 - if (link_info->phy_link_status == BNXT_LINK_LINK) { 1984 - bnxt_fw_to_ethtool_lp_adv(link_info, lk_ksettings); 1985 - if (link_info->duplex & BNXT_LINK_DUPLEX_FULL) 1986 - base->duplex = DUPLEX_FULL; 1987 - else 1988 - base->duplex = DUPLEX_HALF; 1989 - } 1990 - ethtool_speed = bnxt_fw_to_ethtool_speed(link_info->link_speed); 1991 - } else { 1992 - base->autoneg = AUTONEG_DISABLE; 1993 - ethtool_speed = 1994 - bnxt_fw_to_ethtool_speed(link_info->req_link_speed); 1728 + if (link_info->link_state == BNXT_LINK_STATE_UP) { 1729 + base->speed = bnxt_fw_to_ethtool_speed(link_info->link_speed); 1730 + base->duplex = DUPLEX_HALF; 1731 + if (link_info->duplex & BNXT_LINK_DUPLEX_FULL) 1732 + base->duplex = DUPLEX_FULL; 1733 + } else if (!link_info->autoneg) { 1734 + base->speed = bnxt_fw_to_ethtool_speed(link_info->req_link_speed); 1995 1735 base->duplex = DUPLEX_HALF; 1996 1736 if (link_info->req_duplex == BNXT_LINK_DUPLEX_FULL) 1997 1737 base->duplex = DUPLEX_FULL; 1998 1738 } 1999 - base->speed = ethtool_speed; 1739 + } 1740 + 1741 + static int bnxt_get_link_ksettings(struct net_device *dev, 1742 + struct ethtool_link_ksettings *lk_ksettings) 1743 + { 1744 + struct ethtool_link_settings *base = &lk_ksettings->base; 1745 + enum ethtool_link_mode_bit_indices link_mode; 1746 + struct bnxt *bp = netdev_priv(dev); 1747 + struct bnxt_link_info *link_info; 1748 + enum bnxt_media_type media; 1749 + 1750 + ethtool_link_ksettings_zero_link_mode(lk_ksettings, lp_advertising); 1751 + ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising); 1752 + ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported); 1753 + base->duplex = DUPLEX_UNKNOWN; 1754 + base->speed = SPEED_UNKNOWN; 1755 + link_info = &bp->link_info; 1756 + 1757 + mutex_lock(&bp->link_lock); 1758 + bnxt_get_ethtool_modes(link_info, lk_ksettings); 1759 + media = bnxt_get_media(link_info); 1760 + bnxt_get_ethtool_speeds(link_info->support_speeds, 1761 + media, BNXT_SIG_MODE_NRZ, 1762 + lk_ksettings->link_modes.supported); 1763 + bnxt_get_ethtool_speeds(link_info->support_pam4_speeds, 1764 + media, BNXT_SIG_MODE_PAM4, 1765 + lk_ksettings->link_modes.supported); 1766 + bnxt_fw_to_ethtool_support_fec(link_info, lk_ksettings); 1767 + link_mode = bnxt_get_link_mode(link_info); 1768 + if (link_mode != BNXT_LINK_MODE_UNKNOWN) 1769 + ethtool_params_from_link_mode(lk_ksettings, link_mode); 1770 + else 1771 + bnxt_get_default_speeds(lk_ksettings, link_info); 1772 + 1773 + if (link_info->autoneg) { 1774 + bnxt_fw_to_ethtool_advertised_fec(link_info, lk_ksettings); 1775 + linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 1776 + lk_ksettings->link_modes.advertising); 1777 + base->autoneg = AUTONEG_ENABLE; 1778 + bnxt_get_ethtool_speeds(link_info->advertising, 1779 + media, BNXT_SIG_MODE_NRZ, 1780 + lk_ksettings->link_modes.advertising); 1781 + bnxt_get_ethtool_speeds(link_info->advertising_pam4, 1782 + media, BNXT_SIG_MODE_PAM4, 1783 + lk_ksettings->link_modes.advertising); 1784 + if (link_info->phy_link_status == BNXT_LINK_LINK) { 1785 + bnxt_get_ethtool_speeds(link_info->lp_auto_link_speeds, 1786 + media, BNXT_SIG_MODE_NRZ, 1787 + lk_ksettings->link_modes.lp_advertising); 1788 + bnxt_get_ethtool_speeds(link_info->lp_auto_pam4_link_speeds, 1789 + media, BNXT_SIG_MODE_PAM4, 1790 + lk_ksettings->link_modes.lp_advertising); 1791 + } 1792 + } else { 1793 + base->autoneg = AUTONEG_DISABLE; 1794 + } 2000 1795 2001 1796 base->port = PORT_NONE; 2002 1797 if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) { 2003 1798 base->port = PORT_TP; 2004 - ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, 2005 - TP); 2006 - ethtool_link_ksettings_add_link_mode(lk_ksettings, advertising, 2007 - TP); 1799 + linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, 1800 + lk_ksettings->link_modes.supported); 1801 + linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, 1802 + lk_ksettings->link_modes.advertising); 2008 1803 } else { 2009 - ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, 2010 - FIBRE); 2011 - ethtool_link_ksettings_add_link_mode(lk_ksettings, advertising, 2012 - FIBRE); 1804 + linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 1805 + lk_ksettings->link_modes.supported); 1806 + linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 1807 + lk_ksettings->link_modes.advertising); 2013 1808 2014 1809 if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC) 2015 1810 base->port = PORT_DA; 2016 - else if (link_info->media_type == 2017 - PORT_PHY_QCFG_RESP_MEDIA_TYPE_FIBRE) 1811 + else 2018 1812 base->port = PORT_FIBRE; 2019 1813 } 2020 1814 base->phy_address = link_info->phy_addr; ··· 2058 1782 return 0; 2059 1783 } 2060 1784 2061 - static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed) 1785 + static int 1786 + bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed, u32 lanes) 2062 1787 { 2063 1788 struct bnxt *bp = netdev_priv(dev); 2064 1789 struct bnxt_link_info *link_info = &bp->link_info; 2065 1790 u16 support_pam4_spds = link_info->support_pam4_speeds; 2066 1791 u16 support_spds = link_info->support_speeds; 2067 1792 u8 sig_mode = BNXT_SIG_MODE_NRZ; 1793 + u32 lanes_needed = 1; 2068 1794 u16 fw_speed = 0; 2069 1795 2070 1796 switch (ethtool_speed) { ··· 2087 1809 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_10GB; 2088 1810 break; 2089 1811 case SPEED_20000: 2090 - if (support_spds & BNXT_LINK_SPEED_MSK_20GB) 1812 + if (support_spds & BNXT_LINK_SPEED_MSK_20GB) { 2091 1813 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_20GB; 1814 + lanes_needed = 2; 1815 + } 2092 1816 break; 2093 1817 case SPEED_25000: 2094 1818 if (support_spds & BNXT_LINK_SPEED_MSK_25GB) 2095 1819 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_25GB; 2096 1820 break; 2097 1821 case SPEED_40000: 2098 - if (support_spds & BNXT_LINK_SPEED_MSK_40GB) 1822 + if (support_spds & BNXT_LINK_SPEED_MSK_40GB) { 2099 1823 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_40GB; 1824 + lanes_needed = 4; 1825 + } 2100 1826 break; 2101 1827 case SPEED_50000: 2102 - if (support_spds & BNXT_LINK_SPEED_MSK_50GB) { 1828 + if ((support_spds & BNXT_LINK_SPEED_MSK_50GB) && lanes != 1) { 2103 1829 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_50GB; 1830 + lanes_needed = 2; 2104 1831 } else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_50GB) { 2105 1832 fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_50GB; 2106 1833 sig_mode = BNXT_SIG_MODE_PAM4; 2107 1834 } 2108 1835 break; 2109 1836 case SPEED_100000: 2110 - if (support_spds & BNXT_LINK_SPEED_MSK_100GB) { 1837 + if ((support_spds & BNXT_LINK_SPEED_MSK_100GB) && 1838 + lanes != 2 && lanes != 1) { 2111 1839 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB; 1840 + lanes_needed = 4; 2112 1841 } else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_100GB) { 2113 1842 fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_100GB; 2114 1843 sig_mode = BNXT_SIG_MODE_PAM4; 1844 + lanes_needed = 2; 2115 1845 } 2116 1846 break; 2117 1847 case SPEED_200000: 2118 1848 if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_200GB) { 2119 1849 fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_200GB; 2120 1850 sig_mode = BNXT_SIG_MODE_PAM4; 1851 + lanes_needed = 4; 2121 1852 } 2122 1853 break; 2123 1854 } 2124 1855 2125 1856 if (!fw_speed) { 2126 1857 netdev_err(dev, "unsupported speed!\n"); 1858 + return -EINVAL; 1859 + } 1860 + 1861 + if (lanes && lanes != lanes_needed) { 1862 + netdev_err(dev, "unsupported number of lanes for speed\n"); 2127 1863 return -EINVAL; 2128 1864 } 2129 1865 ··· 2185 1893 struct bnxt_link_info *link_info = &bp->link_info; 2186 1894 const struct ethtool_link_settings *base = &lk_ksettings->base; 2187 1895 bool set_pause = false; 2188 - u32 speed; 1896 + u32 speed, lanes = 0; 2189 1897 int rc = 0; 2190 1898 2191 1899 if (!BNXT_PHY_CFG_ABLE(bp)) ··· 2193 1901 2194 1902 mutex_lock(&bp->link_lock); 2195 1903 if (base->autoneg == AUTONEG_ENABLE) { 2196 - link_info->advertising = 0; 2197 - link_info->advertising_pam4 = 0; 2198 - BNXT_ETHTOOL_TO_FW_SPDS(link_info->advertising, lk_ksettings, 2199 - advertising); 2200 - BNXT_ETHTOOL_TO_FW_PAM4_SPDS(link_info->advertising_pam4, 2201 - lk_ksettings, advertising); 1904 + bnxt_set_ethtool_speeds(link_info, 1905 + lk_ksettings->link_modes.advertising); 2202 1906 link_info->autoneg |= BNXT_AUTONEG_SPEED; 2203 1907 if (!link_info->advertising && !link_info->advertising_pam4) { 2204 1908 link_info->advertising = link_info->support_auto_speeds; ··· 2222 1934 goto set_setting_exit; 2223 1935 } 2224 1936 speed = base->speed; 2225 - rc = bnxt_force_link_speed(dev, speed); 1937 + lanes = lk_ksettings->lanes; 1938 + rc = bnxt_force_link_speed(dev, speed, lanes); 2226 1939 if (rc) { 2227 1940 if (rc == -EALREADY) 2228 1941 rc = 0; ··· 4429 4140 } 4430 4141 4431 4142 const struct ethtool_ops bnxt_ethtool_ops = { 4143 + .cap_link_lanes_supported = 1, 4432 4144 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 4433 4145 ETHTOOL_COALESCE_MAX_FRAMES | 4434 4146 ETHTOOL_COALESCE_USECS_IRQ |
+2 -2
drivers/net/ethernet/broadcom/bnxt/bnxt_hwmon.c
··· 18 18 #include "bnxt_hwrm.h" 19 19 #include "bnxt_hwmon.h" 20 20 21 - void bnxt_hwmon_notify_event(struct bnxt *bp, u32 type) 21 + void bnxt_hwmon_notify_event(struct bnxt *bp) 22 22 { 23 23 u32 attr; 24 24 25 25 if (!bp->hwmon_dev) 26 26 return; 27 27 28 - switch (type) { 28 + switch (bp->thermal_threshold_type) { 29 29 case ASYNC_EVENT_CMPL_ERROR_REPORT_THERMAL_EVENT_DATA1_THRESHOLD_TYPE_WARN: 30 30 attr = hwmon_temp_max_alarm; 31 31 break;
+2 -2
drivers/net/ethernet/broadcom/bnxt/bnxt_hwmon.h
··· 11 11 #define BNXT_HWMON_H 12 12 13 13 #ifdef CONFIG_BNXT_HWMON 14 - void bnxt_hwmon_notify_event(struct bnxt *bp, u32 type); 14 + void bnxt_hwmon_notify_event(struct bnxt *bp); 15 15 void bnxt_hwmon_uninit(struct bnxt *bp); 16 16 void bnxt_hwmon_init(struct bnxt *bp); 17 17 #else 18 - static inline void bnxt_hwmon_notify_event(struct bnxt *bp, u32 type) 18 + static inline void bnxt_hwmon_notify_event(struct bnxt *bp) 19 19 { 20 20 } 21 21