diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index d87faad901fe..f952963d594e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -1,7 +1,7 @@ /* Broadcom NetXtreme-C/E network driver. * * Copyright (c) 2014-2016 Broadcom Corporation - * Copyright (c) 2016-2017 Broadcom Limited + * Copyright (c) 2016-2018 Broadcom Limited * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -121,6 +121,23 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting) return rc; } +int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted) +{ + struct bnxt *bp = netdev_priv(dev); + struct bnxt_vf_info *vf; + + if (bnxt_vf_ndo_prep(bp, vf_id)) + return -EINVAL; + + vf = &bp->pf.vf[vf_id]; + if (trusted) + vf->flags |= BNXT_VF_TRUST; + else + vf->flags &= ~BNXT_VF_TRUST; + + return 0; +} + int bnxt_get_vf_config(struct net_device *dev, int vf_id, struct ifla_vf_info *ivi) { @@ -147,6 +164,7 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id, else ivi->qos = 0; ivi->spoofchk = !!(vf->flags & BNXT_VF_SPOOFCHK); + ivi->trusted = !!(vf->flags & BNXT_VF_TRUST); if (!(vf->flags & BNXT_VF_LINK_FORCED)) ivi->linkstate = IFLA_VF_LINK_STATE_AUTO; else if (vf->flags & BNXT_VF_LINK_UP) @@ -492,18 +510,16 @@ static int bnxt_hwrm_func_vf_resc_cfg(struct bnxt *bp, int num_vfs) } mutex_unlock(&bp->hwrm_cmd_lock); if (pf->active_vfs) { - u16 n = 1; + u16 n = pf->active_vfs; - if (pf->vf_resv_strategy != BNXT_VF_RESV_STRATEGY_MINIMAL) - n = pf->active_vfs; - - hw_resc->max_tx_rings -= vf_tx_rings * n; - hw_resc->max_rx_rings -= vf_rx_rings * n; - hw_resc->max_hw_ring_grps -= vf_ring_grps * n; - hw_resc->max_cp_rings -= vf_cp_rings * n; + hw_resc->max_tx_rings -= le16_to_cpu(req.min_tx_rings) * n; + hw_resc->max_rx_rings -= le16_to_cpu(req.min_rx_rings) * n; + hw_resc->max_hw_ring_grps -= le16_to_cpu(req.min_hw_ring_grps) * + n; + hw_resc->max_cp_rings -= le16_to_cpu(req.min_cmpl_rings) * n; hw_resc->max_rsscos_ctxs -= pf->active_vfs; - hw_resc->max_stat_ctxs -= vf_stat_ctx * n; - hw_resc->max_vnics -= vf_vnics * n; + hw_resc->max_stat_ctxs -= le16_to_cpu(req.min_stat_ctx) * n; + hw_resc->max_vnics -= le16_to_cpu(req.min_vnics) * n; rc = pf->active_vfs; } @@ -886,18 +902,19 @@ exec_fwd_resp_exit: return rc; } -static int bnxt_vf_store_mac(struct bnxt *bp, struct bnxt_vf_info *vf) +static int bnxt_vf_configure_mac(struct bnxt *bp, struct bnxt_vf_info *vf) { u32 msg_size = sizeof(struct hwrm_func_vf_cfg_input); struct hwrm_func_vf_cfg_input *req = (struct hwrm_func_vf_cfg_input *)vf->hwrm_cmd_req_addr; - /* Only allow VF to set a valid MAC address if the PF assigned MAC - * address is zero + /* Allow VF to set a valid MAC address, if trust is set to on or + * if the PF assigned MAC address is zero */ if (req->enables & cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR)) { if (is_valid_ether_addr(req->dflt_mac_addr) && - !is_valid_ether_addr(vf->mac_addr)) { + ((vf->flags & BNXT_VF_TRUST) || + (!is_valid_ether_addr(vf->mac_addr)))) { ether_addr_copy(vf->vf_mac_addr, req->dflt_mac_addr); return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size); } @@ -913,11 +930,17 @@ static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf) (struct hwrm_cfa_l2_filter_alloc_input *)vf->hwrm_cmd_req_addr; bool mac_ok = false; - /* VF MAC address must first match PF MAC address, if it is valid. + if (!is_valid_ether_addr((const u8 *)req->l2_addr)) + return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size); + + /* Allow VF to set a valid MAC address, if trust is set to on. + * Or VF MAC address must first match MAC address in PF's context. * Otherwise, it must match the VF MAC address if firmware spec >= * 1.2.2 */ - if (is_valid_ether_addr(vf->mac_addr)) { + if (vf->flags & BNXT_VF_TRUST) { + mac_ok = true; + } else if (is_valid_ether_addr(vf->mac_addr)) { if (ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr)) mac_ok = true; } else if (is_valid_ether_addr(vf->vf_mac_addr)) { @@ -951,7 +974,9 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf) memcpy(&phy_qcfg_resp, &bp->link_info.phy_qcfg_resp, sizeof(phy_qcfg_resp)); mutex_unlock(&bp->hwrm_cmd_lock); + phy_qcfg_resp.resp_len = cpu_to_le16(sizeof(phy_qcfg_resp)); phy_qcfg_resp.seq_id = phy_qcfg_req->seq_id; + phy_qcfg_resp.valid = 1; if (vf->flags & BNXT_VF_LINK_UP) { /* if physical link is down, force link up on VF */ @@ -993,7 +1018,7 @@ static int bnxt_vf_req_validate_snd(struct bnxt *bp, struct bnxt_vf_info *vf) switch (req_type) { case HWRM_FUNC_VF_CFG: - rc = bnxt_vf_store_mac(bp, vf); + rc = bnxt_vf_configure_mac(bp, vf); break; case HWRM_CFA_L2_FILTER_ALLOC: rc = bnxt_vf_validate_set_mac(bp, vf); |