|
@@ -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)
|
|
@@ -886,18 +904,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 +932,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)) {
|
|
@@ -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);
|