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

ice: Add code to control FW LLDP and DCBX

This patch adds code to start or stop LLDP and DCBX in firmware through
use of ethtool private flags.

Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Anirudh Venkataramanan and committed by
Jeff Kirsher
3a257a14 b832c2f6

+159 -2
+2
drivers/net/ethernet/intel/ice/ice.h
··· 325 325 ICE_FLAG_DCB_CAPABLE, 326 326 ICE_FLAG_DCB_ENA, 327 327 ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, 328 + ICE_FLAG_DISABLE_FW_LLDP, 329 + ICE_FLAG_ETHTOOL_CTXT, /* set when ethtool holds RTNL lock */ 328 330 ICE_PF_FLAGS_NBITS /* must be last */ 329 331 }; 330 332
+12
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
··· 1200 1200 u8 reserved[15]; 1201 1201 }; 1202 1202 1203 + /* Stop LLDP (direct 0x0A05) */ 1204 + struct ice_aqc_lldp_stop { 1205 + u8 command; 1206 + #define ICE_AQ_LLDP_AGENT_STATE_MASK BIT(0) 1207 + #define ICE_AQ_LLDP_AGENT_STOP 0x0 1208 + #define ICE_AQ_LLDP_AGENT_SHUTDOWN ICE_AQ_LLDP_AGENT_STATE_MASK 1209 + #define ICE_AQ_LLDP_AGENT_PERSIST_DIS BIT(1) 1210 + u8 reserved[15]; 1211 + }; 1212 + 1203 1213 /* Start LLDP (direct 0x0A06) */ 1204 1214 struct ice_aqc_lldp_start { 1205 1215 u8 command; ··· 1539 1529 struct ice_aqc_pf_vf_msg virt; 1540 1530 struct ice_aqc_lldp_get_mib lldp_get_mib; 1541 1531 struct ice_aqc_lldp_set_mib_change lldp_set_event; 1532 + struct ice_aqc_lldp_stop lldp_stop; 1542 1533 struct ice_aqc_lldp_start lldp_start; 1543 1534 struct ice_aqc_lldp_set_local_mib lldp_set_mib; 1544 1535 struct ice_aqc_lldp_stop_start_specific_agent lldp_agent_ctrl; ··· 1650 1639 /* LLDP commands */ 1651 1640 ice_aqc_opc_lldp_get_mib = 0x0A00, 1652 1641 ice_aqc_opc_lldp_set_mib_change = 0x0A01, 1642 + ice_aqc_opc_lldp_stop = 0x0A05, 1653 1643 ice_aqc_opc_lldp_start = 0x0A06, 1654 1644 ice_aqc_opc_get_cee_dcb_cfg = 0x0A07, 1655 1645 ice_aqc_opc_lldp_set_local_mib = 0x0A08,
+27 -1
drivers/net/ethernet/intel/ice/ice_dcb.c
··· 60 60 * Enable or Disable posting of an event on ARQ when LLDP MIB 61 61 * associated with the interface changes (0x0A01) 62 62 */ 63 - static enum ice_status 63 + enum ice_status 64 64 ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update, 65 65 struct ice_sq_cd *cd) 66 66 { ··· 73 73 74 74 if (!ena_update) 75 75 cmd->command |= ICE_AQ_LLDP_MIB_UPDATE_DIS; 76 + 77 + return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 78 + } 79 + 80 + /** 81 + * ice_aq_stop_lldp 82 + * @hw: pointer to the HW struct 83 + * @shutdown_lldp_agent: True if LLDP Agent needs to be Shutdown 84 + * False if LLDP Agent needs to be Stopped 85 + * @cd: pointer to command details structure or NULL 86 + * 87 + * Stop or Shutdown the embedded LLDP Agent (0x0A05) 88 + */ 89 + enum ice_status 90 + ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, 91 + struct ice_sq_cd *cd) 92 + { 93 + struct ice_aqc_lldp_stop *cmd; 94 + struct ice_aq_desc desc; 95 + 96 + cmd = &desc.params.lldp_stop; 97 + 98 + ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_stop); 99 + 100 + if (shutdown_lldp_agent) 101 + cmd->command |= ICE_AQ_LLDP_AGENT_SHUTDOWN; 76 102 77 103 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 78 104 }
+23
drivers/net/ethernet/intel/ice/ice_dcb.h
··· 130 130 struct ice_aqc_port_ets_elem *buf, u16 buf_size, 131 131 struct ice_sq_cd *cmd_details); 132 132 #ifdef CONFIG_DCB 133 + enum ice_status 134 + ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, 135 + struct ice_sq_cd *cd); 133 136 enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd); 134 137 enum ice_status 135 138 ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent, 136 139 bool *dcbx_agent_status, struct ice_sq_cd *cd); 140 + enum ice_status 141 + ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update, 142 + struct ice_sq_cd *cd); 137 143 #else /* CONFIG_DCB */ 144 + static inline enum ice_status 145 + ice_aq_stop_lldp(struct ice_hw __always_unused *hw, 146 + bool __always_unused shutdown_lldp_agent, 147 + struct ice_sq_cd __always_unused *cd) 148 + { 149 + return 0; 150 + } 151 + 138 152 static inline enum ice_status 139 153 ice_aq_start_lldp(struct ice_hw __always_unused *hw, 140 154 struct ice_sq_cd __always_unused *cd) ··· 166 152 167 153 return 0; 168 154 } 155 + 156 + static inline enum ice_status 157 + ice_aq_cfg_lldp_mib_change(struct ice_hw __always_unused *hw, 158 + bool __always_unused ena_update, 159 + struct ice_sq_cd __always_unused *cd) 160 + { 161 + return 0; 162 + } 163 + 169 164 #endif /* CONFIG_DCB */ 170 165 #endif /* _ICE_DCB_H_ */
+95 -1
drivers/net/ethernet/intel/ice/ice_ethtool.c
··· 4 4 /* ethtool support for ice */ 5 5 6 6 #include "ice.h" 7 + #include "ice_lib.h" 8 + #include "ice_dcb_lib.h" 7 9 8 10 struct ice_stats { 9 11 char stat_string[ETH_GSTRING_LEN]; ··· 134 132 135 133 static const struct ice_priv_flag ice_gstrings_priv_flags[] = { 136 134 ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA), 135 + ICE_PRIV_FLAG("disable-fw-lldp", ICE_FLAG_DISABLE_FW_LLDP), 137 136 }; 138 137 139 138 #define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags) ··· 407 404 static int ice_set_priv_flags(struct net_device *netdev, u32 flags) 408 405 { 409 406 struct ice_netdev_priv *np = netdev_priv(netdev); 407 + DECLARE_BITMAP(change_flags, ICE_PF_FLAGS_NBITS); 408 + DECLARE_BITMAP(orig_flags, ICE_PF_FLAGS_NBITS); 410 409 struct ice_vsi *vsi = np->vsi; 411 410 struct ice_pf *pf = vsi->back; 411 + int ret = 0; 412 412 u32 i; 413 413 414 414 if (flags > BIT(ICE_PRIV_FLAG_ARRAY_SIZE)) 415 415 return -EINVAL; 416 416 417 + set_bit(ICE_FLAG_ETHTOOL_CTXT, pf->flags); 418 + 419 + bitmap_copy(orig_flags, pf->flags, ICE_PF_FLAGS_NBITS); 417 420 for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) { 418 421 const struct ice_priv_flag *priv_flag; 419 422 ··· 431 422 clear_bit(priv_flag->bitno, pf->flags); 432 423 } 433 424 434 - return 0; 425 + bitmap_xor(change_flags, pf->flags, orig_flags, ICE_PF_FLAGS_NBITS); 426 + 427 + if (test_bit(ICE_FLAG_DISABLE_FW_LLDP, change_flags)) { 428 + if (test_bit(ICE_FLAG_DISABLE_FW_LLDP, pf->flags)) { 429 + enum ice_status status; 430 + 431 + status = ice_aq_cfg_lldp_mib_change(&pf->hw, false, 432 + NULL); 433 + /* If unregistering for LLDP events fails, this is 434 + * not an error state, as there shouldn't be any 435 + * events to respond to. 436 + */ 437 + if (status) 438 + dev_info(&pf->pdev->dev, 439 + "Failed to unreg for LLDP events\n"); 440 + 441 + /* The AQ call to stop the FW LLDP agent will generate 442 + * an error if the agent is already stopped. 443 + */ 444 + status = ice_aq_stop_lldp(&pf->hw, true, NULL); 445 + if (status) 446 + dev_warn(&pf->pdev->dev, 447 + "Fail to stop LLDP agent\n"); 448 + /* Use case for having the FW LLDP agent stopped 449 + * will likely not need DCB, so failure to init is 450 + * not a concern of ethtool 451 + */ 452 + status = ice_init_pf_dcb(pf); 453 + if (status) 454 + dev_warn(&pf->pdev->dev, "Fail to init DCB\n"); 455 + } else { 456 + enum ice_status status; 457 + bool dcbx_agent_status; 458 + 459 + /* AQ command to start FW LLDP agent will return an 460 + * error if the agent is already started 461 + */ 462 + status = ice_aq_start_lldp(&pf->hw, NULL); 463 + if (status) 464 + dev_warn(&pf->pdev->dev, 465 + "Fail to start LLDP Agent\n"); 466 + 467 + /* AQ command to start FW DCBx agent will fail if 468 + * the agent is already started 469 + */ 470 + status = ice_aq_start_stop_dcbx(&pf->hw, true, 471 + &dcbx_agent_status, 472 + NULL); 473 + if (status) 474 + dev_dbg(&pf->pdev->dev, 475 + "Failed to start FW DCBX\n"); 476 + 477 + dev_info(&pf->pdev->dev, "FW DCBX agent is %s\n", 478 + dcbx_agent_status ? "ACTIVE" : "DISABLED"); 479 + 480 + /* Failure to configure MIB change or init DCB is not 481 + * relevant to ethtool. Print notification that 482 + * registration/init failed but do not return error 483 + * state to ethtool 484 + */ 485 + status = ice_aq_cfg_lldp_mib_change(&pf->hw, false, 486 + NULL); 487 + if (status) 488 + dev_dbg(&pf->pdev->dev, 489 + "Fail to reg for MIB change\n"); 490 + 491 + status = ice_init_pf_dcb(pf); 492 + if (status) 493 + dev_dbg(&pf->pdev->dev, "Fail to init DCB\n"); 494 + } 495 + } 496 + clear_bit(ICE_FLAG_ETHTOOL_CTXT, pf->flags); 497 + return ret; 435 498 } 436 499 437 500 static int ice_get_sset_count(struct net_device *netdev, int sset) ··· 1935 1854 struct ice_port_info *pi = np->vsi->port_info; 1936 1855 struct ice_aqc_get_phy_caps_data *pcaps; 1937 1856 struct ice_vsi *vsi = np->vsi; 1857 + struct ice_dcbx_cfg *dcbx_cfg; 1938 1858 enum ice_status status; 1939 1859 1940 1860 /* Initialize pause params */ 1941 1861 pause->rx_pause = 0; 1942 1862 pause->tx_pause = 0; 1863 + 1864 + dcbx_cfg = &pi->local_dcbx_cfg; 1943 1865 1944 1866 pcaps = devm_kzalloc(&vsi->back->pdev->dev, sizeof(*pcaps), 1945 1867 GFP_KERNEL); ··· 1957 1873 1958 1874 pause->autoneg = ((pcaps->caps & ICE_AQC_PHY_AN_MODE) ? 1959 1875 AUTONEG_ENABLE : AUTONEG_DISABLE); 1876 + 1877 + if (dcbx_cfg->pfc.pfcena) 1878 + /* PFC enabled so report LFC as off */ 1879 + goto out; 1960 1880 1961 1881 if (pcaps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE) 1962 1882 pause->tx_pause = 1; ··· 1982 1894 struct ice_netdev_priv *np = netdev_priv(netdev); 1983 1895 struct ice_link_status *hw_link_info; 1984 1896 struct ice_pf *pf = np->vsi->back; 1897 + struct ice_dcbx_cfg *dcbx_cfg; 1985 1898 struct ice_vsi *vsi = np->vsi; 1986 1899 struct ice_hw *hw = &pf->hw; 1987 1900 struct ice_port_info *pi; ··· 1993 1904 1994 1905 pi = vsi->port_info; 1995 1906 hw_link_info = &pi->phy.link_info; 1907 + dcbx_cfg = &pi->local_dcbx_cfg; 1996 1908 link_up = hw_link_info->link_info & ICE_AQ_LINK_UP; 1997 1909 1998 1910 /* Changing the port's flow control is not supported if this isn't the ··· 2016 1926 netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n"); 2017 1927 } 2018 1928 1929 + if (dcbx_cfg->pfc.pfcena) { 1930 + netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n"); 1931 + return -EOPNOTSUPP; 1932 + } 2019 1933 if (pause->rx_pause && pause->tx_pause) 2020 1934 pi->fc.req_mode = ICE_FC_FULL; 2021 1935 else if (pause->rx_pause && !pause->tx_pause)