/** * ice_dcbnl_getnumtcs - Get max number of traffic classes supported * @dev: pointer to netdev struct * @tcid: TC ID * @num: total number of TCs supported by the adapter * * Return the total number of TCs supported
*/ staticint
ice_dcbnl_getnumtcs(struct net_device *dev, int __always_unused tcid, u8 *num)
{ struct ice_pf *pf = ice_netdev_to_pf(dev);
if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)) return -EINVAL;
/* Return enabled if any UP enabled for PFC */ if (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena) return 1;
return 0;
}
/** * ice_dcbnl_getstate - get DCB enabled state * @netdev: pointer to netdev struct
*/ static u8 ice_dcbnl_getstate(struct net_device *netdev)
{ struct ice_pf *pf = ice_netdev_to_pf(netdev);
u8 state = 0;
state = test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags);
dev_dbg(ice_pf_to_dev(pf), "DCB enabled state = %d\n", state); return state;
}
/** * ice_dcbnl_setstate - Set CEE DCB state * @netdev: pointer to relevant netdev * @state: state value to set
*/ static u8 ice_dcbnl_setstate(struct net_device *netdev, u8 state)
{ struct ice_pf *pf = ice_netdev_to_pf(netdev);
if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return ICE_DCB_NO_HW_CHG;
if (pf->lag && pf->lag->bonded) {
netdev_err(netdev, "DCB changes not allowed when in a bond\n"); return ICE_DCB_NO_HW_CHG;
}
/* Nothing to do */ if (!!state == test_bit(ICE_FLAG_DCB_ENA, pf->flags)) return ICE_DCB_NO_HW_CHG;
/** * ice_dcbnl_set_pg_tc_cfg_tx - set CEE PG Tx config * @netdev: pointer to relevant netdev * @tc: the corresponding traffic class * @prio_type: the traffic priority type * @bwg_id: the BW group ID the TC belongs to * @bw_pct: the BW perventage for the BWG * @up_map: prio mapped to corresponding TC
*/ staticvoid
ice_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
u8 __always_unused prio_type,
u8 __always_unused bwg_id,
u8 __always_unused bw_pct, u8 up_map)
{ struct ice_pf *pf = ice_netdev_to_pf(netdev); struct ice_dcbx_cfg *new_cfg; int i;
if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return;
if (tc >= ICE_MAX_TRAFFIC_CLASS) return;
if (pf->lag && pf->lag->bonded) {
netdev_err(netdev, "DCB changes not allowed when in a bond\n"); return;
}
/** * ice_dcbnl_getapp - get CEE APP * @netdev: pointer to netdev struct * @idtype: the App selector * @id: the App ethtype or port number
*/ staticint ice_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
{ struct ice_pf *pf = ice_netdev_to_pf(netdev); struct dcb_app app = {
.selector = idtype,
.protocol = id,
};
if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return -EINVAL;
return dcb_getapp(netdev, &app);
}
/** * ice_dcbnl_find_app - Search for APP in given DCB config * @cfg: struct to hold DCBX config * @app: struct to hold app data to look for
*/ staticbool
ice_dcbnl_find_app(struct ice_dcbx_cfg *cfg, struct ice_dcb_app_priority_table *app)
{ unsignedint i;
for (i = 0; i < cfg->numapps; i++) { if (app->selector == cfg->app[i].selector &&
app->prot_id == cfg->app[i].prot_id &&
app->priority == cfg->app[i].priority) returntrue;
}
returnfalse;
}
#define ICE_BYTES_PER_DSCP_VAL 8
/** * ice_dcbnl_setapp - set local IEEE App config * @netdev: relevant netdev struct * @app: struct to hold app config info
*/ staticint ice_dcbnl_setapp(struct net_device *netdev, struct dcb_app *app)
{ struct ice_pf *pf = ice_netdev_to_pf(netdev); struct ice_dcb_app_priority_table new_app; struct ice_dcbx_cfg *old_cfg, *new_cfg;
u8 max_tc; int ret;
/* ONLY DSCP APP TLVs have operational significance */ if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP) return -EINVAL;
/* only allow APP TLVs in SW Mode */ if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
netdev_err(netdev, "can't do DSCP QoS when FW DCB agent active\n"); return -EINVAL;
}
if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) return -EINVAL;
if (!ice_is_feature_supported(pf, ICE_F_DSCP)) return -EOPNOTSUPP;
if (app->protocol >= DSCP_MAX) {
netdev_err(netdev, "DSCP value 0x%04X out of range\n",
app->protocol); return -EINVAL;
}
if (pf->lag && pf->lag->bonded) {
netdev_err(netdev, "DCB changes not allowed when in a bond\n"); return -EINVAL;
}
max_tc = pf->hw.func_caps.common_cap.maxtc; if (app->priority >= max_tc) {
netdev_err(netdev, "TC %d out of range, max TC %d\n",
app->priority, max_tc); return -EINVAL;
}
ret = dcb_ieee_setapp(netdev, app); if (ret) goto setapp_out;
if (test_and_set_bit(app->protocol, new_cfg->dscp_mapped)) {
netdev_err(netdev, "DSCP value 0x%04X already user mapped\n",
app->protocol);
ret = dcb_ieee_delapp(netdev, app); if (ret)
netdev_err(netdev, "Failed to delete re-mapping TLV\n");
ret = -EINVAL; goto setapp_out;
}
for (i = 1; i < max_tc; i++) {
new_cfg->etscfg.tcbwtable[i] = 0;
new_cfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS;
new_cfg->etscfg.prio_table[i] = i;
}
} /* end of switching to DSCP mode */
/* apply new mapping for this DSCP value */
new_cfg->dscp_map[app->protocol] = app->priority;
new_cfg->app[new_cfg->numapps++] = new_app;
ret = ice_pf_dcb_cfg(pf, new_cfg, true); /* return of zero indicates new cfg applied */ if (ret == ICE_DCB_HW_CHG_RST)
ice_dcbnl_devreset(netdev); else
ret = ICE_DCB_NO_HW_CHG;
/** * ice_dcbnl_delapp - Delete local IEEE App config * @netdev: relevant netdev * @app: struct to hold app too delete * * Will not delete first application required by the FW
*/ staticint ice_dcbnl_delapp(struct net_device *netdev, struct dcb_app *app)
{ struct ice_pf *pf = ice_netdev_to_pf(netdev); struct ice_dcbx_cfg *old_cfg, *new_cfg; unsignedint i, j; int ret = 0;
if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
netdev_err(netdev, "can't delete DSCP netlink app when FW DCB agent is active\n"); return -EINVAL;
}
if (pf->lag && pf->lag->bonded) {
netdev_err(netdev, "DCB changes not allowed when in a bond\n"); return -EINVAL;
}
/* if not a DSCP APP TLV or DSCP is not supported, we are done */ if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP ||
!ice_is_feature_supported(pf, ICE_F_DSCP)) {
ret = ICE_DCB_HW_CHG; goto delapp_out;
}
/* if DSCP TLV, then need to address change in mapping */
clear_bit(app->protocol, new_cfg->dscp_mapped); /* remap this DSCP value to default value */
new_cfg->dscp_map[app->protocol] = app->protocol %
ICE_BYTES_PER_DSCP_VAL;
/* if the last DSCP mapping just got deleted, need to switch * to L2 VLAN QoS mode
*/ if (bitmap_empty(new_cfg->dscp_mapped, DSCP_MAX) &&
new_cfg->pfc_mode == ICE_QOS_MODE_DSCP) {
ret = ice_aq_set_pfc_mode(&pf->hw,
ICE_AQC_PFC_VLAN_BASED_PFC,
NULL); if (ret) {
netdev_info(netdev, "Failed to set VLAN PFC mode %d\n",
ret); goto delapp_out;
}
netdev_info(netdev, "Switched QoS to L2 VLAN mode\n");
new_cfg->pfc_mode = ICE_QOS_MODE_VLAN;
ret = ice_dcb_sw_dflt_cfg(pf, true, true);
} else {
ret = ice_pf_dcb_cfg(pf, new_cfg, true);
}
/* return of ICE_DCB_HW_CHG_RST indicates new cfg applied * and reset needs to be performed
*/ if (ret == ICE_DCB_HW_CHG_RST)
ice_dcbnl_devreset(netdev);
/* if the change was not siginificant enough to actually call * the reconfiguration flow, we still need to tell caller that * their request was successfully handled
*/ if (ret == ICE_DCB_NO_HW_CHG)
ret = ICE_DCB_HW_CHG;
/* Add APP only if the TC is enabled for this VSI */ if (tc_map & vsi->tc_cfg.ena_tc) {
sapp.selector = dcbxcfg->app[i].selector;
sapp.protocol = dcbxcfg->app[i].prot_id;
sapp.priority = prio;
dcb_ieee_setapp(netdev, &sapp);
}
} /* Notify user-space of the changes */
dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0);
}
/** * ice_dcbnl_vsi_del_app - Delete APP on all VSIs * @vsi: pointer to the main VSI * @app: APP to delete * * Delete given APP from all the VSIs for given PF
*/ staticvoid
ice_dcbnl_vsi_del_app(struct ice_vsi *vsi, struct ice_dcb_app_priority_table *app)
{ struct dcb_app sapp; int err;
/** * ice_dcbnl_flush_apps - Delete all removed APPs * @pf: the corresponding PF * @old_cfg: old DCBX configuration data * @new_cfg: new DCBX configuration data * * Find and delete all APPS that are not present in the passed * DCB configuration
*/ void
ice_dcbnl_flush_apps(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg, struct ice_dcbx_cfg *new_cfg)
{ struct ice_vsi *main_vsi = ice_get_main_vsi(pf); unsignedint i;
if (!main_vsi) return;
for (i = 0; i < old_cfg->numapps; i++) { struct ice_dcb_app_priority_table app = old_cfg->app[i];
/* The APP is not available anymore delete it */ if (!ice_dcbnl_find_app(new_cfg, &app))
ice_dcbnl_vsi_del_app(main_vsi, &app);
}
}
/** * ice_dcbnl_setup - setup DCBNL * @vsi: VSI to get associated netdev from
*/ void ice_dcbnl_setup(struct ice_vsi *vsi)
{ struct net_device *netdev = vsi->netdev; struct ice_pf *pf;
pf = ice_netdev_to_pf(netdev); if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.