diff options
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_common.c | 11 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_dcb.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 42 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_ethtool.c | 13 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 45 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_main.c | 70 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_switch.c | 56 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_txrx.c | 11 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 113 |
12 files changed, 225 insertions, 148 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 9f9c30d29eb5..97d0f61cf52b 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h | |||
| @@ -329,7 +329,7 @@ enum ice_pf_flags { | |||
| 329 | ICE_FLAG_DCB_ENA, | 329 | ICE_FLAG_DCB_ENA, |
| 330 | ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, | 330 | ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, |
| 331 | ICE_FLAG_NO_MEDIA, | 331 | ICE_FLAG_NO_MEDIA, |
| 332 | ICE_FLAG_ENABLE_FW_LLDP, | 332 | ICE_FLAG_FW_LLDP_AGENT, |
| 333 | ICE_FLAG_ETHTOOL_CTXT, /* set when ethtool holds RTNL lock */ | 333 | ICE_FLAG_ETHTOOL_CTXT, /* set when ethtool holds RTNL lock */ |
| 334 | ICE_PF_FLAGS_NBITS /* must be last */ | 334 | ICE_PF_FLAGS_NBITS /* must be last */ |
| 335 | }; | 335 | }; |
| @@ -447,6 +447,8 @@ ice_find_vsi_by_type(struct ice_pf *pf, enum ice_vsi_type type) | |||
| 447 | int ice_vsi_setup_tx_rings(struct ice_vsi *vsi); | 447 | int ice_vsi_setup_tx_rings(struct ice_vsi *vsi); |
| 448 | int ice_vsi_setup_rx_rings(struct ice_vsi *vsi); | 448 | int ice_vsi_setup_rx_rings(struct ice_vsi *vsi); |
| 449 | void ice_set_ethtool_ops(struct net_device *netdev); | 449 | void ice_set_ethtool_ops(struct net_device *netdev); |
| 450 | void ice_update_vsi_stats(struct ice_vsi *vsi); | ||
| 451 | void ice_update_pf_stats(struct ice_pf *pf); | ||
| 450 | int ice_up(struct ice_vsi *vsi); | 452 | int ice_up(struct ice_vsi *vsi); |
| 451 | int ice_down(struct ice_vsi *vsi); | 453 | int ice_down(struct ice_vsi *vsi); |
| 452 | int ice_vsi_cfg(struct ice_vsi *vsi); | 454 | int ice_vsi_cfg(struct ice_vsi *vsi); |
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h index 765e3c2ed045..bf9aa533a7c6 100644 --- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | |||
| @@ -1610,6 +1610,7 @@ enum ice_aq_err { | |||
| 1610 | ICE_AQ_RC_EBUSY = 12, /* Device or resource busy */ | 1610 | ICE_AQ_RC_EBUSY = 12, /* Device or resource busy */ |
| 1611 | ICE_AQ_RC_EEXIST = 13, /* Object already exists */ | 1611 | ICE_AQ_RC_EEXIST = 13, /* Object already exists */ |
| 1612 | ICE_AQ_RC_ENOSPC = 16, /* No space left or allocation failure */ | 1612 | ICE_AQ_RC_ENOSPC = 16, /* No space left or allocation failure */ |
| 1613 | ICE_AQ_RC_ENOSYS = 17, /* Function not implemented */ | ||
| 1613 | }; | 1614 | }; |
| 1614 | 1615 | ||
| 1615 | /* Admin Queue command opcodes */ | 1616 | /* Admin Queue command opcodes */ |
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 5f9dc76699d2..4b43e6de847b 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c | |||
| @@ -2031,7 +2031,7 @@ enum ice_status ice_update_link_info(struct ice_port_info *pi) | |||
| 2031 | if (!pcaps) | 2031 | if (!pcaps) |
| 2032 | return ICE_ERR_NO_MEMORY; | 2032 | return ICE_ERR_NO_MEMORY; |
| 2033 | 2033 | ||
| 2034 | status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, | 2034 | status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, |
| 2035 | pcaps, NULL); | 2035 | pcaps, NULL); |
| 2036 | if (!status) | 2036 | if (!status) |
| 2037 | memcpy(li->module_type, &pcaps->module_type, | 2037 | memcpy(li->module_type, &pcaps->module_type, |
| @@ -2181,27 +2181,24 @@ ice_cfg_phy_fec(struct ice_aqc_set_phy_cfg_data *cfg, enum ice_fec_mode fec) | |||
| 2181 | { | 2181 | { |
| 2182 | switch (fec) { | 2182 | switch (fec) { |
| 2183 | case ICE_FEC_BASER: | 2183 | case ICE_FEC_BASER: |
| 2184 | /* Clear auto FEC and RS bits, and AND BASE-R ability | 2184 | /* Clear RS bits, and AND BASE-R ability |
| 2185 | * bits and OR request bits. | 2185 | * bits and OR request bits. |
| 2186 | */ | 2186 | */ |
| 2187 | cfg->caps &= ~ICE_AQC_PHY_EN_AUTO_FEC; | ||
| 2188 | cfg->link_fec_opt &= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN | | 2187 | cfg->link_fec_opt &= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN | |
| 2189 | ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN; | 2188 | ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN; |
| 2190 | cfg->link_fec_opt |= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ | | 2189 | cfg->link_fec_opt |= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ | |
| 2191 | ICE_AQC_PHY_FEC_25G_KR_REQ; | 2190 | ICE_AQC_PHY_FEC_25G_KR_REQ; |
| 2192 | break; | 2191 | break; |
| 2193 | case ICE_FEC_RS: | 2192 | case ICE_FEC_RS: |
| 2194 | /* Clear auto FEC and BASE-R bits, and AND RS ability | 2193 | /* Clear BASE-R bits, and AND RS ability |
| 2195 | * bits and OR request bits. | 2194 | * bits and OR request bits. |
| 2196 | */ | 2195 | */ |
| 2197 | cfg->caps &= ~ICE_AQC_PHY_EN_AUTO_FEC; | ||
| 2198 | cfg->link_fec_opt &= ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN; | 2196 | cfg->link_fec_opt &= ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN; |
| 2199 | cfg->link_fec_opt |= ICE_AQC_PHY_FEC_25G_RS_528_REQ | | 2197 | cfg->link_fec_opt |= ICE_AQC_PHY_FEC_25G_RS_528_REQ | |
| 2200 | ICE_AQC_PHY_FEC_25G_RS_544_REQ; | 2198 | ICE_AQC_PHY_FEC_25G_RS_544_REQ; |
| 2201 | break; | 2199 | break; |
| 2202 | case ICE_FEC_NONE: | 2200 | case ICE_FEC_NONE: |
| 2203 | /* Clear auto FEC and all FEC option bits. */ | 2201 | /* Clear all FEC option bits. */ |
| 2204 | cfg->caps &= ~ICE_AQC_PHY_EN_AUTO_FEC; | ||
| 2205 | cfg->link_fec_opt &= ~ICE_AQC_PHY_FEC_MASK; | 2202 | cfg->link_fec_opt &= ~ICE_AQC_PHY_FEC_MASK; |
| 2206 | break; | 2203 | break; |
| 2207 | case ICE_FEC_AUTO: | 2204 | case ICE_FEC_AUTO: |
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb.c b/drivers/net/ethernet/intel/ice/ice_dcb.c index c2002ded65f6..d60c942249e8 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb.c | |||
| @@ -954,7 +954,8 @@ enum ice_status ice_init_dcb(struct ice_hw *hw) | |||
| 954 | pi->dcbx_status = ice_get_dcbx_status(hw); | 954 | pi->dcbx_status = ice_get_dcbx_status(hw); |
| 955 | 955 | ||
| 956 | if (pi->dcbx_status == ICE_DCBX_STATUS_DONE || | 956 | if (pi->dcbx_status == ICE_DCBX_STATUS_DONE || |
| 957 | pi->dcbx_status == ICE_DCBX_STATUS_IN_PROGRESS) { | 957 | pi->dcbx_status == ICE_DCBX_STATUS_IN_PROGRESS || |
| 958 | pi->dcbx_status == ICE_DCBX_STATUS_NOT_STARTED) { | ||
| 958 | /* Get current DCBX configuration */ | 959 | /* Get current DCBX configuration */ |
| 959 | ret = ice_get_dcb_cfg(pi); | 960 | ret = ice_get_dcb_cfg(pi); |
| 960 | pi->is_sw_lldp = (hw->adminq.sq_last_status == ICE_AQ_RC_EPERM); | 961 | pi->is_sw_lldp = (hw->adminq.sq_last_status == ICE_AQ_RC_EPERM); |
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c index bf6cd4760a48..734cef8eed9e 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c | |||
| @@ -319,6 +319,11 @@ void ice_dcb_rebuild(struct ice_pf *pf) | |||
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | ice_init_dcb(&pf->hw); | 321 | ice_init_dcb(&pf->hw); |
| 322 | if (pf->hw.port_info->dcbx_status == ICE_DCBX_STATUS_DIS) | ||
| 323 | pf->hw.port_info->is_sw_lldp = true; | ||
| 324 | else | ||
| 325 | pf->hw.port_info->is_sw_lldp = false; | ||
| 326 | |||
| 322 | if (ice_dcb_need_recfg(pf, prev_cfg, local_dcbx_cfg)) { | 327 | if (ice_dcb_need_recfg(pf, prev_cfg, local_dcbx_cfg)) { |
| 323 | /* difference in cfg detected - disable DCB till next MIB */ | 328 | /* difference in cfg detected - disable DCB till next MIB */ |
| 324 | dev_err(&pf->pdev->dev, "Set local MIB not accurate\n"); | 329 | dev_err(&pf->pdev->dev, "Set local MIB not accurate\n"); |
| @@ -329,8 +334,10 @@ void ice_dcb_rebuild(struct ice_pf *pf) | |||
| 329 | devm_kfree(&pf->pdev->dev, prev_cfg); | 334 | devm_kfree(&pf->pdev->dev, prev_cfg); |
| 330 | 335 | ||
| 331 | /* Set the local desired config */ | 336 | /* Set the local desired config */ |
| 332 | memset(&pf->hw.port_info->local_dcbx_cfg, 0, sizeof(*local_dcbx_cfg)); | 337 | if (local_dcbx_cfg->dcbx_mode == ICE_DCBX_MODE_CEE) |
| 333 | memcpy(local_dcbx_cfg, desired_dcbx_cfg, sizeof(*local_dcbx_cfg)); | 338 | memcpy(local_dcbx_cfg, desired_dcbx_cfg, |
| 339 | sizeof(*local_dcbx_cfg)); | ||
| 340 | |||
| 334 | ice_cfg_etsrec_defaults(pf->hw.port_info); | 341 | ice_cfg_etsrec_defaults(pf->hw.port_info); |
| 335 | ret = ice_set_dcb_cfg(pf->hw.port_info); | 342 | ret = ice_set_dcb_cfg(pf->hw.port_info); |
| 336 | if (ret) { | 343 | if (ret) { |
| @@ -440,35 +447,17 @@ int ice_init_pf_dcb(struct ice_pf *pf, bool locked) | |||
| 440 | struct device *dev = &pf->pdev->dev; | 447 | struct device *dev = &pf->pdev->dev; |
| 441 | struct ice_port_info *port_info; | 448 | struct ice_port_info *port_info; |
| 442 | struct ice_hw *hw = &pf->hw; | 449 | struct ice_hw *hw = &pf->hw; |
| 443 | int sw_default = 0; | ||
| 444 | int err; | 450 | int err; |
| 445 | 451 | ||
| 446 | port_info = hw->port_info; | 452 | port_info = hw->port_info; |
| 447 | 453 | ||
| 448 | err = ice_init_dcb(hw); | 454 | err = ice_init_dcb(hw); |
| 449 | if (err) { | 455 | if (err) { |
| 450 | /* FW LLDP is not active, default to SW DCBX/LLDP */ | 456 | /* FW LLDP is disabled, activate SW DCBX/LLDP mode */ |
| 451 | dev_info(&pf->pdev->dev, "FW LLDP is not active\n"); | 457 | dev_info(&pf->pdev->dev, |
| 452 | hw->port_info->dcbx_status = ICE_DCBX_STATUS_NOT_STARTED; | 458 | "FW LLDP is disabled, DCBx/LLDP in SW mode.\n"); |
| 453 | hw->port_info->is_sw_lldp = true; | 459 | port_info->is_sw_lldp = true; |
| 454 | } | 460 | clear_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags); |
| 455 | |||
| 456 | if (port_info->dcbx_status == ICE_DCBX_STATUS_DIS) | ||
| 457 | dev_info(&pf->pdev->dev, "DCBX disabled\n"); | ||
| 458 | |||
| 459 | /* LLDP disabled in FW */ | ||
| 460 | if (port_info->is_sw_lldp) { | ||
| 461 | sw_default = 1; | ||
| 462 | dev_info(&pf->pdev->dev, "DCBx/LLDP in SW mode.\n"); | ||
| 463 | clear_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags); | ||
| 464 | } else { | ||
| 465 | set_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags); | ||
| 466 | } | ||
| 467 | |||
| 468 | if (port_info->dcbx_status == ICE_DCBX_STATUS_NOT_STARTED) | ||
| 469 | dev_info(&pf->pdev->dev, "DCBX not started\n"); | ||
| 470 | |||
| 471 | if (sw_default) { | ||
| 472 | err = ice_dcb_sw_dflt_cfg(pf, locked); | 461 | err = ice_dcb_sw_dflt_cfg(pf, locked); |
| 473 | if (err) { | 462 | if (err) { |
| 474 | dev_err(&pf->pdev->dev, | 463 | dev_err(&pf->pdev->dev, |
| @@ -483,6 +472,9 @@ int ice_init_pf_dcb(struct ice_pf *pf, bool locked) | |||
| 483 | return 0; | 472 | return 0; |
| 484 | } | 473 | } |
| 485 | 474 | ||
| 475 | port_info->is_sw_lldp = false; | ||
| 476 | set_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags); | ||
| 477 | |||
| 486 | /* DCBX in FW and LLDP enabled in FW */ | 478 | /* DCBX in FW and LLDP enabled in FW */ |
| 487 | pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_IEEE; | 479 | pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_IEEE; |
| 488 | 480 | ||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 6a97ddbbda76..f7dd0bd03d39 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c | |||
| @@ -155,7 +155,7 @@ struct ice_priv_flag { | |||
| 155 | 155 | ||
| 156 | static const struct ice_priv_flag ice_gstrings_priv_flags[] = { | 156 | static const struct ice_priv_flag ice_gstrings_priv_flags[] = { |
| 157 | ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA), | 157 | ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA), |
| 158 | ICE_PRIV_FLAG("enable-fw-lldp", ICE_FLAG_ENABLE_FW_LLDP), | 158 | ICE_PRIV_FLAG("fw-lldp-agent", ICE_FLAG_FW_LLDP_AGENT), |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | #define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags) | 161 | #define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags) |
| @@ -1201,8 +1201,8 @@ static int ice_set_priv_flags(struct net_device *netdev, u32 flags) | |||
| 1201 | 1201 | ||
| 1202 | bitmap_xor(change_flags, pf->flags, orig_flags, ICE_PF_FLAGS_NBITS); | 1202 | bitmap_xor(change_flags, pf->flags, orig_flags, ICE_PF_FLAGS_NBITS); |
| 1203 | 1203 | ||
| 1204 | if (test_bit(ICE_FLAG_ENABLE_FW_LLDP, change_flags)) { | 1204 | if (test_bit(ICE_FLAG_FW_LLDP_AGENT, change_flags)) { |
| 1205 | if (!test_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags)) { | 1205 | if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) { |
| 1206 | enum ice_status status; | 1206 | enum ice_status status; |
| 1207 | 1207 | ||
| 1208 | /* Disable FW LLDP engine */ | 1208 | /* Disable FW LLDP engine */ |
| @@ -1319,14 +1319,17 @@ ice_get_ethtool_stats(struct net_device *netdev, | |||
| 1319 | struct ice_vsi *vsi = np->vsi; | 1319 | struct ice_vsi *vsi = np->vsi; |
| 1320 | struct ice_pf *pf = vsi->back; | 1320 | struct ice_pf *pf = vsi->back; |
| 1321 | struct ice_ring *ring; | 1321 | struct ice_ring *ring; |
| 1322 | unsigned int j = 0; | 1322 | unsigned int j; |
| 1323 | int i = 0; | 1323 | int i = 0; |
| 1324 | char *p; | 1324 | char *p; |
| 1325 | 1325 | ||
| 1326 | ice_update_pf_stats(pf); | ||
| 1327 | ice_update_vsi_stats(vsi); | ||
| 1328 | |||
| 1326 | for (j = 0; j < ICE_VSI_STATS_LEN; j++) { | 1329 | for (j = 0; j < ICE_VSI_STATS_LEN; j++) { |
| 1327 | p = (char *)vsi + ice_gstrings_vsi_stats[j].stat_offset; | 1330 | p = (char *)vsi + ice_gstrings_vsi_stats[j].stat_offset; |
| 1328 | data[i++] = (ice_gstrings_vsi_stats[j].sizeof_stat == | 1331 | data[i++] = (ice_gstrings_vsi_stats[j].sizeof_stat == |
| 1329 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | 1332 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; |
| 1330 | } | 1333 | } |
| 1331 | 1334 | ||
| 1332 | /* populate per queue stats */ | 1335 | /* populate per queue stats */ |
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 6e34c40e7840..8d5d6635a123 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c | |||
| @@ -1010,6 +1010,13 @@ static int ice_vsi_init(struct ice_vsi *vsi) | |||
| 1010 | ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF; | 1010 | ICE_AQ_VSI_SEC_FLAG_ENA_MAC_ANTI_SPOOF; |
| 1011 | } | 1011 | } |
| 1012 | 1012 | ||
| 1013 | /* Allow control frames out of main VSI */ | ||
| 1014 | if (vsi->type == ICE_VSI_PF) { | ||
| 1015 | ctxt->info.sec_flags |= ICE_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD; | ||
| 1016 | ctxt->info.valid_sections |= | ||
| 1017 | cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID); | ||
| 1018 | } | ||
| 1019 | |||
| 1013 | ret = ice_add_vsi(hw, vsi->idx, ctxt, NULL); | 1020 | ret = ice_add_vsi(hw, vsi->idx, ctxt, NULL); |
| 1014 | if (ret) { | 1021 | if (ret) { |
| 1015 | dev_err(&pf->pdev->dev, | 1022 | dev_err(&pf->pdev->dev, |
| @@ -2534,7 +2541,7 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi, | |||
| 2534 | ice_cfg_sw_lldp(vsi, true, true); | 2541 | ice_cfg_sw_lldp(vsi, true, true); |
| 2535 | 2542 | ||
| 2536 | /* Rx LLDP packets */ | 2543 | /* Rx LLDP packets */ |
| 2537 | if (!test_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags)) | 2544 | if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) |
| 2538 | ice_cfg_sw_lldp(vsi, false, true); | 2545 | ice_cfg_sw_lldp(vsi, false, true); |
| 2539 | } | 2546 | } |
| 2540 | 2547 | ||
| @@ -2810,6 +2817,10 @@ void ice_vsi_dis_irq(struct ice_vsi *vsi) | |||
| 2810 | 2817 | ||
| 2811 | ice_flush(hw); | 2818 | ice_flush(hw); |
| 2812 | 2819 | ||
| 2820 | /* don't call synchronize_irq() for VF's from the host */ | ||
| 2821 | if (vsi->type == ICE_VSI_VF) | ||
| 2822 | return; | ||
| 2823 | |||
| 2813 | ice_for_each_q_vector(vsi, i) | 2824 | ice_for_each_q_vector(vsi, i) |
| 2814 | synchronize_irq(pf->msix_entries[i + base].vector); | 2825 | synchronize_irq(pf->msix_entries[i + base].vector); |
| 2815 | } | 2826 | } |
| @@ -2877,7 +2888,7 @@ int ice_vsi_release(struct ice_vsi *vsi) | |||
| 2877 | /* The Rx rule will only exist to remove if the LLDP FW | 2888 | /* The Rx rule will only exist to remove if the LLDP FW |
| 2878 | * engine is currently stopped | 2889 | * engine is currently stopped |
| 2879 | */ | 2890 | */ |
| 2880 | if (!test_bit(ICE_FLAG_ENABLE_FW_LLDP, pf->flags)) | 2891 | if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) |
| 2881 | ice_cfg_sw_lldp(vsi, false, false); | 2892 | ice_cfg_sw_lldp(vsi, false, false); |
| 2882 | } | 2893 | } |
| 2883 | 2894 | ||
| @@ -3170,3 +3181,33 @@ out: | |||
| 3170 | return ret; | 3181 | return ret; |
| 3171 | } | 3182 | } |
| 3172 | #endif /* CONFIG_DCB */ | 3183 | #endif /* CONFIG_DCB */ |
| 3184 | |||
| 3185 | /** | ||
| 3186 | * ice_vsi_cfg_mac_fltr - Add or remove a MAC address filter for a VSI | ||
| 3187 | * @vsi: the VSI being configured MAC filter | ||
| 3188 | * @macaddr: the MAC address to be added. | ||
| 3189 | * @set: Add or delete a MAC filter | ||
| 3190 | * | ||
| 3191 | * Adds or removes MAC address filter entry for VF VSI | ||
| 3192 | */ | ||
| 3193 | enum ice_status | ||
| 3194 | ice_vsi_cfg_mac_fltr(struct ice_vsi *vsi, const u8 *macaddr, bool set) | ||
| 3195 | { | ||
| 3196 | LIST_HEAD(tmp_add_list); | ||
| 3197 | enum ice_status status; | ||
| 3198 | |||
| 3199 | /* Update MAC filter list to be added or removed for a VSI */ | ||
| 3200 | if (ice_add_mac_to_list(vsi, &tmp_add_list, macaddr)) { | ||
| 3201 | status = ICE_ERR_NO_MEMORY; | ||
| 3202 | goto cfg_mac_fltr_exit; | ||
| 3203 | } | ||
| 3204 | |||
| 3205 | if (set) | ||
| 3206 | status = ice_add_mac(&vsi->back->hw, &tmp_add_list); | ||
| 3207 | else | ||
| 3208 | status = ice_remove_mac(&vsi->back->hw, &tmp_add_list); | ||
| 3209 | |||
| 3210 | cfg_mac_fltr_exit: | ||
| 3211 | ice_free_fltr_list(&vsi->back->pdev->dev, &tmp_add_list); | ||
| 3212 | return status; | ||
| 3213 | } | ||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h index 6e43ef03bfc3..969ba27cba95 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_lib.h | |||
| @@ -95,4 +95,8 @@ void ice_vsi_free_tx_rings(struct ice_vsi *vsi); | |||
| 95 | int ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena); | 95 | int ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena); |
| 96 | 96 | ||
| 97 | u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran); | 97 | u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran); |
| 98 | |||
| 99 | enum ice_status | ||
| 100 | ice_vsi_cfg_mac_fltr(struct ice_vsi *vsi, const u8 *macaddr, bool set); | ||
| 101 | |||
| 98 | #endif /* !_ICE_LIB_H_ */ | 102 | #endif /* !_ICE_LIB_H_ */ |
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index a0d148f590c2..f3923dec32b7 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c | |||
| @@ -34,8 +34,6 @@ static const struct net_device_ops ice_netdev_ops; | |||
| 34 | static void ice_rebuild(struct ice_pf *pf); | 34 | static void ice_rebuild(struct ice_pf *pf); |
| 35 | 35 | ||
| 36 | static void ice_vsi_release_all(struct ice_pf *pf); | 36 | static void ice_vsi_release_all(struct ice_pf *pf); |
| 37 | static void ice_update_vsi_stats(struct ice_vsi *vsi); | ||
| 38 | static void ice_update_pf_stats(struct ice_pf *pf); | ||
| 39 | 37 | ||
| 40 | /** | 38 | /** |
| 41 | * ice_get_tx_pending - returns number of Tx descriptors not processed | 39 | * ice_get_tx_pending - returns number of Tx descriptors not processed |
| @@ -118,10 +116,9 @@ static void ice_check_for_hang_subtask(struct ice_pf *pf) | |||
| 118 | */ | 116 | */ |
| 119 | static int ice_init_mac_fltr(struct ice_pf *pf) | 117 | static int ice_init_mac_fltr(struct ice_pf *pf) |
| 120 | { | 118 | { |
| 121 | LIST_HEAD(tmp_add_list); | 119 | enum ice_status status; |
| 122 | u8 broadcast[ETH_ALEN]; | 120 | u8 broadcast[ETH_ALEN]; |
| 123 | struct ice_vsi *vsi; | 121 | struct ice_vsi *vsi; |
| 124 | int status; | ||
| 125 | 122 | ||
| 126 | vsi = ice_find_vsi_by_type(pf, ICE_VSI_PF); | 123 | vsi = ice_find_vsi_by_type(pf, ICE_VSI_PF); |
| 127 | if (!vsi) | 124 | if (!vsi) |
| @@ -132,8 +129,7 @@ static int ice_init_mac_fltr(struct ice_pf *pf) | |||
| 132 | */ | 129 | */ |
| 133 | 130 | ||
| 134 | /* Add a unicast MAC filter so the VSI can get its packets */ | 131 | /* Add a unicast MAC filter so the VSI can get its packets */ |
| 135 | status = ice_add_mac_to_list(vsi, &tmp_add_list, | 132 | status = ice_vsi_cfg_mac_fltr(vsi, vsi->port_info->mac.perm_addr, true); |
| 136 | vsi->port_info->mac.perm_addr); | ||
| 137 | if (status) | 133 | if (status) |
| 138 | goto unregister; | 134 | goto unregister; |
| 139 | 135 | ||
| @@ -141,18 +137,11 @@ static int ice_init_mac_fltr(struct ice_pf *pf) | |||
| 141 | * MAC address to the list as well. | 137 | * MAC address to the list as well. |
| 142 | */ | 138 | */ |
| 143 | eth_broadcast_addr(broadcast); | 139 | eth_broadcast_addr(broadcast); |
| 144 | status = ice_add_mac_to_list(vsi, &tmp_add_list, broadcast); | 140 | status = ice_vsi_cfg_mac_fltr(vsi, broadcast, true); |
| 145 | if (status) | ||
| 146 | goto free_mac_list; | ||
| 147 | |||
| 148 | /* Program MAC filters for entries in tmp_add_list */ | ||
| 149 | status = ice_add_mac(&pf->hw, &tmp_add_list); | ||
| 150 | if (status) | 141 | if (status) |
| 151 | status = -ENOMEM; | 142 | goto unregister; |
| 152 | |||
| 153 | free_mac_list: | ||
| 154 | ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list); | ||
| 155 | 143 | ||
| 144 | return 0; | ||
| 156 | unregister: | 145 | unregister: |
| 157 | /* We aren't useful with no MAC filters, so unregister if we | 146 | /* We aren't useful with no MAC filters, so unregister if we |
| 158 | * had an error | 147 | * had an error |
| @@ -166,7 +155,7 @@ unregister: | |||
| 166 | vsi->netdev = NULL; | 155 | vsi->netdev = NULL; |
| 167 | } | 156 | } |
| 168 | 157 | ||
| 169 | return status; | 158 | return -EIO; |
| 170 | } | 159 | } |
| 171 | 160 | ||
| 172 | /** | 161 | /** |
| @@ -2836,10 +2825,8 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi) | |||
| 2836 | struct ice_hw *hw = &pf->hw; | 2825 | struct ice_hw *hw = &pf->hw; |
| 2837 | struct sockaddr *addr = pi; | 2826 | struct sockaddr *addr = pi; |
| 2838 | enum ice_status status; | 2827 | enum ice_status status; |
| 2839 | LIST_HEAD(a_mac_list); | ||
| 2840 | LIST_HEAD(r_mac_list); | ||
| 2841 | u8 flags = 0; | 2828 | u8 flags = 0; |
| 2842 | int err; | 2829 | int err = 0; |
| 2843 | u8 *mac; | 2830 | u8 *mac; |
| 2844 | 2831 | ||
| 2845 | mac = (u8 *)addr->sa_data; | 2832 | mac = (u8 *)addr->sa_data; |
| @@ -2862,42 +2849,23 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi) | |||
| 2862 | /* When we change the MAC address we also have to change the MAC address | 2849 | /* When we change the MAC address we also have to change the MAC address |
| 2863 | * based filter rules that were created previously for the old MAC | 2850 | * based filter rules that were created previously for the old MAC |
| 2864 | * address. So first, we remove the old filter rule using ice_remove_mac | 2851 | * address. So first, we remove the old filter rule using ice_remove_mac |
| 2865 | * and then create a new filter rule using ice_add_mac. Note that for | 2852 | * and then create a new filter rule using ice_add_mac via |
| 2866 | * both these operations, we first need to form a "list" of MAC | 2853 | * ice_vsi_cfg_mac_fltr function call for both add and/or remove |
| 2867 | * addresses (even though in this case, we have only 1 MAC address to be | 2854 | * filters. |
| 2868 | * added/removed) and this done using ice_add_mac_to_list. Depending on | ||
| 2869 | * the ensuing operation this "list" of MAC addresses is either to be | ||
| 2870 | * added or removed from the filter. | ||
| 2871 | */ | 2855 | */ |
| 2872 | err = ice_add_mac_to_list(vsi, &r_mac_list, netdev->dev_addr); | 2856 | status = ice_vsi_cfg_mac_fltr(vsi, netdev->dev_addr, false); |
| 2873 | if (err) { | ||
| 2874 | err = -EADDRNOTAVAIL; | ||
| 2875 | goto free_lists; | ||
| 2876 | } | ||
| 2877 | |||
| 2878 | status = ice_remove_mac(hw, &r_mac_list); | ||
| 2879 | if (status) { | 2857 | if (status) { |
| 2880 | err = -EADDRNOTAVAIL; | 2858 | err = -EADDRNOTAVAIL; |
| 2881 | goto free_lists; | 2859 | goto err_update_filters; |
| 2882 | } | ||
| 2883 | |||
| 2884 | err = ice_add_mac_to_list(vsi, &a_mac_list, mac); | ||
| 2885 | if (err) { | ||
| 2886 | err = -EADDRNOTAVAIL; | ||
| 2887 | goto free_lists; | ||
| 2888 | } | 2860 | } |
| 2889 | 2861 | ||
| 2890 | status = ice_add_mac(hw, &a_mac_list); | 2862 | status = ice_vsi_cfg_mac_fltr(vsi, mac, true); |
| 2891 | if (status) { | 2863 | if (status) { |
| 2892 | err = -EADDRNOTAVAIL; | 2864 | err = -EADDRNOTAVAIL; |
| 2893 | goto free_lists; | 2865 | goto err_update_filters; |
| 2894 | } | 2866 | } |
| 2895 | 2867 | ||
| 2896 | free_lists: | 2868 | err_update_filters: |
| 2897 | /* free list entries */ | ||
| 2898 | ice_free_fltr_list(&pf->pdev->dev, &r_mac_list); | ||
| 2899 | ice_free_fltr_list(&pf->pdev->dev, &a_mac_list); | ||
| 2900 | |||
| 2901 | if (err) { | 2869 | if (err) { |
| 2902 | netdev_err(netdev, "can't set MAC %pM. filter update failed\n", | 2870 | netdev_err(netdev, "can't set MAC %pM. filter update failed\n", |
| 2903 | mac); | 2871 | mac); |
| @@ -2913,8 +2881,8 @@ free_lists: | |||
| 2913 | flags = ICE_AQC_MAN_MAC_UPDATE_LAA_WOL; | 2881 | flags = ICE_AQC_MAN_MAC_UPDATE_LAA_WOL; |
| 2914 | status = ice_aq_manage_mac_write(hw, mac, flags, NULL); | 2882 | status = ice_aq_manage_mac_write(hw, mac, flags, NULL); |
| 2915 | if (status) { | 2883 | if (status) { |
| 2916 | netdev_err(netdev, "can't set MAC %pM. write to firmware failed.\n", | 2884 | netdev_err(netdev, "can't set MAC %pM. write to firmware failed error %d\n", |
| 2917 | mac); | 2885 | mac, status); |
| 2918 | } | 2886 | } |
| 2919 | return 0; | 2887 | return 0; |
| 2920 | } | 2888 | } |
| @@ -3254,7 +3222,7 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) | |||
| 3254 | * ice_update_vsi_stats - Update VSI stats counters | 3222 | * ice_update_vsi_stats - Update VSI stats counters |
| 3255 | * @vsi: the VSI to be updated | 3223 | * @vsi: the VSI to be updated |
| 3256 | */ | 3224 | */ |
| 3257 | static void ice_update_vsi_stats(struct ice_vsi *vsi) | 3225 | void ice_update_vsi_stats(struct ice_vsi *vsi) |
| 3258 | { | 3226 | { |
| 3259 | struct rtnl_link_stats64 *cur_ns = &vsi->net_stats; | 3227 | struct rtnl_link_stats64 *cur_ns = &vsi->net_stats; |
| 3260 | struct ice_eth_stats *cur_es = &vsi->eth_stats; | 3228 | struct ice_eth_stats *cur_es = &vsi->eth_stats; |
| @@ -3290,7 +3258,7 @@ static void ice_update_vsi_stats(struct ice_vsi *vsi) | |||
| 3290 | * ice_update_pf_stats - Update PF port stats counters | 3258 | * ice_update_pf_stats - Update PF port stats counters |
| 3291 | * @pf: PF whose stats needs to be updated | 3259 | * @pf: PF whose stats needs to be updated |
| 3292 | */ | 3260 | */ |
| 3293 | static void ice_update_pf_stats(struct ice_pf *pf) | 3261 | void ice_update_pf_stats(struct ice_pf *pf) |
| 3294 | { | 3262 | { |
| 3295 | struct ice_hw_port_stats *prev_ps, *cur_ps; | 3263 | struct ice_hw_port_stats *prev_ps, *cur_ps; |
| 3296 | struct ice_hw *hw = &pf->hw; | 3264 | struct ice_hw *hw = &pf->hw; |
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index 8271fd651725..99cf527d2b1a 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c | |||
| @@ -2137,6 +2137,38 @@ out: | |||
| 2137 | } | 2137 | } |
| 2138 | 2138 | ||
| 2139 | /** | 2139 | /** |
| 2140 | * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry | ||
| 2141 | * @hw: pointer to the hardware structure | ||
| 2142 | * @recp_id: lookup type for which the specified rule needs to be searched | ||
| 2143 | * @f_info: rule information | ||
| 2144 | * | ||
| 2145 | * Helper function to search for a unicast rule entry - this is to be used | ||
| 2146 | * to remove unicast MAC filter that is not shared with other VSIs on the | ||
| 2147 | * PF switch. | ||
| 2148 | * | ||
| 2149 | * Returns pointer to entry storing the rule if found | ||
| 2150 | */ | ||
| 2151 | static struct ice_fltr_mgmt_list_entry * | ||
| 2152 | ice_find_ucast_rule_entry(struct ice_hw *hw, u8 recp_id, | ||
| 2153 | struct ice_fltr_info *f_info) | ||
| 2154 | { | ||
| 2155 | struct ice_switch_info *sw = hw->switch_info; | ||
| 2156 | struct ice_fltr_mgmt_list_entry *list_itr; | ||
| 2157 | struct list_head *list_head; | ||
| 2158 | |||
| 2159 | list_head = &sw->recp_list[recp_id].filt_rules; | ||
| 2160 | list_for_each_entry(list_itr, list_head, list_entry) { | ||
| 2161 | if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, | ||
| 2162 | sizeof(f_info->l_data)) && | ||
| 2163 | f_info->fwd_id.hw_vsi_id == | ||
| 2164 | list_itr->fltr_info.fwd_id.hw_vsi_id && | ||
| 2165 | f_info->flag == list_itr->fltr_info.flag) | ||
| 2166 | return list_itr; | ||
| 2167 | } | ||
| 2168 | return NULL; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | /** | ||
| 2140 | * ice_remove_mac - remove a MAC address based filter rule | 2172 | * ice_remove_mac - remove a MAC address based filter rule |
| 2141 | * @hw: pointer to the hardware structure | 2173 | * @hw: pointer to the hardware structure |
| 2142 | * @m_list: list of MAC addresses and forwarding information | 2174 | * @m_list: list of MAC addresses and forwarding information |
| @@ -2153,15 +2185,39 @@ enum ice_status | |||
| 2153 | ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) | 2185 | ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) |
| 2154 | { | 2186 | { |
| 2155 | struct ice_fltr_list_entry *list_itr, *tmp; | 2187 | struct ice_fltr_list_entry *list_itr, *tmp; |
| 2188 | struct mutex *rule_lock; /* Lock to protect filter rule list */ | ||
| 2156 | 2189 | ||
| 2157 | if (!m_list) | 2190 | if (!m_list) |
| 2158 | return ICE_ERR_PARAM; | 2191 | return ICE_ERR_PARAM; |
| 2159 | 2192 | ||
| 2193 | rule_lock = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; | ||
| 2160 | list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) { | 2194 | list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) { |
| 2161 | enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; | 2195 | enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; |
| 2196 | u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0]; | ||
| 2197 | u16 vsi_handle; | ||
| 2162 | 2198 | ||
| 2163 | if (l_type != ICE_SW_LKUP_MAC) | 2199 | if (l_type != ICE_SW_LKUP_MAC) |
| 2164 | return ICE_ERR_PARAM; | 2200 | return ICE_ERR_PARAM; |
| 2201 | |||
| 2202 | vsi_handle = list_itr->fltr_info.vsi_handle; | ||
| 2203 | if (!ice_is_vsi_valid(hw, vsi_handle)) | ||
| 2204 | return ICE_ERR_PARAM; | ||
| 2205 | |||
| 2206 | list_itr->fltr_info.fwd_id.hw_vsi_id = | ||
| 2207 | ice_get_hw_vsi_num(hw, vsi_handle); | ||
| 2208 | if (is_unicast_ether_addr(add) && !hw->ucast_shared) { | ||
| 2209 | /* Don't remove the unicast address that belongs to | ||
| 2210 | * another VSI on the switch, since it is not being | ||
| 2211 | * shared... | ||
| 2212 | */ | ||
| 2213 | mutex_lock(rule_lock); | ||
| 2214 | if (!ice_find_ucast_rule_entry(hw, ICE_SW_LKUP_MAC, | ||
| 2215 | &list_itr->fltr_info)) { | ||
| 2216 | mutex_unlock(rule_lock); | ||
| 2217 | return ICE_ERR_DOES_NOT_EXIST; | ||
| 2218 | } | ||
| 2219 | mutex_unlock(rule_lock); | ||
| 2220 | } | ||
| 2165 | list_itr->status = ice_remove_rule_internal(hw, | 2221 | list_itr->status = ice_remove_rule_internal(hw, |
| 2166 | ICE_SW_LKUP_MAC, | 2222 | ICE_SW_LKUP_MAC, |
| 2167 | list_itr); | 2223 | list_itr); |
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index e5c4c9139e54..5bf5c179a738 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c | |||
| @@ -2106,6 +2106,7 @@ static netdev_tx_t | |||
| 2106 | ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring) | 2106 | ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring) |
| 2107 | { | 2107 | { |
| 2108 | struct ice_tx_offload_params offload = { 0 }; | 2108 | struct ice_tx_offload_params offload = { 0 }; |
| 2109 | struct ice_vsi *vsi = tx_ring->vsi; | ||
| 2109 | struct ice_tx_buf *first; | 2110 | struct ice_tx_buf *first; |
| 2110 | unsigned int count; | 2111 | unsigned int count; |
| 2111 | int tso, csum; | 2112 | int tso, csum; |
| @@ -2153,7 +2154,15 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring) | |||
| 2153 | if (csum < 0) | 2154 | if (csum < 0) |
| 2154 | goto out_drop; | 2155 | goto out_drop; |
| 2155 | 2156 | ||
| 2156 | if (tso || offload.cd_tunnel_params) { | 2157 | /* allow CONTROL frames egress from main VSI if FW LLDP disabled */ |
| 2158 | if (unlikely(skb->priority == TC_PRIO_CONTROL && | ||
| 2159 | vsi->type == ICE_VSI_PF && | ||
| 2160 | vsi->port_info->is_sw_lldp)) | ||
| 2161 | offload.cd_qw1 |= (u64)(ICE_TX_DESC_DTYPE_CTX | | ||
| 2162 | ICE_TX_CTX_DESC_SWTCH_UPLINK << | ||
| 2163 | ICE_TXD_CTX_QW1_CMD_S); | ||
| 2164 | |||
| 2165 | if (offload.cd_qw1 & ICE_TX_DESC_DTYPE_CTX) { | ||
| 2157 | struct ice_tx_ctx_desc *cdesc; | 2166 | struct ice_tx_ctx_desc *cdesc; |
| 2158 | int i = tx_ring->next_to_use; | 2167 | int i = tx_ring->next_to_use; |
| 2159 | 2168 | ||
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c index 1b1d1ea0c8f9..86637d99ee77 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | |||
| @@ -540,7 +540,10 @@ static int ice_alloc_vsi_res(struct ice_vf *vf) | |||
| 540 | 540 | ||
| 541 | status = ice_add_mac(&pf->hw, &tmp_add_list); | 541 | status = ice_add_mac(&pf->hw, &tmp_add_list); |
| 542 | if (status) | 542 | if (status) |
| 543 | dev_err(&pf->pdev->dev, "could not add mac filters\n"); | 543 | dev_err(&pf->pdev->dev, |
| 544 | "could not add mac filters error %d\n", status); | ||
| 545 | else | ||
| 546 | vf->num_mac = 1; | ||
| 544 | 547 | ||
| 545 | /* Clear this bit after VF initialization since we shouldn't reclaim | 548 | /* Clear this bit after VF initialization since we shouldn't reclaim |
| 546 | * and reassign interrupts for synchronous or asynchronous VFR events. | 549 | * and reassign interrupts for synchronous or asynchronous VFR events. |
| @@ -1512,10 +1515,10 @@ ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode, | |||
| 1512 | 1515 | ||
| 1513 | aq_ret = ice_aq_send_msg_to_vf(&pf->hw, vf->vf_id, v_opcode, v_retval, | 1516 | aq_ret = ice_aq_send_msg_to_vf(&pf->hw, vf->vf_id, v_opcode, v_retval, |
| 1514 | msg, msglen, NULL); | 1517 | msg, msglen, NULL); |
| 1515 | if (aq_ret) { | 1518 | if (aq_ret && pf->hw.mailboxq.sq_last_status != ICE_AQ_RC_ENOSYS) { |
| 1516 | dev_info(&pf->pdev->dev, | 1519 | dev_info(&pf->pdev->dev, |
| 1517 | "Unable to send the message to VF %d aq_err %d\n", | 1520 | "Unable to send the message to VF %d ret %d aq_err %d\n", |
| 1518 | vf->vf_id, pf->hw.mailboxq.sq_last_status); | 1521 | vf->vf_id, aq_ret, pf->hw.mailboxq.sq_last_status); |
| 1519 | return -EIO; | 1522 | return -EIO; |
| 1520 | } | 1523 | } |
| 1521 | 1524 | ||
| @@ -1734,18 +1737,18 @@ static int ice_vc_config_rss_key(struct ice_vf *vf, u8 *msg) | |||
| 1734 | goto error_param; | 1737 | goto error_param; |
| 1735 | } | 1738 | } |
| 1736 | 1739 | ||
| 1737 | vsi = pf->vsi[vf->lan_vsi_idx]; | 1740 | if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) { |
| 1738 | if (!vsi) { | ||
| 1739 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1741 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1740 | goto error_param; | 1742 | goto error_param; |
| 1741 | } | 1743 | } |
| 1742 | 1744 | ||
| 1743 | if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) { | 1745 | if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { |
| 1744 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1746 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1745 | goto error_param; | 1747 | goto error_param; |
| 1746 | } | 1748 | } |
| 1747 | 1749 | ||
| 1748 | if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { | 1750 | vsi = pf->vsi[vf->lan_vsi_idx]; |
| 1751 | if (!vsi) { | ||
| 1749 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1752 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1750 | goto error_param; | 1753 | goto error_param; |
| 1751 | } | 1754 | } |
| @@ -1781,18 +1784,18 @@ static int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg) | |||
| 1781 | goto error_param; | 1784 | goto error_param; |
| 1782 | } | 1785 | } |
| 1783 | 1786 | ||
| 1784 | vsi = pf->vsi[vf->lan_vsi_idx]; | 1787 | if (vrl->lut_entries != ICE_VSIQF_HLUT_ARRAY_SIZE) { |
| 1785 | if (!vsi) { | ||
| 1786 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1788 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1787 | goto error_param; | 1789 | goto error_param; |
| 1788 | } | 1790 | } |
| 1789 | 1791 | ||
| 1790 | if (vrl->lut_entries != ICE_VSIQF_HLUT_ARRAY_SIZE) { | 1792 | if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { |
| 1791 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1793 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1792 | goto error_param; | 1794 | goto error_param; |
| 1793 | } | 1795 | } |
| 1794 | 1796 | ||
| 1795 | if (!test_bit(ICE_FLAG_RSS_ENA, vf->pf->flags)) { | 1797 | vsi = pf->vsi[vf->lan_vsi_idx]; |
| 1798 | if (!vsi) { | ||
| 1796 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1799 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1797 | goto error_param; | 1800 | goto error_param; |
| 1798 | } | 1801 | } |
| @@ -1877,6 +1880,12 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg) | |||
| 1877 | goto error_param; | 1880 | goto error_param; |
| 1878 | } | 1881 | } |
| 1879 | 1882 | ||
| 1883 | if (vqs->rx_queues > ICE_MAX_BASE_QS_PER_VF || | ||
| 1884 | vqs->tx_queues > ICE_MAX_BASE_QS_PER_VF) { | ||
| 1885 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1886 | goto error_param; | ||
| 1887 | } | ||
| 1888 | |||
| 1880 | vsi = pf->vsi[vf->lan_vsi_idx]; | 1889 | vsi = pf->vsi[vf->lan_vsi_idx]; |
| 1881 | if (!vsi) { | 1890 | if (!vsi) { |
| 1882 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1891 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| @@ -1932,6 +1941,12 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) | |||
| 1932 | goto error_param; | 1941 | goto error_param; |
| 1933 | } | 1942 | } |
| 1934 | 1943 | ||
| 1944 | if (vqs->rx_queues > ICE_MAX_BASE_QS_PER_VF || | ||
| 1945 | vqs->tx_queues > ICE_MAX_BASE_QS_PER_VF) { | ||
| 1946 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1947 | goto error_param; | ||
| 1948 | } | ||
| 1949 | |||
| 1935 | vsi = pf->vsi[vf->lan_vsi_idx]; | 1950 | vsi = pf->vsi[vf->lan_vsi_idx]; |
| 1936 | if (!vsi) { | 1951 | if (!vsi) { |
| 1937 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1952 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| @@ -1984,12 +1999,6 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg) | |||
| 1984 | irqmap_info = (struct virtchnl_irq_map_info *)msg; | 1999 | irqmap_info = (struct virtchnl_irq_map_info *)msg; |
| 1985 | num_q_vectors_mapped = irqmap_info->num_vectors; | 2000 | num_q_vectors_mapped = irqmap_info->num_vectors; |
| 1986 | 2001 | ||
| 1987 | vsi = pf->vsi[vf->lan_vsi_idx]; | ||
| 1988 | if (!vsi) { | ||
| 1989 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1990 | goto error_param; | ||
| 1991 | } | ||
| 1992 | |||
| 1993 | /* Check to make sure number of VF vectors mapped is not greater than | 2002 | /* Check to make sure number of VF vectors mapped is not greater than |
| 1994 | * number of VF vectors originally allocated, and check that | 2003 | * number of VF vectors originally allocated, and check that |
| 1995 | * there is actually at least a single VF queue vector mapped | 2004 | * there is actually at least a single VF queue vector mapped |
| @@ -2001,6 +2010,12 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg) | |||
| 2001 | goto error_param; | 2010 | goto error_param; |
| 2002 | } | 2011 | } |
| 2003 | 2012 | ||
| 2013 | vsi = pf->vsi[vf->lan_vsi_idx]; | ||
| 2014 | if (!vsi) { | ||
| 2015 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 2016 | goto error_param; | ||
| 2017 | } | ||
| 2018 | |||
| 2004 | for (i = 0; i < num_q_vectors_mapped; i++) { | 2019 | for (i = 0; i < num_q_vectors_mapped; i++) { |
| 2005 | struct ice_q_vector *q_vector; | 2020 | struct ice_q_vector *q_vector; |
| 2006 | 2021 | ||
| @@ -2092,10 +2107,6 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) | |||
| 2092 | goto error_param; | 2107 | goto error_param; |
| 2093 | } | 2108 | } |
| 2094 | 2109 | ||
| 2095 | vsi = pf->vsi[vf->lan_vsi_idx]; | ||
| 2096 | if (!vsi) | ||
| 2097 | goto error_param; | ||
| 2098 | |||
| 2099 | if (qci->num_queue_pairs > ICE_MAX_BASE_QS_PER_VF) { | 2110 | if (qci->num_queue_pairs > ICE_MAX_BASE_QS_PER_VF) { |
| 2100 | dev_err(&pf->pdev->dev, | 2111 | dev_err(&pf->pdev->dev, |
| 2101 | "VF-%d requesting more than supported number of queues: %d\n", | 2112 | "VF-%d requesting more than supported number of queues: %d\n", |
| @@ -2104,11 +2115,18 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) | |||
| 2104 | goto error_param; | 2115 | goto error_param; |
| 2105 | } | 2116 | } |
| 2106 | 2117 | ||
| 2118 | vsi = pf->vsi[vf->lan_vsi_idx]; | ||
| 2119 | if (!vsi) { | ||
| 2120 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 2121 | goto error_param; | ||
| 2122 | } | ||
| 2123 | |||
| 2107 | for (i = 0; i < qci->num_queue_pairs; i++) { | 2124 | for (i = 0; i < qci->num_queue_pairs; i++) { |
| 2108 | qpi = &qci->qpair[i]; | 2125 | qpi = &qci->qpair[i]; |
| 2109 | if (qpi->txq.vsi_id != qci->vsi_id || | 2126 | if (qpi->txq.vsi_id != qci->vsi_id || |
| 2110 | qpi->rxq.vsi_id != qci->vsi_id || | 2127 | qpi->rxq.vsi_id != qci->vsi_id || |
| 2111 | qpi->rxq.queue_id != qpi->txq.queue_id || | 2128 | qpi->rxq.queue_id != qpi->txq.queue_id || |
| 2129 | qpi->txq.headwb_enabled || | ||
| 2112 | !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) { | 2130 | !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) { |
| 2113 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 2131 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 2114 | goto error_param; | 2132 | goto error_param; |
| @@ -2193,7 +2211,7 @@ ice_vc_handle_mac_addr_msg(struct ice_vf *vf, u8 *msg, bool set) | |||
| 2193 | (struct virtchnl_ether_addr_list *)msg; | 2211 | (struct virtchnl_ether_addr_list *)msg; |
| 2194 | struct ice_pf *pf = vf->pf; | 2212 | struct ice_pf *pf = vf->pf; |
| 2195 | enum virtchnl_ops vc_op; | 2213 | enum virtchnl_ops vc_op; |
| 2196 | LIST_HEAD(mac_list); | 2214 | enum ice_status status; |
| 2197 | struct ice_vsi *vsi; | 2215 | struct ice_vsi *vsi; |
| 2198 | int mac_count = 0; | 2216 | int mac_count = 0; |
| 2199 | int i; | 2217 | int i; |
| @@ -2267,33 +2285,32 @@ ice_vc_handle_mac_addr_msg(struct ice_vf *vf, u8 *msg, bool set) | |||
| 2267 | goto handle_mac_exit; | 2285 | goto handle_mac_exit; |
| 2268 | } | 2286 | } |
| 2269 | 2287 | ||
| 2270 | /* get here if maddr is multicast or if VF can change MAC */ | 2288 | /* program the updated filter list */ |
| 2271 | if (ice_add_mac_to_list(vsi, &mac_list, al->list[i].addr)) { | 2289 | status = ice_vsi_cfg_mac_fltr(vsi, maddr, set); |
| 2272 | v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; | 2290 | if (status == ICE_ERR_DOES_NOT_EXIST || |
| 2291 | status == ICE_ERR_ALREADY_EXISTS) { | ||
| 2292 | dev_info(&pf->pdev->dev, | ||
| 2293 | "can't %s MAC filters %pM for VF %d, error %d\n", | ||
| 2294 | set ? "add" : "remove", maddr, vf->vf_id, | ||
| 2295 | status); | ||
| 2296 | } else if (status) { | ||
| 2297 | dev_err(&pf->pdev->dev, | ||
| 2298 | "can't %s MAC filters for VF %d, error %d\n", | ||
| 2299 | set ? "add" : "remove", vf->vf_id, status); | ||
| 2300 | v_ret = ice_err_to_virt_err(status); | ||
| 2273 | goto handle_mac_exit; | 2301 | goto handle_mac_exit; |
| 2274 | } | 2302 | } |
| 2303 | |||
| 2275 | mac_count++; | 2304 | mac_count++; |
| 2276 | } | 2305 | } |
| 2277 | 2306 | ||
| 2278 | /* program the updated filter list */ | 2307 | /* Track number of MAC filters programmed for the VF VSI */ |
| 2279 | if (set) | 2308 | if (set) |
| 2280 | v_ret = ice_err_to_virt_err(ice_add_mac(&pf->hw, &mac_list)); | 2309 | vf->num_mac += mac_count; |
| 2281 | else | 2310 | else |
| 2282 | v_ret = ice_err_to_virt_err(ice_remove_mac(&pf->hw, &mac_list)); | 2311 | vf->num_mac -= mac_count; |
| 2283 | |||
| 2284 | if (v_ret) { | ||
| 2285 | dev_err(&pf->pdev->dev, | ||
| 2286 | "can't %s MAC filters for VF %d, error %d\n", | ||
| 2287 | set ? "add" : "remove", vf->vf_id, v_ret); | ||
| 2288 | } else { | ||
| 2289 | if (set) | ||
| 2290 | vf->num_mac += mac_count; | ||
| 2291 | else | ||
| 2292 | vf->num_mac -= mac_count; | ||
| 2293 | } | ||
| 2294 | 2312 | ||
| 2295 | handle_mac_exit: | 2313 | handle_mac_exit: |
| 2296 | ice_free_fltr_list(&pf->pdev->dev, &mac_list); | ||
| 2297 | /* send the response to the VF */ | 2314 | /* send the response to the VF */ |
| 2298 | return ice_vc_send_msg_to_vf(vf, vc_op, v_ret, NULL, 0); | 2315 | return ice_vc_send_msg_to_vf(vf, vc_op, v_ret, NULL, 0); |
| 2299 | } | 2316 | } |
| @@ -2754,20 +2771,6 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) | |||
| 2754 | err = -EPERM; | 2771 | err = -EPERM; |
| 2755 | else | 2772 | else |
| 2756 | err = -EINVAL; | 2773 | err = -EINVAL; |
| 2757 | goto error_handler; | ||
| 2758 | } | ||
| 2759 | |||
| 2760 | /* Perform additional checks specific to RSS and Virtchnl */ | ||
| 2761 | if (v_opcode == VIRTCHNL_OP_CONFIG_RSS_KEY) { | ||
| 2762 | struct virtchnl_rss_key *vrk = (struct virtchnl_rss_key *)msg; | ||
| 2763 | |||
| 2764 | if (vrk->key_len != ICE_VSIQF_HKEY_ARRAY_SIZE) | ||
| 2765 | err = -EINVAL; | ||
| 2766 | } else if (v_opcode == VIRTCHNL_OP_CONFIG_RSS_LUT) { | ||
| 2767 | struct virtchnl_rss_lut *vrl = (struct virtchnl_rss_lut *)msg; | ||
| 2768 | |||
| 2769 | if (vrl->lut_entries != ICE_VSIQF_HLUT_ARRAY_SIZE) | ||
| 2770 | err = -EINVAL; | ||
| 2771 | } | 2774 | } |
| 2772 | 2775 | ||
| 2773 | error_handler: | 2776 | error_handler: |
