struct mlx4_cmd_mailbox *outbox,
                                struct mlx4_cmd_info *cmd)
 {
+       struct mlx4_priv *priv = mlx4_priv(dev);
        u8      field;
        u32     size;
        int     err = 0;
                field = 0; /* protected FMR support not available as yet */
                MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET);
 
-               size = dev->caps.num_qps;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
 
-               size = dev->caps.num_srqs;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
 
-               size = dev->caps.num_cqs;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
 
                size = dev->caps.num_eqs;
                size = dev->caps.reserved_eqs;
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET);
 
-               size = dev->caps.num_mpts;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
 
-               size = dev->caps.num_mtts;
+               size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave];
                MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
 
                size = dev->caps.num_mgms + dev->caps.num_amgms;
 
        }
 
        dev->caps.num_ports             = func_cap.num_ports;
-       dev->caps.num_qps               = func_cap.qp_quota;
-       dev->caps.num_srqs              = func_cap.srq_quota;
-       dev->caps.num_cqs               = func_cap.cq_quota;
-       dev->caps.num_eqs               = func_cap.max_eq;
-       dev->caps.reserved_eqs          = func_cap.reserved_eq;
-       dev->caps.num_mpts              = func_cap.mpt_quota;
-       dev->caps.num_mtts              = func_cap.mtt_quota;
+       dev->quotas.qp                  = func_cap.qp_quota;
+       dev->quotas.srq                 = func_cap.srq_quota;
+       dev->quotas.cq                  = func_cap.cq_quota;
+       dev->quotas.mpt                 = func_cap.mpt_quota;
+       dev->quotas.mtt                 = func_cap.mtt_quota;
+       dev->caps.num_qps               = 1 << hca_param.log_num_qps;
+       dev->caps.num_srqs              = 1 << hca_param.log_num_srqs;
+       dev->caps.num_cqs               = 1 << hca_param.log_num_cqs;
+       dev->caps.num_mpts              = 1 << hca_param.log_mpt_sz;
+       dev->caps.num_eqs               = func_cap.max_eq;
+       dev->caps.reserved_eqs          = func_cap.reserved_eq;
        dev->caps.num_pds               = MLX4_NUM_PDS;
        dev->caps.num_mgms              = 0;
        dev->caps.num_amgms             = 0;
                        "aborting.\n");
                return err;
        }
-       if (num_vfs > MLX4_MAX_NUM_VF) {
-               printk(KERN_ERR "There are more VF's (%d) than allowed(%d)\n",
-                      num_vfs, MLX4_MAX_NUM_VF);
+
+       /* Due to requirement that all VFs and the PF are *guaranteed* 2 MACS
+        * per port, we must limit the number of VFs to 63 (since their are
+        * 128 MACs)
+        */
+       if (num_vfs >= MLX4_MAX_NUM_VF) {
+               dev_err(&pdev->dev,
+                       "Requested more VF's (%d) than allowed (%d)\n",
+                       num_vfs, MLX4_MAX_NUM_VF - 1);
                return -EINVAL;
        }
 
        if (err)
                goto err_steer;
 
+       mlx4_init_quotas(dev);
+
        for (port = 1; port <= dev->caps.num_ports; port++) {
                err = mlx4_init_port_info(dev, port);
                if (err)
 
 }
 
 static void rem_slave_vlans(struct mlx4_dev *dev, int slave);
+static inline void initialize_res_quotas(struct mlx4_dev *dev,
+                                        struct resource_allocator *res_alloc,
+                                        enum mlx4_resource res_type,
+                                        int vf, int num_instances)
+{
+       res_alloc->guaranteed[vf] = num_instances / (2 * (dev->num_vfs + 1));
+       res_alloc->quota[vf] = (num_instances / 2) + res_alloc->guaranteed[vf];
+       if (vf == mlx4_master_func_num(dev)) {
+               res_alloc->res_free = num_instances;
+               if (res_type == RES_MTT) {
+                       /* reserved mtts will be taken out of the PF allocation */
+                       res_alloc->res_free += dev->caps.reserved_mtts;
+                       res_alloc->guaranteed[vf] += dev->caps.reserved_mtts;
+                       res_alloc->quota[vf] += dev->caps.reserved_mtts;
+               }
+       }
+}
+
+void mlx4_init_quotas(struct mlx4_dev *dev)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       int pf;
+
+       /* quotas for VFs are initialized in mlx4_slave_cap */
+       if (mlx4_is_slave(dev))
+               return;
+
+       if (!mlx4_is_mfunc(dev)) {
+               dev->quotas.qp = dev->caps.num_qps - dev->caps.reserved_qps -
+                       mlx4_num_reserved_sqps(dev);
+               dev->quotas.cq = dev->caps.num_cqs - dev->caps.reserved_cqs;
+               dev->quotas.srq = dev->caps.num_srqs - dev->caps.reserved_srqs;
+               dev->quotas.mtt = dev->caps.num_mtts - dev->caps.reserved_mtts;
+               dev->quotas.mpt = dev->caps.num_mpts - dev->caps.reserved_mrws;
+               return;
+       }
+
+       pf = mlx4_master_func_num(dev);
+       dev->quotas.qp =
+               priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[pf];
+       dev->quotas.cq =
+               priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[pf];
+       dev->quotas.srq =
+               priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[pf];
+       dev->quotas.mtt =
+               priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[pf];
+       dev->quotas.mpt =
+               priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf];
+}
 int mlx4_init_resource_tracker(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
-       int i;
+       int i, j;
        int t;
 
        priv->mfunc.master.res_tracker.slave_list =
        for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++)
                priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT;
 
+       for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
+               struct resource_allocator *res_alloc =
+                       &priv->mfunc.master.res_tracker.res_alloc[i];
+               res_alloc->quota = kmalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL);
+               res_alloc->guaranteed = kmalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL);
+               if (i == RES_MAC || i == RES_VLAN)
+                       res_alloc->allocated = kzalloc(MLX4_MAX_PORTS *
+                                                      (dev->num_vfs + 1) * sizeof(int),
+                                                       GFP_KERNEL);
+               else
+                       res_alloc->allocated = kzalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL);
+
+               if (!res_alloc->quota || !res_alloc->guaranteed ||
+                   !res_alloc->allocated)
+                       goto no_mem_err;
+
+               for (t = 0; t < dev->num_vfs + 1; t++) {
+                       switch (i) {
+                       case RES_QP:
+                               initialize_res_quotas(dev, res_alloc, RES_QP,
+                                                     t, dev->caps.num_qps -
+                                                     dev->caps.reserved_qps -
+                                                     mlx4_num_reserved_sqps(dev));
+                               break;
+                       case RES_CQ:
+                               initialize_res_quotas(dev, res_alloc, RES_CQ,
+                                                     t, dev->caps.num_cqs -
+                                                     dev->caps.reserved_cqs);
+                               break;
+                       case RES_SRQ:
+                               initialize_res_quotas(dev, res_alloc, RES_SRQ,
+                                                     t, dev->caps.num_srqs -
+                                                     dev->caps.reserved_srqs);
+                               break;
+                       case RES_MPT:
+                               initialize_res_quotas(dev, res_alloc, RES_MPT,
+                                                     t, dev->caps.num_mpts -
+                                                     dev->caps.reserved_mrws);
+                               break;
+                       case RES_MTT:
+                               initialize_res_quotas(dev, res_alloc, RES_MTT,
+                                                     t, dev->caps.num_mtts -
+                                                     dev->caps.reserved_mtts);
+                               break;
+                       case RES_MAC:
+                               if (t == mlx4_master_func_num(dev)) {
+                                       res_alloc->quota[t] = MLX4_MAX_MAC_NUM;
+                                       res_alloc->guaranteed[t] = 2;
+                                       for (j = 0; j < MLX4_MAX_PORTS; j++)
+                                               res_alloc->res_port_free[j] = MLX4_MAX_MAC_NUM;
+                               } else {
+                                       res_alloc->quota[t] = MLX4_MAX_MAC_NUM;
+                                       res_alloc->guaranteed[t] = 2;
+                               }
+                               break;
+                       case RES_VLAN:
+                               if (t == mlx4_master_func_num(dev)) {
+                                       res_alloc->quota[t] = MLX4_MAX_VLAN_NUM;
+                                       res_alloc->guaranteed[t] = MLX4_MAX_VLAN_NUM / 2;
+                                       for (j = 0; j < MLX4_MAX_PORTS; j++)
+                                               res_alloc->res_port_free[j] =
+                                                       res_alloc->quota[t];
+                               } else {
+                                       res_alloc->quota[t] = MLX4_MAX_VLAN_NUM / 2;
+                                       res_alloc->guaranteed[t] = 0;
+                               }
+                               break;
+                       case RES_COUNTER:
+                               res_alloc->quota[t] = dev->caps.max_counters;
+                               res_alloc->guaranteed[t] = 0;
+                               if (t == mlx4_master_func_num(dev))
+                                       res_alloc->res_free = res_alloc->quota[t];
+                               break;
+                       default:
+                               break;
+                       }
+                       if (i == RES_MAC || i == RES_VLAN) {
+                               for (j = 0; j < MLX4_MAX_PORTS; j++)
+                                       res_alloc->res_port_rsvd[j] +=
+                                               res_alloc->guaranteed[t];
+                       } else {
+                               res_alloc->res_reserved += res_alloc->guaranteed[t];
+                       }
+               }
+       }
        spin_lock_init(&priv->mfunc.master.res_tracker.lock);
-       return 0 ;
+       return 0;
+
+no_mem_err:
+       for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
+               kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
+               priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
+               kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
+               priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
+               kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
+               priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
+       }
+       return -ENOMEM;
 }
 
 void mlx4_free_resource_tracker(struct mlx4_dev *dev,
                }
 
                if (type != RES_TR_FREE_SLAVES_ONLY) {
+                       for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
+                               kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
+                               priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
+                               kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
+                               priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
+                               kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
+                               priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
+                       }
                        kfree(priv->mfunc.master.res_tracker.slave_list);
                        priv->mfunc.master.res_tracker.slave_list = NULL;
                }