qed_iov_send_response(p_hwfn, p_ptt, vf, length, status);
 }
 
-static int qed_iov_vf_update_unicast_shadow(struct qed_hwfn *p_hwfn,
-                                           struct qed_vf_info *p_vf,
-                                           struct qed_filter_ucast *p_params)
+static int qed_iov_vf_update_vlan_shadow(struct qed_hwfn *p_hwfn,
+                                        struct qed_vf_info *p_vf,
+                                        struct qed_filter_ucast *p_params)
 {
        int i;
 
-       if (p_params->type == QED_FILTER_MAC)
-               return 0;
-
        /* First remove entries and then add new ones */
        if (p_params->opcode == QED_FILTER_REMOVE) {
                for (i = 0; i < QED_ETH_VF_NUM_VLAN_FILTERS + 1; i++)
        return 0;
 }
 
+static int qed_iov_vf_update_mac_shadow(struct qed_hwfn *p_hwfn,
+                                       struct qed_vf_info *p_vf,
+                                       struct qed_filter_ucast *p_params)
+{
+       int i;
+
+       /* If we're in forced-mode, we don't allow any change */
+       if (p_vf->bulletin.p_virt->valid_bitmap & (1 << MAC_ADDR_FORCED))
+               return 0;
+
+       /* First remove entries and then add new ones */
+       if (p_params->opcode == QED_FILTER_REMOVE) {
+               for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
+                       if (ether_addr_equal(p_vf->shadow_config.macs[i],
+                                            p_params->mac)) {
+                               memset(p_vf->shadow_config.macs[i], 0,
+                                      ETH_ALEN);
+                               break;
+                       }
+               }
+
+               if (i == QED_ETH_VF_NUM_MAC_FILTERS) {
+                       DP_VERBOSE(p_hwfn, QED_MSG_IOV,
+                                  "MAC isn't configured\n");
+                       return -EINVAL;
+               }
+       } else if (p_params->opcode == QED_FILTER_REPLACE ||
+                  p_params->opcode == QED_FILTER_FLUSH) {
+               for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++)
+                       memset(p_vf->shadow_config.macs[i], 0, ETH_ALEN);
+       }
+
+       /* List the new MAC address */
+       if (p_params->opcode != QED_FILTER_ADD &&
+           p_params->opcode != QED_FILTER_REPLACE)
+               return 0;
+
+       for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
+               if (is_zero_ether_addr(p_vf->shadow_config.macs[i])) {
+                       ether_addr_copy(p_vf->shadow_config.macs[i],
+                                       p_params->mac);
+                       DP_VERBOSE(p_hwfn, QED_MSG_IOV,
+                                  "Added MAC at %d entry in shadow\n", i);
+                       break;
+               }
+       }
+
+       if (i == QED_ETH_VF_NUM_MAC_FILTERS) {
+               DP_VERBOSE(p_hwfn, QED_MSG_IOV, "No available place for MAC\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int
+qed_iov_vf_update_unicast_shadow(struct qed_hwfn *p_hwfn,
+                                struct qed_vf_info *p_vf,
+                                struct qed_filter_ucast *p_params)
+{
+       int rc = 0;
+
+       if (p_params->type == QED_FILTER_MAC) {
+               rc = qed_iov_vf_update_mac_shadow(p_hwfn, p_vf, p_params);
+               if (rc)
+                       return rc;
+       }
+
+       if (p_params->type == QED_FILTER_VLAN)
+               rc = qed_iov_vf_update_vlan_shadow(p_hwfn, p_vf, p_params);
+
+       return rc;
+}
+
 int qed_iov_chk_ucast(struct qed_hwfn *hwfn,
                      int vfid, struct qed_filter_ucast *params)
 {