bnxt_en: Call firmware to approve VF MAC address change.
authorMichael Chan <michael.chan@broadcom.com>
Mon, 11 Apr 2016 08:11:13 +0000 (04:11 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 11 Apr 2016 18:58:45 +0000 (14:58 -0400)
Some hypervisors (e.g. ESX) require the VF MAC address to be forwarded to
the PF for approval.  In Linux PF, the call is not forwarded and the
firmware will simply check and approve the MAC address if the PF has not
previously administered a valid MAC address for this VF.

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_sriov.c
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h

index e874a564f40becf517ab39b29f8711b6a792b1a5..c83a5a1862d03912a488727c15a76cda5a648ff8 100644 (file)
@@ -5696,10 +5696,9 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
-#ifdef CONFIG_BNXT_SRIOV
-       if (BNXT_VF(bp) && is_valid_ether_addr(bp->vf.mac_addr))
-               return -EADDRNOTAVAIL;
-#endif
+       rc = bnxt_approve_mac(bp, addr->sa_data);
+       if (rc)
+               return rc;
 
        if (ether_addr_equal(addr->sa_data, dev->dev_addr))
                return 0;
index 8457850b0bdd37807839d1b35159d832316ba7b4..363884dd9e8ad6f0801dfa29c5b0c648fec34a4e 100644 (file)
@@ -865,6 +865,31 @@ update_vf_mac_exit:
        mutex_unlock(&bp->hwrm_cmd_lock);
 }
 
+int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
+{
+       struct hwrm_func_vf_cfg_input req = {0};
+       int rc = 0;
+
+       if (!BNXT_VF(bp))
+               return 0;
+
+       if (bp->hwrm_spec_code < 0x10202) {
+               if (is_valid_ether_addr(bp->vf.mac_addr))
+                       rc = -EADDRNOTAVAIL;
+               goto mac_done;
+       }
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1);
+       req.enables = cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR);
+       memcpy(req.dflt_mac_addr, mac, ETH_ALEN);
+       rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+mac_done:
+       if (rc) {
+               rc = -EADDRNOTAVAIL;
+               netdev_warn(bp->dev, "VF MAC address %pM not approved by the PF\n",
+                           mac);
+       }
+       return rc;
+}
 #else
 
 void bnxt_sriov_disable(struct bnxt *bp)
@@ -879,4 +904,9 @@ void bnxt_hwrm_exec_fwd_req(struct bnxt *bp)
 void bnxt_update_vf_mac(struct bnxt *bp)
 {
 }
+
+int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
+{
+       return 0;
+}
 #endif
index 3f08354a247e04e0ffa359f5e03ca23cd7951bff..0392670ab49c07e8c9b147b3eb71b8b2183ba371 100644 (file)
@@ -20,4 +20,5 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs);
 void bnxt_sriov_disable(struct bnxt *);
 void bnxt_hwrm_exec_fwd_req(struct bnxt *);
 void bnxt_update_vf_mac(struct bnxt *);
+int bnxt_approve_mac(struct bnxt *, u8 *);
 #endif