mirror of https://gitee.com/openkylin/linux.git
ice: handle DCBx non-contiguous TC request
If DCBx request non-contiguous TCs, then the driver will configure default traffic class (TC0). This is done to prevent Tx hang since the driver currently does not support non-contiguous TC. Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
031f214752
commit
cfbf13674b
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "ice_dcb_lib.h"
|
#include "ice_dcb_lib.h"
|
||||||
|
|
||||||
|
static void ice_pf_dcb_recfg(struct ice_pf *pf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vsi_cfg_netdev_tc - Setup the netdev TC configuration
|
* ice_vsi_cfg_netdev_tc - Setup the netdev TC configuration
|
||||||
* @vsi: the VSI being configured
|
* @vsi: the VSI being configured
|
||||||
|
@ -137,42 +139,6 @@ void ice_vsi_cfg_dcb_rings(struct ice_vsi *vsi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ice_pf_dcb_recfg - Reconfigure all VEBs and VSIs
|
|
||||||
* @pf: pointer to the PF struct
|
|
||||||
*
|
|
||||||
* Assumed caller has already disabled all VSIs before
|
|
||||||
* calling this function. Reconfiguring DCB based on
|
|
||||||
* local_dcbx_cfg.
|
|
||||||
*/
|
|
||||||
static void ice_pf_dcb_recfg(struct ice_pf *pf)
|
|
||||||
{
|
|
||||||
struct ice_dcbx_cfg *dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
|
|
||||||
u8 tc_map = 0;
|
|
||||||
int v, ret;
|
|
||||||
|
|
||||||
/* Update each VSI */
|
|
||||||
ice_for_each_vsi(pf, v) {
|
|
||||||
if (!pf->vsi[v])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (pf->vsi[v]->type == ICE_VSI_PF)
|
|
||||||
tc_map = ice_dcb_get_ena_tc(dcbcfg);
|
|
||||||
else
|
|
||||||
tc_map = ICE_DFLT_TRAFFIC_CLASS;
|
|
||||||
|
|
||||||
ret = ice_vsi_cfg_tc(pf->vsi[v], tc_map);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(&pf->pdev->dev,
|
|
||||||
"Failed to config TC for VSI index: %d\n",
|
|
||||||
pf->vsi[v]->idx);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ice_vsi_map_rings_to_vectors(pf->vsi[v]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_pf_dcb_cfg - Apply new DCB configuration
|
* ice_pf_dcb_cfg - Apply new DCB configuration
|
||||||
* @pf: pointer to the PF struct
|
* @pf: pointer to the PF struct
|
||||||
|
@ -437,9 +403,10 @@ static int ice_dcb_init_cfg(struct ice_pf *pf, bool locked)
|
||||||
/**
|
/**
|
||||||
* ice_dcb_sw_default_config - Apply a default DCB config
|
* ice_dcb_sw_default_config - Apply a default DCB config
|
||||||
* @pf: PF to apply config to
|
* @pf: PF to apply config to
|
||||||
|
* @ets_willing: configure ets willing
|
||||||
* @locked: was this function called with RTNL held
|
* @locked: was this function called with RTNL held
|
||||||
*/
|
*/
|
||||||
static int ice_dcb_sw_dflt_cfg(struct ice_pf *pf, bool locked)
|
static int ice_dcb_sw_dflt_cfg(struct ice_pf *pf, bool ets_willing, bool locked)
|
||||||
{
|
{
|
||||||
struct ice_aqc_port_ets_elem buf = { 0 };
|
struct ice_aqc_port_ets_elem buf = { 0 };
|
||||||
struct ice_dcbx_cfg *dcbcfg;
|
struct ice_dcbx_cfg *dcbcfg;
|
||||||
|
@ -454,7 +421,7 @@ static int ice_dcb_sw_dflt_cfg(struct ice_pf *pf, bool locked)
|
||||||
memset(dcbcfg, 0, sizeof(*dcbcfg));
|
memset(dcbcfg, 0, sizeof(*dcbcfg));
|
||||||
memset(&pi->local_dcbx_cfg, 0, sizeof(*dcbcfg));
|
memset(&pi->local_dcbx_cfg, 0, sizeof(*dcbcfg));
|
||||||
|
|
||||||
dcbcfg->etscfg.willing = 1;
|
dcbcfg->etscfg.willing = ets_willing ? 1 : 0;
|
||||||
dcbcfg->etscfg.maxtcs = hw->func_caps.common_cap.maxtc;
|
dcbcfg->etscfg.maxtcs = hw->func_caps.common_cap.maxtc;
|
||||||
dcbcfg->etscfg.tcbwtable[0] = 100;
|
dcbcfg->etscfg.tcbwtable[0] = 100;
|
||||||
dcbcfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
|
dcbcfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
|
||||||
|
@ -479,6 +446,102 @@ static int ice_dcb_sw_dflt_cfg(struct ice_pf *pf, bool locked)
|
||||||
return ice_query_port_ets(pi, &buf, sizeof(buf), NULL);
|
return ice_query_port_ets(pi, &buf, sizeof(buf), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_dcb_tc_contig - Check that TCs are contiguous
|
||||||
|
* @prio_table: pointer to priority table
|
||||||
|
*
|
||||||
|
* Check if TCs begin with TC0 and are contiguous
|
||||||
|
*/
|
||||||
|
static bool ice_dcb_tc_contig(u8 *prio_table)
|
||||||
|
{
|
||||||
|
u8 max_tc = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < CEE_DCBX_MAX_PRIO; i++) {
|
||||||
|
u8 cur_tc = prio_table[i];
|
||||||
|
|
||||||
|
if (cur_tc > max_tc)
|
||||||
|
return false;
|
||||||
|
else if (cur_tc == max_tc)
|
||||||
|
max_tc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_dcb_noncontig_cfg - Configure DCB for non-contiguous TCs
|
||||||
|
* @pf: pointer to the PF struct
|
||||||
|
*
|
||||||
|
* If non-contiguous TCs, then configure SW DCB with TC0 and ETS non-willing
|
||||||
|
*/
|
||||||
|
static int ice_dcb_noncontig_cfg(struct ice_pf *pf)
|
||||||
|
{
|
||||||
|
struct ice_dcbx_cfg *dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Configure SW DCB default with ETS non-willing */
|
||||||
|
ret = ice_dcb_sw_dflt_cfg(pf, false, true);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pf->pdev->dev,
|
||||||
|
"Failed to set local DCB config %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reconfigure with ETS willing so that FW will send LLDP MIB event */
|
||||||
|
dcbcfg->etscfg.willing = 1;
|
||||||
|
ret = ice_set_dcb_cfg(pf->hw.port_info);
|
||||||
|
if (ret)
|
||||||
|
dev_err(&pf->pdev->dev, "Failed to set DCB to unwilling\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_pf_dcb_recfg - Reconfigure all VEBs and VSIs
|
||||||
|
* @pf: pointer to the PF struct
|
||||||
|
*
|
||||||
|
* Assumed caller has already disabled all VSIs before
|
||||||
|
* calling this function. Reconfiguring DCB based on
|
||||||
|
* local_dcbx_cfg.
|
||||||
|
*/
|
||||||
|
static void ice_pf_dcb_recfg(struct ice_pf *pf)
|
||||||
|
{
|
||||||
|
struct ice_dcbx_cfg *dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
|
||||||
|
u8 tc_map = 0;
|
||||||
|
int v, ret;
|
||||||
|
|
||||||
|
/* Update each VSI */
|
||||||
|
ice_for_each_vsi(pf, v) {
|
||||||
|
if (!pf->vsi[v])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pf->vsi[v]->type == ICE_VSI_PF) {
|
||||||
|
tc_map = ice_dcb_get_ena_tc(dcbcfg);
|
||||||
|
|
||||||
|
/* If DCBX request non-contiguous TC, then configure
|
||||||
|
* default TC
|
||||||
|
*/
|
||||||
|
if (!ice_dcb_tc_contig(dcbcfg->etscfg.prio_table)) {
|
||||||
|
tc_map = ICE_DFLT_TRAFFIC_CLASS;
|
||||||
|
ice_dcb_noncontig_cfg(pf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tc_map = ICE_DFLT_TRAFFIC_CLASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ice_vsi_cfg_tc(pf->vsi[v], tc_map);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pf->pdev->dev,
|
||||||
|
"Failed to config TC for VSI index: %d\n",
|
||||||
|
pf->vsi[v]->idx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ice_vsi_map_rings_to_vectors(pf->vsi[v]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_init_pf_dcb - initialize DCB for a PF
|
* ice_init_pf_dcb - initialize DCB for a PF
|
||||||
* @pf: PF to initialize DCB for
|
* @pf: PF to initialize DCB for
|
||||||
|
@ -507,7 +570,7 @@ int ice_init_pf_dcb(struct ice_pf *pf, bool locked)
|
||||||
dev_info(&pf->pdev->dev,
|
dev_info(&pf->pdev->dev,
|
||||||
"FW LLDP is disabled, DCBx/LLDP in SW mode.\n");
|
"FW LLDP is disabled, DCBx/LLDP in SW mode.\n");
|
||||||
clear_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags);
|
clear_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags);
|
||||||
err = ice_dcb_sw_dflt_cfg(pf, locked);
|
err = ice_dcb_sw_dflt_cfg(pf, true, locked);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&pf->pdev->dev,
|
dev_err(&pf->pdev->dev,
|
||||||
"Failed to set local DCB config %d\n", err);
|
"Failed to set local DCB config %d\n", err);
|
||||||
|
|
Loading…
Reference in New Issue