mirror of https://gitee.com/openkylin/linux.git
ice: Refactor the LLDP MIB change event handling
This patch fixes the LLDP MIB change event handling code by removing the workarounds in the current code. Added ice_dcb_need_recfg() to print the DCB configuration changes detected via MIB change event. Signed-off-by: Usha Ketineni <usha.k.ketineni@intel.com> 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>
This commit is contained in:
parent
9ccb062c14
commit
a17a5ff681
|
@ -624,7 +624,8 @@ ice_parse_org_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
|
||||||
*
|
*
|
||||||
* Parse DCB configuration from the LLDPDU
|
* Parse DCB configuration from the LLDPDU
|
||||||
*/
|
*/
|
||||||
enum ice_status ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg)
|
static enum ice_status
|
||||||
|
ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg)
|
||||||
{
|
{
|
||||||
struct ice_lldp_org_tlv *tlv;
|
struct ice_lldp_org_tlv *tlv;
|
||||||
enum ice_status ret = 0;
|
enum ice_status ret = 0;
|
||||||
|
@ -674,7 +675,7 @@ enum ice_status ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg)
|
||||||
*
|
*
|
||||||
* Query DCB configuration from the firmware
|
* Query DCB configuration from the firmware
|
||||||
*/
|
*/
|
||||||
static enum ice_status
|
enum ice_status
|
||||||
ice_aq_get_dcb_cfg(struct ice_hw *hw, u8 mib_type, u8 bridgetype,
|
ice_aq_get_dcb_cfg(struct ice_hw *hw, u8 mib_type, u8 bridgetype,
|
||||||
struct ice_dcbx_cfg *dcbcfg)
|
struct ice_dcbx_cfg *dcbcfg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,7 +120,9 @@ struct ice_cee_app_prio {
|
||||||
u8 prio_map;
|
u8 prio_map;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
enum ice_status ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg);
|
enum ice_status
|
||||||
|
ice_aq_get_dcb_cfg(struct ice_hw *hw, u8 mib_type, u8 bridgetype,
|
||||||
|
struct ice_dcbx_cfg *dcbcfg);
|
||||||
enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi);
|
enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi);
|
||||||
enum ice_status ice_set_dcb_cfg(struct ice_port_info *pi);
|
enum ice_status ice_set_dcb_cfg(struct ice_port_info *pi);
|
||||||
enum ice_status ice_init_dcb(struct ice_hw *hw);
|
enum ice_status ice_init_dcb(struct ice_hw *hw);
|
||||||
|
|
|
@ -501,6 +501,55 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_ring *tx_ring,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_dcb_need_recfg - Check if DCB needs reconfig
|
||||||
|
* @pf: board private structure
|
||||||
|
* @old_cfg: current DCB config
|
||||||
|
* @new_cfg: new DCB config
|
||||||
|
*/
|
||||||
|
static bool ice_dcb_need_recfg(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg,
|
||||||
|
struct ice_dcbx_cfg *new_cfg)
|
||||||
|
{
|
||||||
|
bool need_reconfig = false;
|
||||||
|
|
||||||
|
/* Check if ETS configuration has changed */
|
||||||
|
if (memcmp(&new_cfg->etscfg, &old_cfg->etscfg,
|
||||||
|
sizeof(new_cfg->etscfg))) {
|
||||||
|
/* If Priority Table has changed reconfig is needed */
|
||||||
|
if (memcmp(&new_cfg->etscfg.prio_table,
|
||||||
|
&old_cfg->etscfg.prio_table,
|
||||||
|
sizeof(new_cfg->etscfg.prio_table))) {
|
||||||
|
need_reconfig = true;
|
||||||
|
dev_dbg(&pf->pdev->dev, "ETS UP2TC changed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(&new_cfg->etscfg.tcbwtable,
|
||||||
|
&old_cfg->etscfg.tcbwtable,
|
||||||
|
sizeof(new_cfg->etscfg.tcbwtable)))
|
||||||
|
dev_dbg(&pf->pdev->dev, "ETS TC BW Table changed.\n");
|
||||||
|
|
||||||
|
if (memcmp(&new_cfg->etscfg.tsatable,
|
||||||
|
&old_cfg->etscfg.tsatable,
|
||||||
|
sizeof(new_cfg->etscfg.tsatable)))
|
||||||
|
dev_dbg(&pf->pdev->dev, "ETS TSA Table changed.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if PFC configuration has changed */
|
||||||
|
if (memcmp(&new_cfg->pfc, &old_cfg->pfc, sizeof(new_cfg->pfc))) {
|
||||||
|
need_reconfig = true;
|
||||||
|
dev_dbg(&pf->pdev->dev, "PFC config change detected.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if APP Table has changed */
|
||||||
|
if (memcmp(&new_cfg->app, &old_cfg->app, sizeof(new_cfg->app))) {
|
||||||
|
need_reconfig = true;
|
||||||
|
dev_dbg(&pf->pdev->dev, "APP Table change detected.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_dbg(&pf->pdev->dev, "dcb need_reconfig=%d\n", need_reconfig);
|
||||||
|
return need_reconfig;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_dcb_process_lldp_set_mib_change - Process MIB change
|
* ice_dcb_process_lldp_set_mib_change - Process MIB change
|
||||||
* @pf: ptr to ice_pf
|
* @pf: ptr to ice_pf
|
||||||
|
@ -510,29 +559,95 @@ void
|
||||||
ice_dcb_process_lldp_set_mib_change(struct ice_pf *pf,
|
ice_dcb_process_lldp_set_mib_change(struct ice_pf *pf,
|
||||||
struct ice_rq_event_info *event)
|
struct ice_rq_event_info *event)
|
||||||
{
|
{
|
||||||
if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
|
struct ice_aqc_port_ets_elem buf = { 0 };
|
||||||
struct ice_dcbx_cfg *dcbcfg, *prev_cfg;
|
struct ice_aqc_lldp_get_mib *mib;
|
||||||
int err;
|
struct ice_dcbx_cfg tmp_dcbx_cfg;
|
||||||
|
bool need_reconfig = false;
|
||||||
|
struct ice_port_info *pi;
|
||||||
|
u8 type;
|
||||||
|
int ret;
|
||||||
|
|
||||||
prev_cfg = &pf->hw.port_info->local_dcbx_cfg;
|
/* Not DCB capable or capability disabled */
|
||||||
dcbcfg = devm_kmemdup(&pf->pdev->dev, prev_cfg,
|
if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)))
|
||||||
sizeof(*dcbcfg), GFP_KERNEL);
|
return;
|
||||||
if (!dcbcfg)
|
|
||||||
return;
|
|
||||||
|
|
||||||
err = ice_lldp_to_dcb_cfg(event->msg_buf, dcbcfg);
|
if (pf->dcbx_cap & DCB_CAP_DCBX_HOST) {
|
||||||
if (!err)
|
|
||||||
ice_pf_dcb_cfg(pf, dcbcfg, false);
|
|
||||||
|
|
||||||
devm_kfree(&pf->pdev->dev, dcbcfg);
|
|
||||||
|
|
||||||
/* Get updated DCBx data from firmware */
|
|
||||||
err = ice_get_dcb_cfg(pf->hw.port_info);
|
|
||||||
if (err)
|
|
||||||
dev_err(&pf->pdev->dev,
|
|
||||||
"Failed to get DCB config\n");
|
|
||||||
} else {
|
|
||||||
dev_dbg(&pf->pdev->dev,
|
dev_dbg(&pf->pdev->dev,
|
||||||
"MIB Change Event in HOST mode\n");
|
"MIB Change Event in HOST mode\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pi = pf->hw.port_info;
|
||||||
|
mib = (struct ice_aqc_lldp_get_mib *)&event->desc.params.raw;
|
||||||
|
/* Ignore if event is not for Nearest Bridge */
|
||||||
|
type = ((mib->type >> ICE_AQ_LLDP_BRID_TYPE_S) &
|
||||||
|
ICE_AQ_LLDP_BRID_TYPE_M);
|
||||||
|
dev_dbg(&pf->pdev->dev, "LLDP event MIB bridge type 0x%x\n", type);
|
||||||
|
if (type != ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Check MIB Type and return if event for Remote MIB update */
|
||||||
|
type = mib->type & ICE_AQ_LLDP_MIB_TYPE_M;
|
||||||
|
dev_dbg(&pf->pdev->dev,
|
||||||
|
"LLDP event mib type %s\n", type ? "remote" : "local");
|
||||||
|
if (type == ICE_AQ_LLDP_MIB_REMOTE) {
|
||||||
|
/* Update the remote cached instance and return */
|
||||||
|
ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE,
|
||||||
|
ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID,
|
||||||
|
&pi->remote_dcbx_cfg);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pf->pdev->dev, "Failed to get remote DCB config\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store the old configuration */
|
||||||
|
tmp_dcbx_cfg = pf->hw.port_info->local_dcbx_cfg;
|
||||||
|
|
||||||
|
/* Reset the old DCBx configuration data */
|
||||||
|
memset(&pi->local_dcbx_cfg, 0, sizeof(pi->local_dcbx_cfg));
|
||||||
|
|
||||||
|
/* Get updated DCBx data from firmware */
|
||||||
|
ret = ice_get_dcb_cfg(pf->hw.port_info);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pf->pdev->dev, "Failed to get DCB config\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No change detected in DCBX configs */
|
||||||
|
if (!memcmp(&tmp_dcbx_cfg, &pi->local_dcbx_cfg, sizeof(tmp_dcbx_cfg))) {
|
||||||
|
dev_dbg(&pf->pdev->dev,
|
||||||
|
"No change detected in DCBX configuration.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
need_reconfig = ice_dcb_need_recfg(pf, &tmp_dcbx_cfg,
|
||||||
|
&pi->local_dcbx_cfg);
|
||||||
|
if (!need_reconfig)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Enable DCB tagging only when more than one TC */
|
||||||
|
if (ice_dcb_get_num_tc(&pi->local_dcbx_cfg) > 1) {
|
||||||
|
dev_dbg(&pf->pdev->dev, "DCB tagging enabled (num TC > 1)\n");
|
||||||
|
set_bit(ICE_FLAG_DCB_ENA, pf->flags);
|
||||||
|
} else {
|
||||||
|
dev_dbg(&pf->pdev->dev, "DCB tagging disabled (num TC = 1)\n");
|
||||||
|
clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtnl_lock();
|
||||||
|
ice_pf_dis_all_vsi(pf, true);
|
||||||
|
|
||||||
|
ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
|
||||||
|
rtnl_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* changes in configuration update VSI */
|
||||||
|
ice_pf_dcb_recfg(pf);
|
||||||
|
|
||||||
|
ice_pf_ena_all_vsi(pf, true);
|
||||||
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue