aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx4/main.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c99
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h21
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c87
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c510
-rw-r--r--include/linux/mlx4/device.h20
11 files changed, 675 insertions, 120 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index f0612645de99..7567437dbd34 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -177,18 +177,18 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
177 177
178 props->max_mr_size = ~0ull; 178 props->max_mr_size = ~0ull;
179 props->page_size_cap = dev->dev->caps.page_size_cap; 179 props->page_size_cap = dev->dev->caps.page_size_cap;
180 props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; 180 props->max_qp = dev->dev->quotas.qp;
181 props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; 181 props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE;
182 props->max_sge = min(dev->dev->caps.max_sq_sg, 182 props->max_sge = min(dev->dev->caps.max_sq_sg,
183 dev->dev->caps.max_rq_sg); 183 dev->dev->caps.max_rq_sg);
184 props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; 184 props->max_cq = dev->dev->quotas.cq;
185 props->max_cqe = dev->dev->caps.max_cqes; 185 props->max_cqe = dev->dev->caps.max_cqes;
186 props->max_mr = dev->dev->caps.num_mpts - dev->dev->caps.reserved_mrws; 186 props->max_mr = dev->dev->quotas.mpt;
187 props->max_pd = dev->dev->caps.num_pds - dev->dev->caps.reserved_pds; 187 props->max_pd = dev->dev->caps.num_pds - dev->dev->caps.reserved_pds;
188 props->max_qp_rd_atom = dev->dev->caps.max_qp_dest_rdma; 188 props->max_qp_rd_atom = dev->dev->caps.max_qp_dest_rdma;
189 props->max_qp_init_rd_atom = dev->dev->caps.max_qp_init_rdma; 189 props->max_qp_init_rd_atom = dev->dev->caps.max_qp_init_rdma;
190 props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp; 190 props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
191 props->max_srq = dev->dev->caps.num_srqs - dev->dev->caps.reserved_srqs; 191 props->max_srq = dev->dev->quotas.srq;
192 props->max_srq_wr = dev->dev->caps.max_srq_wqes - 1; 192 props->max_srq_wr = dev->dev->caps.max_srq_wqes - 1;
193 props->max_srq_sge = dev->dev->caps.max_srq_sge; 193 props->max_srq_sge = dev->dev->caps.max_srq_sge;
194 props->max_fast_reg_page_list_len = MLX4_MAX_FAST_REG_PAGES; 194 props->max_fast_reg_page_list_len = MLX4_MAX_FAST_REG_PAGES;
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index ae8eb4c4fb6c..65d41b76fa2c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1687,7 +1687,7 @@ static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave
1687 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; 1687 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
1688 if (NO_INDX != vp_oper->vlan_idx) { 1688 if (NO_INDX != vp_oper->vlan_idx) {
1689 __mlx4_unregister_vlan(&priv->dev, 1689 __mlx4_unregister_vlan(&priv->dev,
1690 port, vp_oper->vlan_idx); 1690 port, vp_oper->state.default_vlan);
1691 vp_oper->vlan_idx = NO_INDX; 1691 vp_oper->vlan_idx = NO_INDX;
1692 } 1692 }
1693 if (NO_INDX != vp_oper->mac_idx) { 1693 if (NO_INDX != vp_oper->mac_idx) {
@@ -1718,6 +1718,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
1718 if (cmd == MLX4_COMM_CMD_RESET) { 1718 if (cmd == MLX4_COMM_CMD_RESET) {
1719 mlx4_warn(dev, "Received reset from slave:%d\n", slave); 1719 mlx4_warn(dev, "Received reset from slave:%d\n", slave);
1720 slave_state[slave].active = false; 1720 slave_state[slave].active = false;
1721 slave_state[slave].old_vlan_api = false;
1721 mlx4_master_deactivate_admin_state(priv, slave); 1722 mlx4_master_deactivate_admin_state(priv, slave);
1722 for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) { 1723 for (i = 0; i < MLX4_EVENT_TYPES_NUM; ++i) {
1723 slave_state[slave].event_eq[i].eqn = -1; 1724 slave_state[slave].event_eq[i].eqn = -1;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 85d91665d400..b5554121aca4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -417,7 +417,6 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev,
417 struct mlx4_en_priv *priv = netdev_priv(dev); 417 struct mlx4_en_priv *priv = netdev_priv(dev);
418 struct mlx4_en_dev *mdev = priv->mdev; 418 struct mlx4_en_dev *mdev = priv->mdev;
419 int err; 419 int err;
420 int idx;
421 420
422 en_dbg(HW, priv, "Killing VID:%d\n", vid); 421 en_dbg(HW, priv, "Killing VID:%d\n", vid);
423 422
@@ -425,10 +424,7 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev,
425 424
426 /* Remove VID from port VLAN filter */ 425 /* Remove VID from port VLAN filter */
427 mutex_lock(&mdev->state_lock); 426 mutex_lock(&mdev->state_lock);
428 if (!mlx4_find_cached_vlan(mdev->dev, priv->port, vid, &idx)) 427 mlx4_unregister_vlan(mdev->dev, priv->port, vid);
429 mlx4_unregister_vlan(mdev->dev, priv->port, idx);
430 else
431 en_dbg(HW, priv, "could not find vid %d in cache\n", vid);
432 428
433 if (mdev->device_up && priv->port_up) { 429 if (mdev->device_up && priv->port_up) {
434 err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); 430 err = mlx4_SET_VLAN_FLTR(mdev->dev, priv);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index c151e7a6710a..c3e70bc2d875 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -177,6 +177,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
177 struct mlx4_cmd_mailbox *outbox, 177 struct mlx4_cmd_mailbox *outbox,
178 struct mlx4_cmd_info *cmd) 178 struct mlx4_cmd_info *cmd)
179{ 179{
180 struct mlx4_priv *priv = mlx4_priv(dev);
180 u8 field; 181 u8 field;
181 u32 size; 182 u32 size;
182 int err = 0; 183 int err = 0;
@@ -185,18 +186,26 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
185#define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 186#define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1
186#define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 187#define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4
187#define QUERY_FUNC_CAP_FMR_OFFSET 0x8 188#define QUERY_FUNC_CAP_FMR_OFFSET 0x8
188#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x10 189#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP 0x10
189#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x14 190#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP 0x14
190#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x18 191#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP 0x18
191#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET 0x20 192#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP 0x20
192#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET 0x24 193#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP 0x24
193#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x28 194#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP 0x28
194#define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c 195#define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c
195#define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0x30 196#define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0x30
196 197
198#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x50
199#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x54
200#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x58
201#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET 0x60
202#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET 0x64
203#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x68
204
197#define QUERY_FUNC_CAP_FMR_FLAG 0x80 205#define QUERY_FUNC_CAP_FMR_FLAG 0x80
198#define QUERY_FUNC_CAP_FLAG_RDMA 0x40 206#define QUERY_FUNC_CAP_FLAG_RDMA 0x40
199#define QUERY_FUNC_CAP_FLAG_ETH 0x80 207#define QUERY_FUNC_CAP_FLAG_ETH 0x80
208#define QUERY_FUNC_CAP_FLAG_QUOTAS 0x10
200 209
201/* when opcode modifier = 1 */ 210/* when opcode modifier = 1 */
202#define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 211#define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3
@@ -237,8 +246,9 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
237 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY); 246 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_PROXY);
238 247
239 } else if (vhcr->op_modifier == 0) { 248 } else if (vhcr->op_modifier == 0) {
240 /* enable rdma and ethernet interfaces */ 249 /* enable rdma and ethernet interfaces, and new quota locations */
241 field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA); 250 field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA |
251 QUERY_FUNC_CAP_FLAG_QUOTAS);
242 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); 252 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET);
243 253
244 field = dev->caps.num_ports; 254 field = dev->caps.num_ports;
@@ -250,14 +260,20 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
250 field = 0; /* protected FMR support not available as yet */ 260 field = 0; /* protected FMR support not available as yet */
251 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET); 261 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET);
252 262
253 size = dev->caps.num_qps; 263 size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave];
254 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 264 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
265 size = dev->caps.num_qps;
266 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP);
255 267
256 size = dev->caps.num_srqs; 268 size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave];
257 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 269 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
270 size = dev->caps.num_srqs;
271 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP);
258 272
259 size = dev->caps.num_cqs; 273 size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave];
260 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 274 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
275 size = dev->caps.num_cqs;
276 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP);
261 277
262 size = dev->caps.num_eqs; 278 size = dev->caps.num_eqs;
263 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 279 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET);
@@ -265,14 +281,19 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave,
265 size = dev->caps.reserved_eqs; 281 size = dev->caps.reserved_eqs;
266 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 282 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET);
267 283
268 size = dev->caps.num_mpts; 284 size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave];
269 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); 285 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
286 size = dev->caps.num_mpts;
287 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP);
270 288
271 size = dev->caps.num_mtts; 289 size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave];
272 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); 290 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
291 size = dev->caps.num_mtts;
292 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP);
273 293
274 size = dev->caps.num_mgms + dev->caps.num_amgms; 294 size = dev->caps.num_mgms + dev->caps.num_amgms;
275 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); 295 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
296 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP);
276 297
277 } else 298 } else
278 err = -EINVAL; 299 err = -EINVAL;
@@ -287,7 +308,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
287 u32 *outbox; 308 u32 *outbox;
288 u8 field, op_modifier; 309 u8 field, op_modifier;
289 u32 size; 310 u32 size;
290 int err = 0; 311 int err = 0, quotas = 0;
291 312
292 op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ 313 op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */
293 314
@@ -311,6 +332,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
311 goto out; 332 goto out;
312 } 333 }
313 func_cap->flags = field; 334 func_cap->flags = field;
335 quotas = !!(func_cap->flags & QUERY_FUNC_CAP_FLAG_QUOTAS);
314 336
315 MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); 337 MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET);
316 func_cap->num_ports = field; 338 func_cap->num_ports = field;
@@ -318,29 +340,50 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port,
318 MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET); 340 MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET);
319 func_cap->pf_context_behaviour = size; 341 func_cap->pf_context_behaviour = size;
320 342
321 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 343 if (quotas) {
322 func_cap->qp_quota = size & 0xFFFFFF; 344 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET);
345 func_cap->qp_quota = size & 0xFFFFFF;
323 346
324 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 347 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET);
325 func_cap->srq_quota = size & 0xFFFFFF; 348 func_cap->srq_quota = size & 0xFFFFFF;
326 349
327 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 350 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET);
328 func_cap->cq_quota = size & 0xFFFFFF; 351 func_cap->cq_quota = size & 0xFFFFFF;
329 352
353 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
354 func_cap->mpt_quota = size & 0xFFFFFF;
355
356 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
357 func_cap->mtt_quota = size & 0xFFFFFF;
358
359 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
360 func_cap->mcg_quota = size & 0xFFFFFF;
361
362 } else {
363 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP);
364 func_cap->qp_quota = size & 0xFFFFFF;
365
366 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP);
367 func_cap->srq_quota = size & 0xFFFFFF;
368
369 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP);
370 func_cap->cq_quota = size & 0xFFFFFF;
371
372 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP);
373 func_cap->mpt_quota = size & 0xFFFFFF;
374
375 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP);
376 func_cap->mtt_quota = size & 0xFFFFFF;
377
378 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP);
379 func_cap->mcg_quota = size & 0xFFFFFF;
380 }
330 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 381 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET);
331 func_cap->max_eq = size & 0xFFFFFF; 382 func_cap->max_eq = size & 0xFFFFFF;
332 383
333 MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 384 MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET);
334 func_cap->reserved_eq = size & 0xFFFFFF; 385 func_cap->reserved_eq = size & 0xFFFFFF;
335 386
336 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET);
337 func_cap->mpt_quota = size & 0xFFFFFF;
338
339 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET);
340 func_cap->mtt_quota = size & 0xFFFFFF;
341
342 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET);
343 func_cap->mcg_quota = size & 0xFFFFFF;
344 goto out; 387 goto out;
345 } 388 }
346 389
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 179d26709c94..7d2628dfdc29 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -562,13 +562,17 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
562 } 562 }
563 563
564 dev->caps.num_ports = func_cap.num_ports; 564 dev->caps.num_ports = func_cap.num_ports;
565 dev->caps.num_qps = func_cap.qp_quota; 565 dev->quotas.qp = func_cap.qp_quota;
566 dev->caps.num_srqs = func_cap.srq_quota; 566 dev->quotas.srq = func_cap.srq_quota;
567 dev->caps.num_cqs = func_cap.cq_quota; 567 dev->quotas.cq = func_cap.cq_quota;
568 dev->caps.num_eqs = func_cap.max_eq; 568 dev->quotas.mpt = func_cap.mpt_quota;
569 dev->caps.reserved_eqs = func_cap.reserved_eq; 569 dev->quotas.mtt = func_cap.mtt_quota;
570 dev->caps.num_mpts = func_cap.mpt_quota; 570 dev->caps.num_qps = 1 << hca_param.log_num_qps;
571 dev->caps.num_mtts = func_cap.mtt_quota; 571 dev->caps.num_srqs = 1 << hca_param.log_num_srqs;
572 dev->caps.num_cqs = 1 << hca_param.log_num_cqs;
573 dev->caps.num_mpts = 1 << hca_param.log_mpt_sz;
574 dev->caps.num_eqs = func_cap.max_eq;
575 dev->caps.reserved_eqs = func_cap.reserved_eq;
572 dev->caps.num_pds = MLX4_NUM_PDS; 576 dev->caps.num_pds = MLX4_NUM_PDS;
573 dev->caps.num_mgms = 0; 577 dev->caps.num_mgms = 0;
574 dev->caps.num_amgms = 0; 578 dev->caps.num_amgms = 0;
@@ -2102,9 +2106,15 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
2102 "aborting.\n"); 2106 "aborting.\n");
2103 return err; 2107 return err;
2104 } 2108 }
2105 if (num_vfs > MLX4_MAX_NUM_VF) { 2109
2106 printk(KERN_ERR "There are more VF's (%d) than allowed(%d)\n", 2110 /* Due to requirement that all VFs and the PF are *guaranteed* 2 MACS
2107 num_vfs, MLX4_MAX_NUM_VF); 2111 * per port, we must limit the number of VFs to 63 (since their are
2112 * 128 MACs)
2113 */
2114 if (num_vfs >= MLX4_MAX_NUM_VF) {
2115 dev_err(&pdev->dev,
2116 "Requested more VF's (%d) than allowed (%d)\n",
2117 num_vfs, MLX4_MAX_NUM_VF - 1);
2108 return -EINVAL; 2118 return -EINVAL;
2109 } 2119 }
2110 2120
@@ -2322,6 +2332,8 @@ slave_start:
2322 if (err) 2332 if (err)
2323 goto err_steer; 2333 goto err_steer;
2324 2334
2335 mlx4_init_quotas(dev);
2336
2325 for (port = 1; port <= dev->caps.num_ports; port++) { 2337 for (port = 1; port <= dev->caps.num_ports; port++) {
2326 err = mlx4_init_port_info(dev, port); 2338 err = mlx4_init_port_info(dev, port);
2327 if (err) 2339 if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 348bb8c7d9a7..e582a41a802b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -455,6 +455,7 @@ struct mlx4_slave_state {
455 u8 last_cmd; 455 u8 last_cmd;
456 u8 init_port_mask; 456 u8 init_port_mask;
457 bool active; 457 bool active;
458 bool old_vlan_api;
458 u8 function; 459 u8 function;
459 dma_addr_t vhcr_dma; 460 dma_addr_t vhcr_dma;
460 u16 mtu[MLX4_MAX_PORTS + 1]; 461 u16 mtu[MLX4_MAX_PORTS + 1];
@@ -503,12 +504,28 @@ struct slave_list {
503 struct list_head res_list[MLX4_NUM_OF_RESOURCE_TYPE]; 504 struct list_head res_list[MLX4_NUM_OF_RESOURCE_TYPE];
504}; 505};
505 506
507struct resource_allocator {
508 spinlock_t alloc_lock; /* protect quotas */
509 union {
510 int res_reserved;
511 int res_port_rsvd[MLX4_MAX_PORTS];
512 };
513 union {
514 int res_free;
515 int res_port_free[MLX4_MAX_PORTS];
516 };
517 int *quota;
518 int *allocated;
519 int *guaranteed;
520};
521
506struct mlx4_resource_tracker { 522struct mlx4_resource_tracker {
507 spinlock_t lock; 523 spinlock_t lock;
508 /* tree for each resources */ 524 /* tree for each resources */
509 struct rb_root res_tree[MLX4_NUM_OF_RESOURCE_TYPE]; 525 struct rb_root res_tree[MLX4_NUM_OF_RESOURCE_TYPE];
510 /* num_of_slave's lists, one per slave */ 526 /* num_of_slave's lists, one per slave */
511 struct slave_list *slave_list; 527 struct slave_list *slave_list;
528 struct resource_allocator res_alloc[MLX4_NUM_OF_RESOURCE_TYPE];
512}; 529};
513 530
514#define SLAVE_EVENT_EQ_SIZE 128 531#define SLAVE_EVENT_EQ_SIZE 128
@@ -1111,7 +1128,7 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
1111 1128
1112void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); 1129void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
1113void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); 1130void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
1114void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index); 1131void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan);
1115int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); 1132int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
1116 1133
1117int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz); 1134int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz);
@@ -1252,4 +1269,6 @@ static inline spinlock_t *mlx4_tlock(struct mlx4_dev *dev)
1252 1269
1253void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work); 1270void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work);
1254 1271
1272void mlx4_init_quotas(struct mlx4_dev *dev);
1273
1255#endif /* MLX4_H */ 1274#endif /* MLX4_H */
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index f91719a08cba..63391a1a7f8c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -755,14 +755,14 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
755 struct mlx4_mr_table *mr_table = &priv->mr_table; 755 struct mlx4_mr_table *mr_table = &priv->mr_table;
756 int err; 756 int err;
757 757
758 if (!is_power_of_2(dev->caps.num_mpts))
759 return -EINVAL;
760
761 /* Nothing to do for slaves - all MR handling is forwarded 758 /* Nothing to do for slaves - all MR handling is forwarded
762 * to the master */ 759 * to the master */
763 if (mlx4_is_slave(dev)) 760 if (mlx4_is_slave(dev))
764 return 0; 761 return 0;
765 762
763 if (!is_power_of_2(dev->caps.num_mpts))
764 return -EINVAL;
765
766 err = mlx4_bitmap_init(&mr_table->mpt_bitmap, dev->caps.num_mpts, 766 err = mlx4_bitmap_init(&mr_table->mpt_bitmap, dev->caps.num_mpts,
767 ~0, dev->caps.reserved_mrws, 0); 767 ~0, dev->caps.reserved_mrws, 0);
768 if (err) 768 if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 946e0af5faef..caaa15470395 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -178,13 +178,24 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac);
178int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac) 178int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
179{ 179{
180 u64 out_param = 0; 180 u64 out_param = 0;
181 int err; 181 int err = -EINVAL;
182 182
183 if (mlx4_is_mfunc(dev)) { 183 if (mlx4_is_mfunc(dev)) {
184 set_param_l(&out_param, port); 184 if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
185 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, 185 err = mlx4_cmd_imm(dev, mac, &out_param,
186 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES, 186 ((u32) port) << 8 | (u32) RES_MAC,
187 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 187 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
188 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
189 }
190 if (err && err == -EINVAL && mlx4_is_slave(dev)) {
191 /* retry using old REG_MAC format */
192 set_param_l(&out_param, port);
193 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
194 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
195 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
196 if (!err)
197 dev->flags |= MLX4_FLAG_OLD_REG_MAC;
198 }
188 if (err) 199 if (err)
189 return err; 200 return err;
190 201
@@ -231,10 +242,18 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
231 u64 out_param = 0; 242 u64 out_param = 0;
232 243
233 if (mlx4_is_mfunc(dev)) { 244 if (mlx4_is_mfunc(dev)) {
234 set_param_l(&out_param, port); 245 if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) {
235 (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, 246 (void) mlx4_cmd_imm(dev, mac, &out_param,
236 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES, 247 ((u32) port) << 8 | (u32) RES_MAC,
237 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 248 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
249 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
250 } else {
251 /* use old unregister mac format */
252 set_param_l(&out_param, port);
253 (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
254 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
255 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
256 }
238 return; 257 return;
239 } 258 }
240 __mlx4_unregister_mac(dev, port, mac); 259 __mlx4_unregister_mac(dev, port, mac);
@@ -284,7 +303,7 @@ static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port,
284 memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE); 303 memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
285 in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port; 304 in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
286 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 305 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
287 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); 306 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
288 307
289 mlx4_free_cmd_mailbox(dev, mailbox); 308 mlx4_free_cmd_mailbox(dev, mailbox);
290 309
@@ -370,9 +389,12 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
370 u64 out_param = 0; 389 u64 out_param = 0;
371 int err; 390 int err;
372 391
392 if (vlan > 4095)
393 return -EINVAL;
394
373 if (mlx4_is_mfunc(dev)) { 395 if (mlx4_is_mfunc(dev)) {
374 set_param_l(&out_param, port); 396 err = mlx4_cmd_imm(dev, vlan, &out_param,
375 err = mlx4_cmd_imm(dev, vlan, &out_param, RES_VLAN, 397 ((u32) port) << 8 | (u32) RES_VLAN,
376 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES, 398 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
377 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 399 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
378 if (!err) 400 if (!err)
@@ -384,23 +406,26 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
384} 406}
385EXPORT_SYMBOL_GPL(mlx4_register_vlan); 407EXPORT_SYMBOL_GPL(mlx4_register_vlan);
386 408
387void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) 409void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan)
388{ 410{
389 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 411 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
412 int index;
390 413
391 if (index < MLX4_VLAN_REGULAR) { 414 mutex_lock(&table->mutex);
392 mlx4_warn(dev, "Trying to free special vlan index %d\n", index); 415 if (mlx4_find_cached_vlan(dev, port, vlan, &index)) {
393 return; 416 mlx4_warn(dev, "vlan 0x%x is not in the vlan table\n", vlan);
417 goto out;
394 } 418 }
395 419
396 mutex_lock(&table->mutex); 420 if (index < MLX4_VLAN_REGULAR) {
397 if (!table->refs[index]) { 421 mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
398 mlx4_warn(dev, "No vlan entry for index %d\n", index);
399 goto out; 422 goto out;
400 } 423 }
424
401 if (--table->refs[index]) { 425 if (--table->refs[index]) {
402 mlx4_dbg(dev, "Have more references for index %d," 426 mlx4_dbg(dev, "Have %d more references for index %d,"
403 "no need to modify vlan table\n", index); 427 "no need to modify vlan table\n", table->refs[index],
428 index);
404 goto out; 429 goto out;
405 } 430 }
406 table->entries[index] = 0; 431 table->entries[index] = 0;
@@ -410,23 +435,19 @@ out:
410 mutex_unlock(&table->mutex); 435 mutex_unlock(&table->mutex);
411} 436}
412 437
413void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) 438void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan)
414{ 439{
415 u64 in_param = 0; 440 u64 out_param = 0;
416 int err;
417 441
418 if (mlx4_is_mfunc(dev)) { 442 if (mlx4_is_mfunc(dev)) {
419 set_param_l(&in_param, port); 443 (void) mlx4_cmd_imm(dev, vlan, &out_param,
420 err = mlx4_cmd(dev, in_param, RES_VLAN, RES_OP_RESERVE_AND_MAP, 444 ((u32) port) << 8 | (u32) RES_VLAN,
421 MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A, 445 RES_OP_RESERVE_AND_MAP,
422 MLX4_CMD_WRAPPED); 446 MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
423 if (!err) 447 MLX4_CMD_WRAPPED);
424 mlx4_warn(dev, "Failed freeing vlan at index:%d\n",
425 index);
426
427 return; 448 return;
428 } 449 }
429 __mlx4_unregister_vlan(dev, port, index); 450 __mlx4_unregister_vlan(dev, port, vlan);
430} 451}
431EXPORT_SYMBOL_GPL(mlx4_unregister_vlan); 452EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
432 453
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index e891b058c1be..2715e61dbb74 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -480,8 +480,7 @@ int mlx4_init_qp_table(struct mlx4_dev *dev)
480 */ 480 */
481 481
482 err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps, 482 err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps,
483 (1 << 23) - 1, dev->phys_caps.base_sqpn + 8 + 483 (1 << 23) - 1, mlx4_num_reserved_sqps(dev),
484 16 * MLX4_MFUNC_MAX * !!mlx4_is_master(dev),
485 reserved_from_top); 484 reserved_from_top);
486 if (err) 485 if (err)
487 return err; 486 return err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index dd6876321116..b1603e2287a7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -55,6 +55,14 @@ struct mac_res {
55 u8 port; 55 u8 port;
56}; 56};
57 57
58struct vlan_res {
59 struct list_head list;
60 u16 vlan;
61 int ref_count;
62 int vlan_index;
63 u8 port;
64};
65
58struct res_common { 66struct res_common {
59 struct list_head list; 67 struct list_head list;
60 struct rb_node node; 68 struct rb_node node;
@@ -266,6 +274,7 @@ static const char *ResourceType(enum mlx4_resource rt)
266 case RES_MPT: return "RES_MPT"; 274 case RES_MPT: return "RES_MPT";
267 case RES_MTT: return "RES_MTT"; 275 case RES_MTT: return "RES_MTT";
268 case RES_MAC: return "RES_MAC"; 276 case RES_MAC: return "RES_MAC";
277 case RES_VLAN: return "RES_VLAN";
269 case RES_EQ: return "RES_EQ"; 278 case RES_EQ: return "RES_EQ";
270 case RES_COUNTER: return "RES_COUNTER"; 279 case RES_COUNTER: return "RES_COUNTER";
271 case RES_FS_RULE: return "RES_FS_RULE"; 280 case RES_FS_RULE: return "RES_FS_RULE";
@@ -274,10 +283,139 @@ static const char *ResourceType(enum mlx4_resource rt)
274 }; 283 };
275} 284}
276 285
286static void rem_slave_vlans(struct mlx4_dev *dev, int slave);
287static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
288 enum mlx4_resource res_type, int count,
289 int port)
290{
291 struct mlx4_priv *priv = mlx4_priv(dev);
292 struct resource_allocator *res_alloc =
293 &priv->mfunc.master.res_tracker.res_alloc[res_type];
294 int err = -EINVAL;
295 int allocated, free, reserved, guaranteed, from_free;
296
297 if (slave > dev->num_vfs)
298 return -EINVAL;
299
300 spin_lock(&res_alloc->alloc_lock);
301 allocated = (port > 0) ?
302 res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] :
303 res_alloc->allocated[slave];
304 free = (port > 0) ? res_alloc->res_port_free[port - 1] :
305 res_alloc->res_free;
306 reserved = (port > 0) ? res_alloc->res_port_rsvd[port - 1] :
307 res_alloc->res_reserved;
308 guaranteed = res_alloc->guaranteed[slave];
309
310 if (allocated + count > res_alloc->quota[slave])
311 goto out;
312
313 if (allocated + count <= guaranteed) {
314 err = 0;
315 } else {
316 /* portion may need to be obtained from free area */
317 if (guaranteed - allocated > 0)
318 from_free = count - (guaranteed - allocated);
319 else
320 from_free = count;
321
322 if (free - from_free > reserved)
323 err = 0;
324 }
325
326 if (!err) {
327 /* grant the request */
328 if (port > 0) {
329 res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] += count;
330 res_alloc->res_port_free[port - 1] -= count;
331 } else {
332 res_alloc->allocated[slave] += count;
333 res_alloc->res_free -= count;
334 }
335 }
336
337out:
338 spin_unlock(&res_alloc->alloc_lock);
339 return err;
340}
341
342static inline void mlx4_release_resource(struct mlx4_dev *dev, int slave,
343 enum mlx4_resource res_type, int count,
344 int port)
345{
346 struct mlx4_priv *priv = mlx4_priv(dev);
347 struct resource_allocator *res_alloc =
348 &priv->mfunc.master.res_tracker.res_alloc[res_type];
349
350 if (slave > dev->num_vfs)
351 return;
352
353 spin_lock(&res_alloc->alloc_lock);
354 if (port > 0) {
355 res_alloc->allocated[(port - 1) * (dev->num_vfs + 1) + slave] -= count;
356 res_alloc->res_port_free[port - 1] += count;
357 } else {
358 res_alloc->allocated[slave] -= count;
359 res_alloc->res_free += count;
360 }
361
362 spin_unlock(&res_alloc->alloc_lock);
363 return;
364}
365
366static inline void initialize_res_quotas(struct mlx4_dev *dev,
367 struct resource_allocator *res_alloc,
368 enum mlx4_resource res_type,
369 int vf, int num_instances)
370{
371 res_alloc->guaranteed[vf] = num_instances / (2 * (dev->num_vfs + 1));
372 res_alloc->quota[vf] = (num_instances / 2) + res_alloc->guaranteed[vf];
373 if (vf == mlx4_master_func_num(dev)) {
374 res_alloc->res_free = num_instances;
375 if (res_type == RES_MTT) {
376 /* reserved mtts will be taken out of the PF allocation */
377 res_alloc->res_free += dev->caps.reserved_mtts;
378 res_alloc->guaranteed[vf] += dev->caps.reserved_mtts;
379 res_alloc->quota[vf] += dev->caps.reserved_mtts;
380 }
381 }
382}
383
384void mlx4_init_quotas(struct mlx4_dev *dev)
385{
386 struct mlx4_priv *priv = mlx4_priv(dev);
387 int pf;
388
389 /* quotas for VFs are initialized in mlx4_slave_cap */
390 if (mlx4_is_slave(dev))
391 return;
392
393 if (!mlx4_is_mfunc(dev)) {
394 dev->quotas.qp = dev->caps.num_qps - dev->caps.reserved_qps -
395 mlx4_num_reserved_sqps(dev);
396 dev->quotas.cq = dev->caps.num_cqs - dev->caps.reserved_cqs;
397 dev->quotas.srq = dev->caps.num_srqs - dev->caps.reserved_srqs;
398 dev->quotas.mtt = dev->caps.num_mtts - dev->caps.reserved_mtts;
399 dev->quotas.mpt = dev->caps.num_mpts - dev->caps.reserved_mrws;
400 return;
401 }
402
403 pf = mlx4_master_func_num(dev);
404 dev->quotas.qp =
405 priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[pf];
406 dev->quotas.cq =
407 priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[pf];
408 dev->quotas.srq =
409 priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[pf];
410 dev->quotas.mtt =
411 priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[pf];
412 dev->quotas.mpt =
413 priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf];
414}
277int mlx4_init_resource_tracker(struct mlx4_dev *dev) 415int mlx4_init_resource_tracker(struct mlx4_dev *dev)
278{ 416{
279 struct mlx4_priv *priv = mlx4_priv(dev); 417 struct mlx4_priv *priv = mlx4_priv(dev);
280 int i; 418 int i, j;
281 int t; 419 int t;
282 420
283 priv->mfunc.master.res_tracker.slave_list = 421 priv->mfunc.master.res_tracker.slave_list =
@@ -298,8 +436,105 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
298 for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) 436 for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++)
299 priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT; 437 priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT;
300 438
439 for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
440 struct resource_allocator *res_alloc =
441 &priv->mfunc.master.res_tracker.res_alloc[i];
442 res_alloc->quota = kmalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL);
443 res_alloc->guaranteed = kmalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL);
444 if (i == RES_MAC || i == RES_VLAN)
445 res_alloc->allocated = kzalloc(MLX4_MAX_PORTS *
446 (dev->num_vfs + 1) * sizeof(int),
447 GFP_KERNEL);
448 else
449 res_alloc->allocated = kzalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL);
450
451 if (!res_alloc->quota || !res_alloc->guaranteed ||
452 !res_alloc->allocated)
453 goto no_mem_err;
454
455 spin_lock_init(&res_alloc->alloc_lock);
456 for (t = 0; t < dev->num_vfs + 1; t++) {
457 switch (i) {
458 case RES_QP:
459 initialize_res_quotas(dev, res_alloc, RES_QP,
460 t, dev->caps.num_qps -
461 dev->caps.reserved_qps -
462 mlx4_num_reserved_sqps(dev));
463 break;
464 case RES_CQ:
465 initialize_res_quotas(dev, res_alloc, RES_CQ,
466 t, dev->caps.num_cqs -
467 dev->caps.reserved_cqs);
468 break;
469 case RES_SRQ:
470 initialize_res_quotas(dev, res_alloc, RES_SRQ,
471 t, dev->caps.num_srqs -
472 dev->caps.reserved_srqs);
473 break;
474 case RES_MPT:
475 initialize_res_quotas(dev, res_alloc, RES_MPT,
476 t, dev->caps.num_mpts -
477 dev->caps.reserved_mrws);
478 break;
479 case RES_MTT:
480 initialize_res_quotas(dev, res_alloc, RES_MTT,
481 t, dev->caps.num_mtts -
482 dev->caps.reserved_mtts);
483 break;
484 case RES_MAC:
485 if (t == mlx4_master_func_num(dev)) {
486 res_alloc->quota[t] = MLX4_MAX_MAC_NUM;
487 res_alloc->guaranteed[t] = 2;
488 for (j = 0; j < MLX4_MAX_PORTS; j++)
489 res_alloc->res_port_free[j] = MLX4_MAX_MAC_NUM;
490 } else {
491 res_alloc->quota[t] = MLX4_MAX_MAC_NUM;
492 res_alloc->guaranteed[t] = 2;
493 }
494 break;
495 case RES_VLAN:
496 if (t == mlx4_master_func_num(dev)) {
497 res_alloc->quota[t] = MLX4_MAX_VLAN_NUM;
498 res_alloc->guaranteed[t] = MLX4_MAX_VLAN_NUM / 2;
499 for (j = 0; j < MLX4_MAX_PORTS; j++)
500 res_alloc->res_port_free[j] =
501 res_alloc->quota[t];
502 } else {
503 res_alloc->quota[t] = MLX4_MAX_VLAN_NUM / 2;
504 res_alloc->guaranteed[t] = 0;
505 }
506 break;
507 case RES_COUNTER:
508 res_alloc->quota[t] = dev->caps.max_counters;
509 res_alloc->guaranteed[t] = 0;
510 if (t == mlx4_master_func_num(dev))
511 res_alloc->res_free = res_alloc->quota[t];
512 break;
513 default:
514 break;
515 }
516 if (i == RES_MAC || i == RES_VLAN) {
517 for (j = 0; j < MLX4_MAX_PORTS; j++)
518 res_alloc->res_port_rsvd[j] +=
519 res_alloc->guaranteed[t];
520 } else {
521 res_alloc->res_reserved += res_alloc->guaranteed[t];
522 }
523 }
524 }
301 spin_lock_init(&priv->mfunc.master.res_tracker.lock); 525 spin_lock_init(&priv->mfunc.master.res_tracker.lock);
302 return 0 ; 526 return 0;
527
528no_mem_err:
529 for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
530 kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
531 priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
532 kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
533 priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
534 kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
535 priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
536 }
537 return -ENOMEM;
303} 538}
304 539
305void mlx4_free_resource_tracker(struct mlx4_dev *dev, 540void mlx4_free_resource_tracker(struct mlx4_dev *dev,
@@ -309,13 +544,28 @@ void mlx4_free_resource_tracker(struct mlx4_dev *dev,
309 int i; 544 int i;
310 545
311 if (priv->mfunc.master.res_tracker.slave_list) { 546 if (priv->mfunc.master.res_tracker.slave_list) {
312 if (type != RES_TR_FREE_STRUCTS_ONLY) 547 if (type != RES_TR_FREE_STRUCTS_ONLY) {
313 for (i = 0 ; i < dev->num_slaves; i++) 548 for (i = 0; i < dev->num_slaves; i++) {
314 if (type == RES_TR_FREE_ALL || 549 if (type == RES_TR_FREE_ALL ||
315 dev->caps.function != i) 550 dev->caps.function != i)
316 mlx4_delete_all_resources_for_slave(dev, i); 551 mlx4_delete_all_resources_for_slave(dev, i);
552 }
553 /* free master's vlans */
554 i = dev->caps.function;
555 mutex_lock(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
556 rem_slave_vlans(dev, i);
557 mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
558 }
317 559
318 if (type != RES_TR_FREE_SLAVES_ONLY) { 560 if (type != RES_TR_FREE_SLAVES_ONLY) {
561 for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
562 kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
563 priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
564 kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
565 priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
566 kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
567 priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
568 }
319 kfree(priv->mfunc.master.res_tracker.slave_list); 569 kfree(priv->mfunc.master.res_tracker.slave_list);
320 priv->mfunc.master.res_tracker.slave_list = NULL; 570 priv->mfunc.master.res_tracker.slave_list = NULL;
321 } 571 }
@@ -1229,12 +1479,19 @@ static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1229 case RES_OP_RESERVE: 1479 case RES_OP_RESERVE:
1230 count = get_param_l(&in_param); 1480 count = get_param_l(&in_param);
1231 align = get_param_h(&in_param); 1481 align = get_param_h(&in_param);
1232 err = __mlx4_qp_reserve_range(dev, count, align, &base); 1482 err = mlx4_grant_resource(dev, slave, RES_QP, count, 0);
1233 if (err) 1483 if (err)
1234 return err; 1484 return err;
1235 1485
1486 err = __mlx4_qp_reserve_range(dev, count, align, &base);
1487 if (err) {
1488 mlx4_release_resource(dev, slave, RES_QP, count, 0);
1489 return err;
1490 }
1491
1236 err = add_res_range(dev, slave, base, count, RES_QP, 0); 1492 err = add_res_range(dev, slave, base, count, RES_QP, 0);
1237 if (err) { 1493 if (err) {
1494 mlx4_release_resource(dev, slave, RES_QP, count, 0);
1238 __mlx4_qp_release_range(dev, base, count); 1495 __mlx4_qp_release_range(dev, base, count);
1239 return err; 1496 return err;
1240 } 1497 }
@@ -1282,15 +1539,24 @@ static int mtt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1282 return err; 1539 return err;
1283 1540
1284 order = get_param_l(&in_param); 1541 order = get_param_l(&in_param);
1542
1543 err = mlx4_grant_resource(dev, slave, RES_MTT, 1 << order, 0);
1544 if (err)
1545 return err;
1546
1285 base = __mlx4_alloc_mtt_range(dev, order); 1547 base = __mlx4_alloc_mtt_range(dev, order);
1286 if (base == -1) 1548 if (base == -1) {
1549 mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1287 return -ENOMEM; 1550 return -ENOMEM;
1551 }
1288 1552
1289 err = add_res_range(dev, slave, base, 1, RES_MTT, order); 1553 err = add_res_range(dev, slave, base, 1, RES_MTT, order);
1290 if (err) 1554 if (err) {
1555 mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1291 __mlx4_free_mtt_range(dev, base, order); 1556 __mlx4_free_mtt_range(dev, base, order);
1292 else 1557 } else {
1293 set_param_l(out_param, base); 1558 set_param_l(out_param, base);
1559 }
1294 1560
1295 return err; 1561 return err;
1296} 1562}
@@ -1305,13 +1571,20 @@ static int mpt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1305 1571
1306 switch (op) { 1572 switch (op) {
1307 case RES_OP_RESERVE: 1573 case RES_OP_RESERVE:
1574 err = mlx4_grant_resource(dev, slave, RES_MPT, 1, 0);
1575 if (err)
1576 break;
1577
1308 index = __mlx4_mpt_reserve(dev); 1578 index = __mlx4_mpt_reserve(dev);
1309 if (index == -1) 1579 if (index == -1) {
1580 mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1310 break; 1581 break;
1582 }
1311 id = index & mpt_mask(dev); 1583 id = index & mpt_mask(dev);
1312 1584
1313 err = add_res_range(dev, slave, id, 1, RES_MPT, index); 1585 err = add_res_range(dev, slave, id, 1, RES_MPT, index);
1314 if (err) { 1586 if (err) {
1587 mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1315 __mlx4_mpt_release(dev, index); 1588 __mlx4_mpt_release(dev, index);
1316 break; 1589 break;
1317 } 1590 }
@@ -1345,12 +1618,19 @@ static int cq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1345 1618
1346 switch (op) { 1619 switch (op) {
1347 case RES_OP_RESERVE_AND_MAP: 1620 case RES_OP_RESERVE_AND_MAP:
1348 err = __mlx4_cq_alloc_icm(dev, &cqn); 1621 err = mlx4_grant_resource(dev, slave, RES_CQ, 1, 0);
1349 if (err) 1622 if (err)
1350 break; 1623 break;
1351 1624
1625 err = __mlx4_cq_alloc_icm(dev, &cqn);
1626 if (err) {
1627 mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1628 break;
1629 }
1630
1352 err = add_res_range(dev, slave, cqn, 1, RES_CQ, 0); 1631 err = add_res_range(dev, slave, cqn, 1, RES_CQ, 0);
1353 if (err) { 1632 if (err) {
1633 mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1354 __mlx4_cq_free_icm(dev, cqn); 1634 __mlx4_cq_free_icm(dev, cqn);
1355 break; 1635 break;
1356 } 1636 }
@@ -1373,12 +1653,19 @@ static int srq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1373 1653
1374 switch (op) { 1654 switch (op) {
1375 case RES_OP_RESERVE_AND_MAP: 1655 case RES_OP_RESERVE_AND_MAP:
1376 err = __mlx4_srq_alloc_icm(dev, &srqn); 1656 err = mlx4_grant_resource(dev, slave, RES_SRQ, 1, 0);
1377 if (err) 1657 if (err)
1378 break; 1658 break;
1379 1659
1660 err = __mlx4_srq_alloc_icm(dev, &srqn);
1661 if (err) {
1662 mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1663 break;
1664 }
1665
1380 err = add_res_range(dev, slave, srqn, 1, RES_SRQ, 0); 1666 err = add_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
1381 if (err) { 1667 if (err) {
1668 mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1382 __mlx4_srq_free_icm(dev, srqn); 1669 __mlx4_srq_free_icm(dev, srqn);
1383 break; 1670 break;
1384 } 1671 }
@@ -1399,9 +1686,13 @@ static int mac_add_to_slave(struct mlx4_dev *dev, int slave, u64 mac, int port)
1399 struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; 1686 struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1400 struct mac_res *res; 1687 struct mac_res *res;
1401 1688
1689 if (mlx4_grant_resource(dev, slave, RES_MAC, 1, port))
1690 return -EINVAL;
1402 res = kzalloc(sizeof *res, GFP_KERNEL); 1691 res = kzalloc(sizeof *res, GFP_KERNEL);
1403 if (!res) 1692 if (!res) {
1693 mlx4_release_resource(dev, slave, RES_MAC, 1, port);
1404 return -ENOMEM; 1694 return -ENOMEM;
1695 }
1405 res->mac = mac; 1696 res->mac = mac;
1406 res->port = (u8) port; 1697 res->port = (u8) port;
1407 list_add_tail(&res->list, 1698 list_add_tail(&res->list,
@@ -1421,6 +1712,7 @@ static void mac_del_from_slave(struct mlx4_dev *dev, int slave, u64 mac,
1421 list_for_each_entry_safe(res, tmp, mac_list, list) { 1712 list_for_each_entry_safe(res, tmp, mac_list, list) {
1422 if (res->mac == mac && res->port == (u8) port) { 1713 if (res->mac == mac && res->port == (u8) port) {
1423 list_del(&res->list); 1714 list_del(&res->list);
1715 mlx4_release_resource(dev, slave, RES_MAC, 1, port);
1424 kfree(res); 1716 kfree(res);
1425 break; 1717 break;
1426 } 1718 }
@@ -1438,12 +1730,13 @@ static void rem_slave_macs(struct mlx4_dev *dev, int slave)
1438 list_for_each_entry_safe(res, tmp, mac_list, list) { 1730 list_for_each_entry_safe(res, tmp, mac_list, list) {
1439 list_del(&res->list); 1731 list_del(&res->list);
1440 __mlx4_unregister_mac(dev, res->port, res->mac); 1732 __mlx4_unregister_mac(dev, res->port, res->mac);
1733 mlx4_release_resource(dev, slave, RES_MAC, 1, res->port);
1441 kfree(res); 1734 kfree(res);
1442 } 1735 }
1443} 1736}
1444 1737
1445static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, 1738static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1446 u64 in_param, u64 *out_param) 1739 u64 in_param, u64 *out_param, int in_port)
1447{ 1740{
1448 int err = -EINVAL; 1741 int err = -EINVAL;
1449 int port; 1742 int port;
@@ -1452,7 +1745,7 @@ static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1452 if (op != RES_OP_RESERVE_AND_MAP) 1745 if (op != RES_OP_RESERVE_AND_MAP)
1453 return err; 1746 return err;
1454 1747
1455 port = get_param_l(out_param); 1748 port = !in_port ? get_param_l(out_param) : in_port;
1456 mac = in_param; 1749 mac = in_param;
1457 1750
1458 err = __mlx4_register_mac(dev, port, mac); 1751 err = __mlx4_register_mac(dev, port, mac);
@@ -1469,12 +1762,114 @@ static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1469 return err; 1762 return err;
1470} 1763}
1471 1764
1472static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, 1765static int vlan_add_to_slave(struct mlx4_dev *dev, int slave, u16 vlan,
1473 u64 in_param, u64 *out_param) 1766 int port, int vlan_index)
1474{ 1767{
1768 struct mlx4_priv *priv = mlx4_priv(dev);
1769 struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1770 struct list_head *vlan_list =
1771 &tracker->slave_list[slave].res_list[RES_VLAN];
1772 struct vlan_res *res, *tmp;
1773
1774 list_for_each_entry_safe(res, tmp, vlan_list, list) {
1775 if (res->vlan == vlan && res->port == (u8) port) {
1776 /* vlan found. update ref count */
1777 ++res->ref_count;
1778 return 0;
1779 }
1780 }
1781
1782 if (mlx4_grant_resource(dev, slave, RES_VLAN, 1, port))
1783 return -EINVAL;
1784 res = kzalloc(sizeof(*res), GFP_KERNEL);
1785 if (!res) {
1786 mlx4_release_resource(dev, slave, RES_VLAN, 1, port);
1787 return -ENOMEM;
1788 }
1789 res->vlan = vlan;
1790 res->port = (u8) port;
1791 res->vlan_index = vlan_index;
1792 res->ref_count = 1;
1793 list_add_tail(&res->list,
1794 &tracker->slave_list[slave].res_list[RES_VLAN]);
1475 return 0; 1795 return 0;
1476} 1796}
1477 1797
1798
1799static void vlan_del_from_slave(struct mlx4_dev *dev, int slave, u16 vlan,
1800 int port)
1801{
1802 struct mlx4_priv *priv = mlx4_priv(dev);
1803 struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1804 struct list_head *vlan_list =
1805 &tracker->slave_list[slave].res_list[RES_VLAN];
1806 struct vlan_res *res, *tmp;
1807
1808 list_for_each_entry_safe(res, tmp, vlan_list, list) {
1809 if (res->vlan == vlan && res->port == (u8) port) {
1810 if (!--res->ref_count) {
1811 list_del(&res->list);
1812 mlx4_release_resource(dev, slave, RES_VLAN,
1813 1, port);
1814 kfree(res);
1815 }
1816 break;
1817 }
1818 }
1819}
1820
1821static void rem_slave_vlans(struct mlx4_dev *dev, int slave)
1822{
1823 struct mlx4_priv *priv = mlx4_priv(dev);
1824 struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1825 struct list_head *vlan_list =
1826 &tracker->slave_list[slave].res_list[RES_VLAN];
1827 struct vlan_res *res, *tmp;
1828 int i;
1829
1830 list_for_each_entry_safe(res, tmp, vlan_list, list) {
1831 list_del(&res->list);
1832 /* dereference the vlan the num times the slave referenced it */
1833 for (i = 0; i < res->ref_count; i++)
1834 __mlx4_unregister_vlan(dev, res->port, res->vlan);
1835 mlx4_release_resource(dev, slave, RES_VLAN, 1, res->port);
1836 kfree(res);
1837 }
1838}
1839
1840static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1841 u64 in_param, u64 *out_param, int in_port)
1842{
1843 struct mlx4_priv *priv = mlx4_priv(dev);
1844 struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
1845 int err;
1846 u16 vlan;
1847 int vlan_index;
1848 int port;
1849
1850 port = !in_port ? get_param_l(out_param) : in_port;
1851
1852 if (!port || op != RES_OP_RESERVE_AND_MAP)
1853 return -EINVAL;
1854
1855 /* upstream kernels had NOP for reg/unreg vlan. Continue this. */
1856 if (!in_port && port > 0 && port <= dev->caps.num_ports) {
1857 slave_state[slave].old_vlan_api = true;
1858 return 0;
1859 }
1860
1861 vlan = (u16) in_param;
1862
1863 err = __mlx4_register_vlan(dev, port, vlan, &vlan_index);
1864 if (!err) {
1865 set_param_l(out_param, (u32) vlan_index);
1866 err = vlan_add_to_slave(dev, slave, vlan, port, vlan_index);
1867 if (err)
1868 __mlx4_unregister_vlan(dev, port, vlan);
1869 }
1870 return err;
1871}
1872
1478static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd, 1873static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1479 u64 in_param, u64 *out_param) 1874 u64 in_param, u64 *out_param)
1480{ 1875{
@@ -1484,15 +1879,23 @@ static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1484 if (op != RES_OP_RESERVE) 1879 if (op != RES_OP_RESERVE)
1485 return -EINVAL; 1880 return -EINVAL;
1486 1881
1487 err = __mlx4_counter_alloc(dev, &index); 1882 err = mlx4_grant_resource(dev, slave, RES_COUNTER, 1, 0);
1488 if (err) 1883 if (err)
1489 return err; 1884 return err;
1490 1885
1886 err = __mlx4_counter_alloc(dev, &index);
1887 if (err) {
1888 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
1889 return err;
1890 }
1891
1491 err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0); 1892 err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0);
1492 if (err) 1893 if (err) {
1493 __mlx4_counter_free(dev, index); 1894 __mlx4_counter_free(dev, index);
1494 else 1895 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
1896 } else {
1495 set_param_l(out_param, index); 1897 set_param_l(out_param, index);
1898 }
1496 1899
1497 return err; 1900 return err;
1498} 1901}
@@ -1528,7 +1931,7 @@ int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
1528 int err; 1931 int err;
1529 int alop = vhcr->op_modifier; 1932 int alop = vhcr->op_modifier;
1530 1933
1531 switch (vhcr->in_modifier) { 1934 switch (vhcr->in_modifier & 0xFF) {
1532 case RES_QP: 1935 case RES_QP:
1533 err = qp_alloc_res(dev, slave, vhcr->op_modifier, alop, 1936 err = qp_alloc_res(dev, slave, vhcr->op_modifier, alop,
1534 vhcr->in_param, &vhcr->out_param); 1937 vhcr->in_param, &vhcr->out_param);
@@ -1556,12 +1959,14 @@ int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
1556 1959
1557 case RES_MAC: 1960 case RES_MAC:
1558 err = mac_alloc_res(dev, slave, vhcr->op_modifier, alop, 1961 err = mac_alloc_res(dev, slave, vhcr->op_modifier, alop,
1559 vhcr->in_param, &vhcr->out_param); 1962 vhcr->in_param, &vhcr->out_param,
1963 (vhcr->in_modifier >> 8) & 0xFF);
1560 break; 1964 break;
1561 1965
1562 case RES_VLAN: 1966 case RES_VLAN:
1563 err = vlan_alloc_res(dev, slave, vhcr->op_modifier, alop, 1967 err = vlan_alloc_res(dev, slave, vhcr->op_modifier, alop,
1564 vhcr->in_param, &vhcr->out_param); 1968 vhcr->in_param, &vhcr->out_param,
1969 (vhcr->in_modifier >> 8) & 0xFF);
1565 break; 1970 break;
1566 1971
1567 case RES_COUNTER: 1972 case RES_COUNTER:
@@ -1597,6 +2002,7 @@ static int qp_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1597 err = rem_res_range(dev, slave, base, count, RES_QP, 0); 2002 err = rem_res_range(dev, slave, base, count, RES_QP, 0);
1598 if (err) 2003 if (err)
1599 break; 2004 break;
2005 mlx4_release_resource(dev, slave, RES_QP, count, 0);
1600 __mlx4_qp_release_range(dev, base, count); 2006 __mlx4_qp_release_range(dev, base, count);
1601 break; 2007 break;
1602 case RES_OP_MAP_ICM: 2008 case RES_OP_MAP_ICM:
@@ -1634,8 +2040,10 @@ static int mtt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1634 base = get_param_l(&in_param); 2040 base = get_param_l(&in_param);
1635 order = get_param_h(&in_param); 2041 order = get_param_h(&in_param);
1636 err = rem_res_range(dev, slave, base, 1, RES_MTT, order); 2042 err = rem_res_range(dev, slave, base, 1, RES_MTT, order);
1637 if (!err) 2043 if (!err) {
2044 mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1638 __mlx4_free_mtt_range(dev, base, order); 2045 __mlx4_free_mtt_range(dev, base, order);
2046 }
1639 return err; 2047 return err;
1640} 2048}
1641 2049
@@ -1660,6 +2068,7 @@ static int mpt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1660 err = rem_res_range(dev, slave, id, 1, RES_MPT, 0); 2068 err = rem_res_range(dev, slave, id, 1, RES_MPT, 0);
1661 if (err) 2069 if (err)
1662 break; 2070 break;
2071 mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1663 __mlx4_mpt_release(dev, index); 2072 __mlx4_mpt_release(dev, index);
1664 break; 2073 break;
1665 case RES_OP_MAP_ICM: 2074 case RES_OP_MAP_ICM:
@@ -1694,6 +2103,7 @@ static int cq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1694 if (err) 2103 if (err)
1695 break; 2104 break;
1696 2105
2106 mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1697 __mlx4_cq_free_icm(dev, cqn); 2107 __mlx4_cq_free_icm(dev, cqn);
1698 break; 2108 break;
1699 2109
@@ -1718,6 +2128,7 @@ static int srq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1718 if (err) 2128 if (err)
1719 break; 2129 break;
1720 2130
2131 mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1721 __mlx4_srq_free_icm(dev, srqn); 2132 __mlx4_srq_free_icm(dev, srqn);
1722 break; 2133 break;
1723 2134
@@ -1730,14 +2141,14 @@ static int srq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1730} 2141}
1731 2142
1732static int mac_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, 2143static int mac_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1733 u64 in_param, u64 *out_param) 2144 u64 in_param, u64 *out_param, int in_port)
1734{ 2145{
1735 int port; 2146 int port;
1736 int err = 0; 2147 int err = 0;
1737 2148
1738 switch (op) { 2149 switch (op) {
1739 case RES_OP_RESERVE_AND_MAP: 2150 case RES_OP_RESERVE_AND_MAP:
1740 port = get_param_l(out_param); 2151 port = !in_port ? get_param_l(out_param) : in_port;
1741 mac_del_from_slave(dev, slave, in_param, port); 2152 mac_del_from_slave(dev, slave, in_param, port);
1742 __mlx4_unregister_mac(dev, port, in_param); 2153 __mlx4_unregister_mac(dev, port, in_param);
1743 break; 2154 break;
@@ -1751,9 +2162,27 @@ static int mac_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1751} 2162}
1752 2163
1753static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, 2164static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1754 u64 in_param, u64 *out_param) 2165 u64 in_param, u64 *out_param, int port)
1755{ 2166{
1756 return 0; 2167 struct mlx4_priv *priv = mlx4_priv(dev);
2168 struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
2169 int err = 0;
2170
2171 switch (op) {
2172 case RES_OP_RESERVE_AND_MAP:
2173 if (slave_state[slave].old_vlan_api)
2174 return 0;
2175 if (!port)
2176 return -EINVAL;
2177 vlan_del_from_slave(dev, slave, in_param, port);
2178 __mlx4_unregister_vlan(dev, port, in_param);
2179 break;
2180 default:
2181 err = -EINVAL;
2182 break;
2183 }
2184
2185 return err;
1757} 2186}
1758 2187
1759static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd, 2188static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
@@ -1771,6 +2200,7 @@ static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1771 return err; 2200 return err;
1772 2201
1773 __mlx4_counter_free(dev, index); 2202 __mlx4_counter_free(dev, index);
2203 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
1774 2204
1775 return err; 2205 return err;
1776} 2206}
@@ -1803,7 +2233,7 @@ int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
1803 int err = -EINVAL; 2233 int err = -EINVAL;
1804 int alop = vhcr->op_modifier; 2234 int alop = vhcr->op_modifier;
1805 2235
1806 switch (vhcr->in_modifier) { 2236 switch (vhcr->in_modifier & 0xFF) {
1807 case RES_QP: 2237 case RES_QP:
1808 err = qp_free_res(dev, slave, vhcr->op_modifier, alop, 2238 err = qp_free_res(dev, slave, vhcr->op_modifier, alop,
1809 vhcr->in_param); 2239 vhcr->in_param);
@@ -1831,12 +2261,14 @@ int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
1831 2261
1832 case RES_MAC: 2262 case RES_MAC:
1833 err = mac_free_res(dev, slave, vhcr->op_modifier, alop, 2263 err = mac_free_res(dev, slave, vhcr->op_modifier, alop,
1834 vhcr->in_param, &vhcr->out_param); 2264 vhcr->in_param, &vhcr->out_param,
2265 (vhcr->in_modifier >> 8) & 0xFF);
1835 break; 2266 break;
1836 2267
1837 case RES_VLAN: 2268 case RES_VLAN:
1838 err = vlan_free_res(dev, slave, vhcr->op_modifier, alop, 2269 err = vlan_free_res(dev, slave, vhcr->op_modifier, alop,
1839 vhcr->in_param, &vhcr->out_param); 2270 vhcr->in_param, &vhcr->out_param,
2271 (vhcr->in_modifier >> 8) & 0xFF);
1840 break; 2272 break;
1841 2273
1842 case RES_COUNTER: 2274 case RES_COUNTER:
@@ -3498,6 +3930,11 @@ static void rem_slave_qps(struct mlx4_dev *dev, int slave)
3498 &tracker->res_tree[RES_QP]); 3930 &tracker->res_tree[RES_QP]);
3499 list_del(&qp->com.list); 3931 list_del(&qp->com.list);
3500 spin_unlock_irq(mlx4_tlock(dev)); 3932 spin_unlock_irq(mlx4_tlock(dev));
3933 if (!valid_reserved(dev, slave, qpn)) {
3934 __mlx4_qp_release_range(dev, qpn, 1);
3935 mlx4_release_resource(dev, slave,
3936 RES_QP, 1, 0);
3937 }
3501 kfree(qp); 3938 kfree(qp);
3502 state = 0; 3939 state = 0;
3503 break; 3940 break;
@@ -3569,6 +4006,8 @@ static void rem_slave_srqs(struct mlx4_dev *dev, int slave)
3569 &tracker->res_tree[RES_SRQ]); 4006 &tracker->res_tree[RES_SRQ]);
3570 list_del(&srq->com.list); 4007 list_del(&srq->com.list);
3571 spin_unlock_irq(mlx4_tlock(dev)); 4008 spin_unlock_irq(mlx4_tlock(dev));
4009 mlx4_release_resource(dev, slave,
4010 RES_SRQ, 1, 0);
3572 kfree(srq); 4011 kfree(srq);
3573 state = 0; 4012 state = 0;
3574 break; 4013 break;
@@ -3635,6 +4074,8 @@ static void rem_slave_cqs(struct mlx4_dev *dev, int slave)
3635 &tracker->res_tree[RES_CQ]); 4074 &tracker->res_tree[RES_CQ]);
3636 list_del(&cq->com.list); 4075 list_del(&cq->com.list);
3637 spin_unlock_irq(mlx4_tlock(dev)); 4076 spin_unlock_irq(mlx4_tlock(dev));
4077 mlx4_release_resource(dev, slave,
4078 RES_CQ, 1, 0);
3638 kfree(cq); 4079 kfree(cq);
3639 state = 0; 4080 state = 0;
3640 break; 4081 break;
@@ -3698,6 +4139,8 @@ static void rem_slave_mrs(struct mlx4_dev *dev, int slave)
3698 &tracker->res_tree[RES_MPT]); 4139 &tracker->res_tree[RES_MPT]);
3699 list_del(&mpt->com.list); 4140 list_del(&mpt->com.list);
3700 spin_unlock_irq(mlx4_tlock(dev)); 4141 spin_unlock_irq(mlx4_tlock(dev));
4142 mlx4_release_resource(dev, slave,
4143 RES_MPT, 1, 0);
3701 kfree(mpt); 4144 kfree(mpt);
3702 state = 0; 4145 state = 0;
3703 break; 4146 break;
@@ -3767,6 +4210,8 @@ static void rem_slave_mtts(struct mlx4_dev *dev, int slave)
3767 &tracker->res_tree[RES_MTT]); 4210 &tracker->res_tree[RES_MTT]);
3768 list_del(&mtt->com.list); 4211 list_del(&mtt->com.list);
3769 spin_unlock_irq(mlx4_tlock(dev)); 4212 spin_unlock_irq(mlx4_tlock(dev));
4213 mlx4_release_resource(dev, slave, RES_MTT,
4214 1 << mtt->order, 0);
3770 kfree(mtt); 4215 kfree(mtt);
3771 state = 0; 4216 state = 0;
3772 break; 4217 break;
@@ -3925,6 +4370,7 @@ static void rem_slave_counters(struct mlx4_dev *dev, int slave)
3925 list_del(&counter->com.list); 4370 list_del(&counter->com.list);
3926 kfree(counter); 4371 kfree(counter);
3927 __mlx4_counter_free(dev, index); 4372 __mlx4_counter_free(dev, index);
4373 mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
3928 } 4374 }
3929 } 4375 }
3930 spin_unlock_irq(mlx4_tlock(dev)); 4376 spin_unlock_irq(mlx4_tlock(dev));
@@ -3964,7 +4410,7 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
3964 struct mlx4_priv *priv = mlx4_priv(dev); 4410 struct mlx4_priv *priv = mlx4_priv(dev);
3965 4411
3966 mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); 4412 mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
3967 /*VLAN*/ 4413 rem_slave_vlans(dev, slave);
3968 rem_slave_macs(dev, slave); 4414 rem_slave_macs(dev, slave);
3969 rem_slave_fs_rule(dev, slave); 4415 rem_slave_fs_rule(dev, slave);
3970 rem_slave_qps(dev, slave); 4416 rem_slave_qps(dev, slave);
@@ -4081,7 +4527,7 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
4081 if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN && !errors && 4527 if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN && !errors &&
4082 NO_INDX != work->orig_vlan_ix) 4528 NO_INDX != work->orig_vlan_ix)
4083 __mlx4_unregister_vlan(&work->priv->dev, work->port, 4529 __mlx4_unregister_vlan(&work->priv->dev, work->port,
4084 work->orig_vlan_ix); 4530 work->orig_vlan_id);
4085out: 4531out:
4086 kfree(work); 4532 kfree(work);
4087 return; 4533 return;
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 9ad0c18495ad..f6f59271f857 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -54,6 +54,7 @@ enum {
54 MLX4_FLAG_MASTER = 1 << 2, 54 MLX4_FLAG_MASTER = 1 << 2,
55 MLX4_FLAG_SLAVE = 1 << 3, 55 MLX4_FLAG_SLAVE = 1 << 3,
56 MLX4_FLAG_SRIOV = 1 << 4, 56 MLX4_FLAG_SRIOV = 1 << 4,
57 MLX4_FLAG_OLD_REG_MAC = 1 << 6,
57}; 58};
58 59
59enum { 60enum {
@@ -640,12 +641,23 @@ struct mlx4_counter {
640 __be64 tx_bytes; 641 __be64 tx_bytes;
641}; 642};
642 643
644struct mlx4_quotas {
645 int qp;
646 int cq;
647 int srq;
648 int mpt;
649 int mtt;
650 int counter;
651 int xrcd;
652};
653
643struct mlx4_dev { 654struct mlx4_dev {
644 struct pci_dev *pdev; 655 struct pci_dev *pdev;
645 unsigned long flags; 656 unsigned long flags;
646 unsigned long num_slaves; 657 unsigned long num_slaves;
647 struct mlx4_caps caps; 658 struct mlx4_caps caps;
648 struct mlx4_phys_caps phys_caps; 659 struct mlx4_phys_caps phys_caps;
660 struct mlx4_quotas quotas;
649 struct radix_tree_root qp_table_tree; 661 struct radix_tree_root qp_table_tree;
650 u8 rev_id; 662 u8 rev_id;
651 char board_id[MLX4_BOARD_ID_LEN]; 663 char board_id[MLX4_BOARD_ID_LEN];
@@ -771,6 +783,12 @@ static inline int mlx4_is_master(struct mlx4_dev *dev)
771 return dev->flags & MLX4_FLAG_MASTER; 783 return dev->flags & MLX4_FLAG_MASTER;
772} 784}
773 785
786static inline int mlx4_num_reserved_sqps(struct mlx4_dev *dev)
787{
788 return dev->phys_caps.base_sqpn + 8 +
789 16 * MLX4_MFUNC_MAX * !!mlx4_is_master(dev);
790}
791
774static inline int mlx4_is_qp_reserved(struct mlx4_dev *dev, u32 qpn) 792static inline int mlx4_is_qp_reserved(struct mlx4_dev *dev, u32 qpn)
775{ 793{
776 return (qpn < dev->phys_caps.base_sqpn + 8 + 794 return (qpn < dev->phys_caps.base_sqpn + 8 +
@@ -1078,7 +1096,7 @@ int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
1078 u8 *pg, u16 *ratelimit); 1096 u8 *pg, u16 *ratelimit);
1079int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx); 1097int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
1080int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); 1098int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
1081void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index); 1099void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan);
1082 1100
1083int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list, 1101int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list,
1084 int npages, u64 iova, u32 *lkey, u32 *rkey); 1102 int npages, u64 iova, u32 *lkey, u32 *rkey);