bnxt_en: Forward VF MAC address to the PF.
authorVasundhara Volam <vasundhara-v.volam@broadcom.com>
Wed, 17 Jan 2018 08:21:14 +0000 (03:21 -0500)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 Jan 2018 19:48:27 +0000 (14:48 -0500)
Forward hwrm_func_vf_cfg command from VF to PF driver, to store
VF MAC address in PF's context.  This will allow "ip link show"
to display all VF MAC addresses.

Maintain 2 locations of MAC address in VF info structure, one for
a PF assigned MAC and one for VF assigned MAC.

Display VF assigned MAC in "ip link show", only if PF assigned MAC is
not valid.

Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
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 e265219..ec8e623 100644 (file)
@@ -213,6 +213,7 @@ MODULE_DEVICE_TABLE(pci, bnxt_pci_tbl);
 
 static const u16 bnxt_vf_req_snif[] = {
        HWRM_FUNC_CFG,
+       HWRM_FUNC_VF_CFG,
        HWRM_PORT_PHY_QCFG,
        HWRM_CFA_L2_FILTER_ALLOC,
 };
@@ -8432,7 +8433,7 @@ static int bnxt_init_mac_addr(struct bnxt *bp)
                struct bnxt_vf_info *vf = &bp->vf;
 
                if (is_valid_ether_addr(vf->mac_addr)) {
-                       /* overwrite netdev dev_adr with admin VF MAC */
+                       /* overwrite netdev dev_addr with admin VF MAC */
                        memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
                } else {
                        eth_hw_addr_random(bp->dev);
index 920c19b..0b30dcc 100644 (file)
@@ -804,7 +804,10 @@ struct bnxt_hw_resc {
 #if defined(CONFIG_BNXT_SRIOV)
 struct bnxt_vf_info {
        u16     fw_fid;
-       u8      mac_addr[ETH_ALEN];
+       u8      mac_addr[ETH_ALEN];     /* PF assigned MAC Address */
+       u8      vf_mac_addr[ETH_ALEN];  /* VF assigned MAC address, only
+                                        * stored by PF.
+                                        */
        u16     vlan;
        u32     flags;
 #define BNXT_VF_QOS            0x1
index 508e917..d87faad 100644 (file)
@@ -135,7 +135,10 @@ int bnxt_get_vf_config(struct net_device *dev, int vf_id,
        ivi->vf = vf_id;
        vf = &bp->pf.vf[vf_id];
 
-       memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN);
+       if (is_valid_ether_addr(vf->mac_addr))
+               memcpy(&ivi->mac, vf->mac_addr, ETH_ALEN);
+       else
+               memcpy(&ivi->mac, vf->vf_mac_addr, ETH_ALEN);
        ivi->max_tx_rate = vf->max_tx_rate;
        ivi->min_tx_rate = vf->min_tx_rate;
        ivi->vlan = vf->vlan;
@@ -883,17 +886,51 @@ exec_fwd_resp_exit:
        return rc;
 }
 
+static int bnxt_vf_store_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
+        */
+       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)) {
+                       ether_addr_copy(vf->vf_mac_addr, req->dflt_mac_addr);
+                       return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size);
+               }
+               return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
+       }
+       return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size);
+}
+
 static int bnxt_vf_validate_set_mac(struct bnxt *bp, struct bnxt_vf_info *vf)
 {
        u32 msg_size = sizeof(struct hwrm_cfa_l2_filter_alloc_input);
        struct hwrm_cfa_l2_filter_alloc_input *req =
                (struct hwrm_cfa_l2_filter_alloc_input *)vf->hwrm_cmd_req_addr;
+       bool mac_ok = false;
 
-       if (!is_valid_ether_addr(vf->mac_addr) ||
-           ether_addr_equal((const u8 *)req->l2_addr, vf->mac_addr))
+       /* VF MAC address must first match PF MAC address, if it is valid.
+        * Otherwise, it must match the VF MAC address if firmware spec >=
+        * 1.2.2
+        */
+       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)) {
+               if (ether_addr_equal((const u8 *)req->l2_addr, vf->vf_mac_addr))
+                       mac_ok = true;
+       } else if (bp->hwrm_spec_code < 0x10202) {
+               mac_ok = true;
+       } else {
+               mac_ok = true;
+       }
+       if (mac_ok)
                return bnxt_hwrm_exec_fwd_resp(bp, vf, msg_size);
-       else
-               return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
+       return bnxt_hwrm_fwd_err_resp(bp, vf, msg_size);
 }
 
 static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)
@@ -955,6 +992,9 @@ static int bnxt_vf_req_validate_snd(struct bnxt *bp, struct bnxt_vf_info *vf)
        u32 req_type = le16_to_cpu(encap_req->req_type);
 
        switch (req_type) {
+       case HWRM_FUNC_VF_CFG:
+               rc = bnxt_vf_store_mac(bp, vf);
+               break;
        case HWRM_CFA_L2_FILTER_ALLOC:
                rc = bnxt_vf_validate_set_mac(bp, vf);
                break;