vf->opaque_fid = (p_hwfn->hw_info.opaque_fid & 0xff) |
                                 (vf->abs_vf_id << 8);
                vf->vport_id = idx + 1;
+
+               vf->num_mac_filters = QED_ETH_VF_NUM_MAC_FILTERS;
+               vf->num_vlan_filters = QED_ETH_VF_NUM_VLAN_FILTERS;
        }
 }
 
 
        p_vf->vf_bulletin = 0;
        p_vf->vport_instance = 0;
-       p_vf->num_mac_filters = 0;
-       p_vf->num_vlan_filters = 0;
        p_vf->configured_features = 0;
 
        /* If VF previously requested less resources, go back to default */
        qed_iov_clean_vf(p_hwfn, p_vf->relative_vf_id);
 }
 
+static u8 qed_iov_vf_mbx_acquire_resc(struct qed_hwfn *p_hwfn,
+                                     struct qed_ptt *p_ptt,
+                                     struct qed_vf_info *p_vf,
+                                     struct vf_pf_resc_request *p_req,
+                                     struct pf_vf_resc *p_resp)
+{
+       int i;
+
+       /* Queue related information */
+       p_resp->num_rxqs = p_vf->num_rxqs;
+       p_resp->num_txqs = p_vf->num_txqs;
+       p_resp->num_sbs = p_vf->num_sbs;
+
+       for (i = 0; i < p_resp->num_sbs; i++) {
+               p_resp->hw_sbs[i].hw_sb_id = p_vf->igu_sbs[i];
+               p_resp->hw_sbs[i].sb_qid = 0;
+       }
+
+       /* These fields are filled for backward compatibility.
+        * Unused by modern vfs.
+        */
+       for (i = 0; i < p_resp->num_rxqs; i++) {
+               qed_fw_l2_queue(p_hwfn, p_vf->vf_queues[i].fw_rx_qid,
+                               (u16 *)&p_resp->hw_qid[i]);
+               p_resp->cid[i] = p_vf->vf_queues[i].fw_cid;
+       }
+
+       /* Filter related information */
+       p_resp->num_mac_filters = min_t(u8, p_vf->num_mac_filters,
+                                       p_req->num_mac_filters);
+       p_resp->num_vlan_filters = min_t(u8, p_vf->num_vlan_filters,
+                                        p_req->num_vlan_filters);
+
+       /* This isn't really needed/enforced, but some legacy VFs might depend
+        * on the correct filling of this field.
+        */
+       p_resp->num_mc_filters = QED_MAX_MC_ADDRS;
+
+       /* Validate sufficient resources for VF */
+       if (p_resp->num_rxqs < p_req->num_rxqs ||
+           p_resp->num_txqs < p_req->num_txqs ||
+           p_resp->num_sbs < p_req->num_sbs ||
+           p_resp->num_mac_filters < p_req->num_mac_filters ||
+           p_resp->num_vlan_filters < p_req->num_vlan_filters ||
+           p_resp->num_mc_filters < p_req->num_mc_filters) {
+               DP_VERBOSE(p_hwfn,
+                          QED_MSG_IOV,
+                          "VF[%d] - Insufficient resources: rxq [%02x/%02x] txq [%02x/%02x] sbs [%02x/%02x] mac [%02x/%02x] vlan [%02x/%02x] mc [%02x/%02x]\n",
+                          p_vf->abs_vf_id,
+                          p_req->num_rxqs,
+                          p_resp->num_rxqs,
+                          p_req->num_rxqs,
+                          p_resp->num_txqs,
+                          p_req->num_sbs,
+                          p_resp->num_sbs,
+                          p_req->num_mac_filters,
+                          p_resp->num_mac_filters,
+                          p_req->num_vlan_filters,
+                          p_resp->num_vlan_filters,
+                          p_req->num_mc_filters, p_resp->num_mc_filters);
+               return PFVF_STATUS_NO_RESOURCE;
+       }
+
+       return PFVF_STATUS_SUCCESS;
+}
+
+static void qed_iov_vf_mbx_acquire_stats(struct qed_hwfn *p_hwfn,
+                                        struct pfvf_stats_info *p_stats)
+{
+       p_stats->mstats.address = PXP_VF_BAR0_START_MSDM_ZONE_B +
+                                 offsetof(struct mstorm_vf_zone,
+                                          non_trigger.eth_queue_stat);
+       p_stats->mstats.len = sizeof(struct eth_mstorm_per_queue_stat);
+       p_stats->ustats.address = PXP_VF_BAR0_START_USDM_ZONE_B +
+                                 offsetof(struct ustorm_vf_zone,
+                                          non_trigger.eth_queue_stat);
+       p_stats->ustats.len = sizeof(struct eth_ustorm_per_queue_stat);
+       p_stats->pstats.address = PXP_VF_BAR0_START_PSDM_ZONE_B +
+                                 offsetof(struct pstorm_vf_zone,
+                                          non_trigger.eth_queue_stat);
+       p_stats->pstats.len = sizeof(struct eth_pstorm_per_queue_stat);
+       p_stats->tstats.address = 0;
+       p_stats->tstats.len = 0;
+}
+
 static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
                                   struct qed_ptt *p_ptt,
                                   struct qed_vf_info *vf)
        struct pfvf_acquire_resp_tlv *resp = &mbx->reply_virt->acquire_resp;
        struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info;
        struct vfpf_acquire_tlv *req = &mbx->req_virt->acquire;
-       u8 i, vfpf_status = PFVF_STATUS_NOT_SUPPORTED;
+       u8 vfpf_status = PFVF_STATUS_NOT_SUPPORTED;
        struct pf_vf_resc *resc = &resp->resc;
        int rc;
 
        /* Store the acquire message */
        memcpy(&vf->acquire, req, sizeof(vf->acquire));
 
-       /* Fill in vf info stuff */
        vf->opaque_fid = req->vfdev_info.opaque_fid;
-       vf->num_mac_filters = 1;
-       vf->num_vlan_filters = QED_ETH_VF_NUM_VLAN_FILTERS;
 
        vf->vf_bulletin = req->bulletin_addr;
        vf->bulletin.size = (vf->bulletin.size < req->bulletin_size) ?
        if (p_hwfn->cdev->num_hwfns > 1)
                pfdev_info->capabilities |= PFVF_ACQUIRE_CAP_100G;
 
-       pfdev_info->stats_info.mstats.address =
-           PXP_VF_BAR0_START_MSDM_ZONE_B +
-           offsetof(struct mstorm_vf_zone, non_trigger.eth_queue_stat);
-       pfdev_info->stats_info.mstats.len =
-           sizeof(struct eth_mstorm_per_queue_stat);
-
-       pfdev_info->stats_info.ustats.address =
-           PXP_VF_BAR0_START_USDM_ZONE_B +
-           offsetof(struct ustorm_vf_zone, non_trigger.eth_queue_stat);
-       pfdev_info->stats_info.ustats.len =
-           sizeof(struct eth_ustorm_per_queue_stat);
-
-       pfdev_info->stats_info.pstats.address =
-           PXP_VF_BAR0_START_PSDM_ZONE_B +
-           offsetof(struct pstorm_vf_zone, non_trigger.eth_queue_stat);
-       pfdev_info->stats_info.pstats.len =
-           sizeof(struct eth_pstorm_per_queue_stat);
-
-       pfdev_info->stats_info.tstats.address = 0;
-       pfdev_info->stats_info.tstats.len = 0;
+       qed_iov_vf_mbx_acquire_stats(p_hwfn, &pfdev_info->stats_info);
 
        memcpy(pfdev_info->port_mac, p_hwfn->hw_info.hw_mac_addr, ETH_ALEN);
 
        pfdev_info->dev_type = p_hwfn->cdev->type;
        pfdev_info->chip_rev = p_hwfn->cdev->chip_rev;
 
-       resc->num_rxqs = vf->num_rxqs;
-       resc->num_txqs = vf->num_txqs;
-       resc->num_sbs = vf->num_sbs;
-       for (i = 0; i < resc->num_sbs; i++) {
-               resc->hw_sbs[i].hw_sb_id = vf->igu_sbs[i];
-               resc->hw_sbs[i].sb_qid = 0;
-       }
-
-       for (i = 0; i < resc->num_rxqs; i++) {
-               qed_fw_l2_queue(p_hwfn, vf->vf_queues[i].fw_rx_qid,
-                               (u16 *)&resc->hw_qid[i]);
-               resc->cid[i] = vf->vf_queues[i].fw_cid;
-       }
-
-       resc->num_mac_filters = min_t(u8, vf->num_mac_filters,
-                                     req->resc_request.num_mac_filters);
-       resc->num_vlan_filters = min_t(u8, vf->num_vlan_filters,
-                                      req->resc_request.num_vlan_filters);
-
-       /* This isn't really required as VF isn't limited, but some VFs might
-        * actually test this value, so need to provide it.
+       /* Fill resources available to VF; Make sure there are enough to
+        * satisfy the VF's request.
         */
-       resc->num_mc_filters = req->resc_request.num_mc_filters;
+       vfpf_status = qed_iov_vf_mbx_acquire_resc(p_hwfn, p_ptt, vf,
+                                                 &req->resc_request, resc);
+       if (vfpf_status != PFVF_STATUS_SUCCESS)
+               goto out;
 
        /* Start the VF in FW */
        rc = qed_sp_vf_start(p_hwfn, vf);
 
 }
 
 #define VF_ACQUIRE_THRESH 3
-#define VF_ACQUIRE_MAC_FILTERS 1
+static void qed_vf_pf_acquire_reduce_resc(struct qed_hwfn *p_hwfn,
+                                         struct vf_pf_resc_request *p_req,
+                                         struct pf_vf_resc *p_resp)
+{
+       DP_VERBOSE(p_hwfn,
+                  QED_MSG_IOV,
+                  "PF unwilling to fullill resource request: rxq [%02x/%02x] txq [%02x/%02x] sbs [%02x/%02x] mac [%02x/%02x] vlan [%02x/%02x] mc [%02x/%02x]. Try PF recommended amount\n",
+                  p_req->num_rxqs,
+                  p_resp->num_rxqs,
+                  p_req->num_rxqs,
+                  p_resp->num_txqs,
+                  p_req->num_sbs,
+                  p_resp->num_sbs,
+                  p_req->num_mac_filters,
+                  p_resp->num_mac_filters,
+                  p_req->num_vlan_filters,
+                  p_resp->num_vlan_filters,
+                  p_req->num_mc_filters, p_resp->num_mc_filters);
+
+       /* humble our request */
+       p_req->num_txqs = p_resp->num_txqs;
+       p_req->num_rxqs = p_resp->num_rxqs;
+       p_req->num_sbs = p_resp->num_sbs;
+       p_req->num_mac_filters = p_resp->num_mac_filters;
+       p_req->num_vlan_filters = p_resp->num_vlan_filters;
+       p_req->num_mc_filters = p_resp->num_mc_filters;
+}
 
 static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn)
 {
        struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
        struct pfvf_acquire_resp_tlv *resp = &p_iov->pf2vf_reply->acquire_resp;
        struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info;
-       u8 rx_count = 1, tx_count = 1, num_sbs = 1;
-       u8 num_mac = VF_ACQUIRE_MAC_FILTERS;
+       struct vf_pf_resc_request *p_resc;
        bool resources_acquired = false;
        struct vfpf_acquire_tlv *req;
        int rc = 0, attempts = 0;
 
        /* clear mailbox and prep first tlv */
        req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_ACQUIRE, sizeof(*req));
+       p_resc = &req->resc_request;
 
        /* starting filling the request */
        req->vfdev_info.opaque_fid = p_hwfn->hw_info.opaque_fid;
 
-       req->resc_request.num_rxqs = rx_count;
-       req->resc_request.num_txqs = tx_count;
-       req->resc_request.num_sbs = num_sbs;
-       req->resc_request.num_mac_filters = num_mac;
-       req->resc_request.num_vlan_filters = QED_ETH_VF_NUM_VLAN_FILTERS;
+       p_resc->num_rxqs = QED_MAX_VF_CHAINS_PER_PF;
+       p_resc->num_txqs = QED_MAX_VF_CHAINS_PER_PF;
+       p_resc->num_sbs = QED_MAX_VF_CHAINS_PER_PF;
+       p_resc->num_mac_filters = QED_ETH_VF_NUM_MAC_FILTERS;
+       p_resc->num_vlan_filters = QED_ETH_VF_NUM_VLAN_FILTERS;
 
        req->vfdev_info.os_type = VFPF_ACQUIRE_OS_LINUX;
        req->vfdev_info.fw_major = FW_MAJOR_VERSION;
                        resources_acquired = true;
                } else if (resp->hdr.status == PFVF_STATUS_NO_RESOURCE &&
                           attempts < VF_ACQUIRE_THRESH) {
-                       DP_VERBOSE(p_hwfn,
-                                  QED_MSG_IOV,
-                                  "PF unwilling to fullfill resource request. Try PF recommended amount\n");
-
-                       /* humble our request */
-                       req->resc_request.num_txqs = resp->resc.num_txqs;
-                       req->resc_request.num_rxqs = resp->resc.num_rxqs;
-                       req->resc_request.num_sbs = resp->resc.num_sbs;
-                       req->resc_request.num_mac_filters =
-                           resp->resc.num_mac_filters;
-                       req->resc_request.num_vlan_filters =
-                           resp->resc.num_vlan_filters;
+                       qed_vf_pf_acquire_reduce_resc(p_hwfn, p_resc,
+                                                     &resp->resc);
 
                        /* Clear response buffer */
                        memset(p_iov->pf2vf_reply, 0, sizeof(union pfvf_tlvs));