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;
        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)
        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;