}
 
 static bool qed_iov_is_valid_vfid(struct qed_hwfn *p_hwfn,
-                                 int rel_vf_id, bool b_enabled_only)
+                                 int rel_vf_id,
+                                 bool b_enabled_only, bool b_non_malicious)
 {
        if (!p_hwfn->pf_iov_info) {
                DP_NOTICE(p_hwfn->cdev, "No iov info\n");
            b_enabled_only)
                return false;
 
+       if ((p_hwfn->pf_iov_info->vfs_array[rel_vf_id].b_malicious) &&
+           b_non_malicious)
+               return false;
+
        return true;
 }
 
                return NULL;
        }
 
-       if (qed_iov_is_valid_vfid(p_hwfn, relative_vf_id, b_enabled_only))
+       if (qed_iov_is_valid_vfid(p_hwfn, relative_vf_id,
+                                 b_enabled_only, false))
                vf = &p_hwfn->pf_iov_info->vfs_array[relative_vf_id];
        else
                DP_ERR(p_hwfn, "qed_iov_get_vf_info: VF[%d] is not enabled\n",
        return 0;
 }
 
-static bool qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn, int vfid)
+bool _qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn,
+                             int vfid, bool b_fail_malicious)
 {
        /* Check PF supports sriov */
        if (IS_VF(p_hwfn->cdev) || !IS_QED_SRIOV(p_hwfn->cdev) ||
                return false;
 
        /* Check VF validity */
-       if (!qed_iov_is_valid_vfid(p_hwfn, vfid, true))
+       if (!qed_iov_is_valid_vfid(p_hwfn, vfid, true, b_fail_malicious))
                return false;
 
        return true;
 }
 
+bool qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn, int vfid)
+{
+       return _qed_iov_pf_sanity_check(p_hwfn, vfid, true);
+}
+
 static void qed_iov_set_vf_to_disable(struct qed_dev *cdev,
                                      u16 rel_vf_id, u8 to_disable)
 {
 
        qed_iov_vf_igu_reset(p_hwfn, p_ptt, vf);
 
+       /* It's possible VF was previously considered malicious */
+       vf->b_malicious = false;
+
        rc = qed_mcp_config_vf_msix(p_hwfn, p_ptt, vf->abs_vf_id, vf->num_sbs);
        if (rc)
                return rc;
                        return rc;
                }
 
+               /* Workaround to make VF-PF channel ready, as FW
+                * doesn't do that as a part of FLR.
+                */
+               REG_WR(p_hwfn,
+                      GTT_BAR0_MAP_REG_USDM_RAM +
+                      USTORM_VF_PF_CHANNEL_READY_OFFSET(vfid), 1);
+
                /* VF_STOPPED has to be set only after final cleanup
                 * but prior to re-enabling the VF.
                 */
        mbx->first_tlv = mbx->req_virt->first_tlv;
 
        /* check if tlv type is known */
-       if (qed_iov_tlv_supported(mbx->first_tlv.tl.type)) {
+       if (qed_iov_tlv_supported(mbx->first_tlv.tl.type) &&
+           !p_vf->b_malicious) {
                switch (mbx->first_tlv.tl.type) {
                case CHANNEL_TLV_ACQUIRE:
                        qed_iov_vf_mbx_acquire(p_hwfn, p_ptt, p_vf);
                        qed_iov_vf_mbx_release(p_hwfn, p_ptt, p_vf);
                        break;
                }
+       } else if (qed_iov_tlv_supported(mbx->first_tlv.tl.type)) {
+               DP_VERBOSE(p_hwfn, QED_MSG_IOV,
+                          "VF [%02x] - considered malicious; Ignoring TLV [%04x]\n",
+                          p_vf->abs_vf_id, mbx->first_tlv.tl.type);
+
+               qed_iov_prepare_resp(p_hwfn, p_ptt, p_vf,
+                                    mbx->first_tlv.tl.type,
+                                    sizeof(struct pfvf_def_resp_tlv),
+                                    PFVF_STATUS_MALICIOUS);
        } else {
                /* unknown TLV - this may belong to a VF driver from the future
                 * - a version written after this PF driver was written, which
        memset(p_pending_events, 0, sizeof(u64) * QED_VF_ARRAY_LENGTH);
 }
 
-static int qed_sriov_vfpf_msg(struct qed_hwfn *p_hwfn,
-                             u16 abs_vfid, struct regpair *vf_msg)
+static struct qed_vf_info *qed_sriov_get_vf_from_absid(struct qed_hwfn *p_hwfn,
+                                                      u16 abs_vfid)
 {
-       u8 min = (u8)p_hwfn->cdev->p_iov_info->first_vf_in_pf;
-       struct qed_vf_info *p_vf;
+       u8 min = (u8) p_hwfn->cdev->p_iov_info->first_vf_in_pf;
 
-       if (!qed_iov_pf_sanity_check(p_hwfn, (int)abs_vfid - min)) {
+       if (!_qed_iov_pf_sanity_check(p_hwfn, (int)abs_vfid - min, false)) {
                DP_VERBOSE(p_hwfn,
                           QED_MSG_IOV,
-                          "Got a message from VF [abs 0x%08x] that cannot be handled by PF\n",
+                          "Got indication for VF [abs 0x%08x] that cannot be handled by PF\n",
                           abs_vfid);
-               return 0;
+               return NULL;
        }
-       p_vf = &p_hwfn->pf_iov_info->vfs_array[(u8)abs_vfid - min];
+
+       return &p_hwfn->pf_iov_info->vfs_array[(u8) abs_vfid - min];
+}
+
+static int qed_sriov_vfpf_msg(struct qed_hwfn *p_hwfn,
+                             u16 abs_vfid, struct regpair *vf_msg)
+{
+       struct qed_vf_info *p_vf = qed_sriov_get_vf_from_absid(p_hwfn,
+                          abs_vfid);
+
+       if (!p_vf)
+               return 0;
 
        /* List the physical address of the request so that handler
         * could later on copy the message from it.
        return 0;
 }
 
+static void qed_sriov_vfpf_malicious(struct qed_hwfn *p_hwfn,
+                                    struct malicious_vf_eqe_data *p_data)
+{
+       struct qed_vf_info *p_vf;
+
+       p_vf = qed_sriov_get_vf_from_absid(p_hwfn, p_data->vf_id);
+
+       if (!p_vf)
+               return;
+
+       DP_INFO(p_hwfn,
+               "VF [%d] - Malicious behavior [%02x]\n",
+               p_vf->abs_vf_id, p_data->err_id);
+
+       p_vf->b_malicious = true;
+}
+
 int qed_sriov_eqe_event(struct qed_hwfn *p_hwfn,
                        u8 opcode, __le16 echo, union event_ring_data *data)
 {
        case COMMON_EVENT_VF_PF_CHANNEL:
                return qed_sriov_vfpf_msg(p_hwfn, le16_to_cpu(echo),
                                          &data->vf_pf_channel.msg_addr);
+       case COMMON_EVENT_MALICIOUS_VF:
+               qed_sriov_vfpf_malicious(p_hwfn, &data->malicious_vf);
+               return 0;
        default:
                DP_INFO(p_hwfn->cdev, "Unknown sriov eqe event 0x%02x\n",
                        opcode);
                goto out;
 
        for (i = rel_vf_id; i < p_iov->total_vfs; i++)
-               if (qed_iov_is_valid_vfid(p_hwfn, rel_vf_id, true))
+               if (qed_iov_is_valid_vfid(p_hwfn, rel_vf_id, true, false))
                        return i;
 
 out:
                return;
        }
 
+       if (vf_info->b_malicious) {
+               DP_NOTICE(p_hwfn->cdev,
+                         "Can't set forced MAC to malicious VF [%d]\n", vfid);
+               return;
+       }
+
        feature = 1 << MAC_ADDR_FORCED;
        memcpy(vf_info->bulletin.p_virt->mac, mac, ETH_ALEN);
 
                return;
        }
 
+       if (vf_info->b_malicious) {
+               DP_NOTICE(p_hwfn->cdev,
+                         "Can't set forced vlan to malicious VF [%d]\n", vfid);
+               return;
+       }
+
        feature = 1 << VLAN_ADDR_FORCED;
        vf_info->bulletin.p_virt->pvid = pvid;
        if (pvid)
                qed_for_each_vf(hwfn, j) {
                        int k;
 
-                       if (!qed_iov_is_valid_vfid(hwfn, j, true))
+                       if (!qed_iov_is_valid_vfid(hwfn, j, true, false))
                                continue;
 
                        /* Wait until VF is disabled before releasing */
                num_sbs = min_t(int, sb_cnt_info.sb_free_blk, limit);
 
                for (i = 0; i < num; i++) {
-                       if (!qed_iov_is_valid_vfid(hwfn, i, false))
+                       if (!qed_iov_is_valid_vfid(hwfn, i, false, true))
                                continue;
 
                        rc = qed_iov_init_hw_for_vf(hwfn,
                return -EINVAL;
        }
 
-       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vfid, true)) {
+       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vfid, true, true)) {
                DP_VERBOSE(cdev, QED_MSG_IOV,
                           "Cannot set VF[%d] MAC (VF is not active)\n", vfid);
                return -EINVAL;
                return -EINVAL;
        }
 
-       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vfid, true)) {
+       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vfid, true, true)) {
                DP_VERBOSE(cdev, QED_MSG_IOV,
                           "Cannot set VF[%d] MAC (VF is not active)\n", vfid);
                return -EINVAL;
        if (IS_VF(cdev))
                return -EINVAL;
 
-       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vf_id, true)) {
+       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vf_id, true, false)) {
                DP_VERBOSE(cdev, QED_MSG_IOV,
                           "VF index [%d] isn't active\n", vf_id);
                return -EINVAL;
        if (IS_VF(cdev))
                return -EINVAL;
 
-       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vf_id, true)) {
+       if (!qed_iov_is_valid_vfid(&cdev->hwfns[0], vf_id, true, true)) {
                DP_VERBOSE(cdev, QED_MSG_IOV,
                           "VF index [%d] isn't active\n", vf_id);
                return -EINVAL;