bnxt_en: Propagate trusted VF attribute to firmware.
authorMichael Chan <michael.chan@broadcom.com>
Tue, 19 Feb 2019 10:31:14 +0000 (05:31 -0500)
committerDavid S. Miller <davem@davemloft.net>
Tue, 19 Feb 2019 18:45:14 +0000 (10:45 -0800)
Newer firmware understands the concept of a trusted VF, so propagate the
trusted VF attribute set by the PF admin. to the firmware.  Also, check
the firmware trusted setting when considering the VF MAC address change
and reporting the trusted setting to the user.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c

index 0f7a34a3b004296be42763676f6410a05d2466d0..9700891a26b89e39b05e813e803ee829f3a96894 100644 (file)
@@ -6683,6 +6683,10 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
            VER_GET_RESP_DEV_CAPS_CFG_FLOW_HANDLE_64BIT_SUPPORTED)
                bp->fw_cap |= BNXT_FW_CAP_OVS_64BIT_HANDLE;
 
+       if (dev_caps_cfg &
+           VER_GET_RESP_DEV_CAPS_CFG_TRUSTED_VF_SUPPORTED)
+               bp->fw_cap |= BNXT_FW_CAP_TRUSTED_VF;
+
 hwrm_ver_get_exit:
        mutex_unlock(&bp->hwrm_cmd_lock);
        return rc;
index 17554d4be65156c329af297b3f972405cfb109f3..ecbe7d28a723555acb0fea405193b3537197fd09 100644 (file)
@@ -945,6 +945,7 @@ struct bnxt_vf_info {
                                         * stored by PF.
                                         */
        u16     vlan;
+       u16     func_qcfg_flags;
        u32     flags;
 #define BNXT_VF_QOS            0x1
 #define BNXT_VF_SPOOFCHK       0x2
@@ -1478,6 +1479,7 @@ struct bnxt {
        #define BNXT_FW_CAP_IF_CHANGE                   0x00000010
        #define BNXT_FW_CAP_KONG_MB_CHNL                0x00000080
        #define BNXT_FW_CAP_OVS_64BIT_HANDLE            0x00000400
+       #define BNXT_FW_CAP_TRUSTED_VF                  0x00000800
 
 #define BNXT_NEW_RM(bp)                ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
        u32                     hwrm_spec_code;
index d80f5c981d90399d5caec826bf5d599e810be272..2b90a2bb1a1d26a6905c51a1554e236efdeaf2bd 100644 (file)
@@ -121,6 +121,54 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting)
        return rc;
 }
 
+static int bnxt_hwrm_func_qcfg_flags(struct bnxt *bp, struct bnxt_vf_info *vf)
+{
+       struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+       struct hwrm_func_qcfg_input req = {0};
+       int rc;
+
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCFG, -1, -1);
+       req.fid = cpu_to_le16(vf->fw_fid);
+       mutex_lock(&bp->hwrm_cmd_lock);
+       rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (rc) {
+               mutex_unlock(&bp->hwrm_cmd_lock);
+               return -EIO;
+       }
+       vf->func_qcfg_flags = le16_to_cpu(resp->flags);
+       mutex_unlock(&bp->hwrm_cmd_lock);
+       return 0;
+}
+
+static bool bnxt_is_trusted_vf(struct bnxt *bp, struct bnxt_vf_info *vf)
+{
+       if (!(bp->fw_cap & BNXT_FW_CAP_TRUSTED_VF))
+               return !!(vf->flags & BNXT_VF_TRUST);
+
+       bnxt_hwrm_func_qcfg_flags(bp, vf);
+       return !!(vf->func_qcfg_flags & FUNC_QCFG_RESP_FLAGS_TRUSTED_VF);
+}
+
+static int bnxt_hwrm_set_trusted_vf(struct bnxt *bp, struct bnxt_vf_info *vf)
+{
+       struct hwrm_func_cfg_input req = {0};
+       int rc;
+
+       if (!(bp->fw_cap & BNXT_FW_CAP_TRUSTED_VF))
+               return 0;
+
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
+       req.fid = cpu_to_le16(vf->fw_fid);
+       if (vf->flags & BNXT_VF_TRUST)
+               req.flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_TRUSTED_VF_ENABLE);
+       else
+               req.flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_TRUSTED_VF_DISABLE);
+       rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (rc)
+               return -EIO;
+       return 0;
+}
+
 int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted)
 {
        struct bnxt *bp = netdev_priv(dev);
@@ -135,6 +183,7 @@ int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trusted)
        else
                vf->flags &= ~BNXT_VF_TRUST;
 
+       bnxt_hwrm_set_trusted_vf(bp, vf);
        return 0;
 }
 
@@ -164,7 +213,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);
+       ivi->trusted = bnxt_is_trusted_vf(bp, vf);
        if (!(vf->flags & BNXT_VF_LINK_FORCED))
                ivi->linkstate = IFLA_VF_LINK_STATE_AUTO;
        else if (vf->flags & BNXT_VF_LINK_UP)
@@ -935,9 +984,10 @@ static int bnxt_vf_configure_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
         * if the PF assigned MAC address is zero
         */
        if (req->enables & cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR)) {
+               bool trust = bnxt_is_trusted_vf(bp, vf);
+
                if (is_valid_ether_addr(req->dflt_mac_addr) &&
-                   ((vf->flags & BNXT_VF_TRUST) ||
-                    !is_valid_ether_addr(vf->mac_addr) ||
+                   (trust || !is_valid_ether_addr(vf->mac_addr) ||
                     ether_addr_equal(req->dflt_mac_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);
@@ -962,7 +1012,7 @@ static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
         * Otherwise, it must match the VF MAC address if firmware spec >=
         * 1.2.2
         */
-       if (vf->flags & BNXT_VF_TRUST) {
+       if (bnxt_is_trusted_vf(bp, vf)) {
                mac_ok = true;
        } else if (is_valid_ether_addr(vf->mac_addr)) {
                if (ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr))