aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c218
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h22
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/profile.c5
5 files changed, 198 insertions, 69 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index bce0579a285..0f2069d9827 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -997,6 +997,15 @@ static struct mlx4_cmd_info cmd_info[] = {
997 .wrapper = mlx4_QP_ATTACH_wrapper 997 .wrapper = mlx4_QP_ATTACH_wrapper
998 }, 998 },
999 { 999 {
1000 .opcode = MLX4_CMD_PROMISC,
1001 .has_inbox = false,
1002 .has_outbox = false,
1003 .out_is_imm = false,
1004 .encode_slave_id = false,
1005 .verify = NULL,
1006 .wrapper = mlx4_PROMISC_wrapper
1007 },
1008 {
1000 .opcode = MLX4_CMD_INFORM_FLR_DONE, 1009 .opcode = MLX4_CMD_INFORM_FLR_DONE,
1001 .has_inbox = false, 1010 .has_inbox = false,
1002 .has_outbox = false, 1011 .has_outbox = false,
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 64d03f8b23a..8be56326b04 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -75,6 +75,14 @@ MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero");
75 75
76#endif /* CONFIG_PCI_MSI */ 76#endif /* CONFIG_PCI_MSI */
77 77
78int mlx4_log_num_mgm_entry_size = 10;
79module_param_named(log_num_mgm_entry_size,
80 mlx4_log_num_mgm_entry_size, int, 0444);
81MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num"
82 " of qp per mcg, for example:"
83 " 10 gives 248.range: 9<="
84 " log_num_mgm_entry_size <= 12");
85
78static char mlx4_version[] __devinitdata = 86static char mlx4_version[] __devinitdata =
79 DRV_NAME ": Mellanox ConnectX core driver v" 87 DRV_NAME ": Mellanox ConnectX core driver v"
80 DRV_VERSION " (" DRV_RELDATE ")\n"; 88 DRV_VERSION " (" DRV_RELDATE ")\n";
@@ -205,7 +213,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
205 dev->caps.reserved_srqs = dev_cap->reserved_srqs; 213 dev->caps.reserved_srqs = dev_cap->reserved_srqs;
206 dev->caps.max_sq_desc_sz = dev_cap->max_sq_desc_sz; 214 dev->caps.max_sq_desc_sz = dev_cap->max_sq_desc_sz;
207 dev->caps.max_rq_desc_sz = dev_cap->max_rq_desc_sz; 215 dev->caps.max_rq_desc_sz = dev_cap->max_rq_desc_sz;
208 dev->caps.num_qp_per_mgm = MLX4_QP_PER_MGM; 216 dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev);
209 /* 217 /*
210 * Subtract 1 from the limit because we need to allocate a 218 * Subtract 1 from the limit because we need to allocate a
211 * spare CQE so the HCA HW can tell the difference between an 219 * spare CQE so the HCA HW can tell the difference between an
@@ -648,7 +656,8 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
648 * and it's a lot easier than trying to track ref counts. 656 * and it's a lot easier than trying to track ref counts.
649 */ 657 */
650 err = mlx4_init_icm_table(dev, &priv->mcg_table.table, 658 err = mlx4_init_icm_table(dev, &priv->mcg_table.table,
651 init_hca->mc_base, MLX4_MGM_ENTRY_SIZE, 659 init_hca->mc_base,
660 mlx4_get_mgm_entry_size(dev),
652 dev->caps.num_mgms + dev->caps.num_amgms, 661 dev->caps.num_mgms + dev->caps.num_amgms,
653 dev->caps.num_mgms + dev->caps.num_amgms, 662 dev->caps.num_mgms + dev->caps.num_amgms,
654 0, 0); 663 0, 0);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 4187f7bbd79..b36c279bcca 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -44,6 +44,24 @@
44 44
45static const u8 zero_gid[16]; /* automatically initialized to 0 */ 45static const u8 zero_gid[16]; /* automatically initialized to 0 */
46 46
47struct mlx4_mgm {
48 __be32 next_gid_index;
49 __be32 members_count;
50 u32 reserved[2];
51 u8 gid[16];
52 __be32 qp[MLX4_MAX_QP_PER_MGM];
53};
54
55int mlx4_get_mgm_entry_size(struct mlx4_dev *dev)
56{
57 return min((1 << mlx4_log_num_mgm_entry_size), MLX4_MAX_MGM_ENTRY_SIZE);
58}
59
60int mlx4_get_qp_per_mgm(struct mlx4_dev *dev)
61{
62 return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2);
63}
64
47static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index, 65static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index,
48 struct mlx4_cmd_mailbox *mailbox) 66 struct mlx4_cmd_mailbox *mailbox)
49{ 67{
@@ -58,12 +76,12 @@ static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index,
58 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 76 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
59} 77}
60 78
61static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 vep_num, u8 port, u8 steer, 79static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 port, u8 steer,
62 struct mlx4_cmd_mailbox *mailbox) 80 struct mlx4_cmd_mailbox *mailbox)
63{ 81{
64 u32 in_mod; 82 u32 in_mod;
65 83
66 in_mod = (u32) vep_num << 24 | (u32) port << 16 | steer << 1; 84 in_mod = (u32) port << 16 | steer << 1;
67 return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1, 85 return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1,
68 MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A, 86 MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A,
69 MLX4_CMD_NATIVE); 87 MLX4_CMD_NATIVE);
@@ -104,7 +122,7 @@ static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num,
104 * Add new entry to steering data structure. 122 * Add new entry to steering data structure.
105 * All promisc QPs should be added as well 123 * All promisc QPs should be added as well
106 */ 124 */
107static int new_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port, 125static int new_steering_entry(struct mlx4_dev *dev, u8 port,
108 enum mlx4_steer_type steer, 126 enum mlx4_steer_type steer,
109 unsigned int index, u32 qpn) 127 unsigned int index, u32 qpn)
110{ 128{
@@ -117,10 +135,8 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
117 struct mlx4_promisc_qp *dqp = NULL; 135 struct mlx4_promisc_qp *dqp = NULL;
118 u32 prot; 136 u32 prot;
119 int err; 137 int err;
120 u8 pf_num;
121 138
122 pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1); 139 s_steer = &mlx4_priv(dev)->steer[0];
123 s_steer = &mlx4_priv(dev)->steer[pf_num];
124 new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL); 140 new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
125 if (!new_entry) 141 if (!new_entry)
126 return -ENOMEM; 142 return -ENOMEM;
@@ -132,7 +148,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
132 /* If the given qpn is also a promisc qp, 148 /* If the given qpn is also a promisc qp,
133 * it should be inserted to duplicates list 149 * it should be inserted to duplicates list
134 */ 150 */
135 pqp = get_promisc_qp(dev, pf_num, steer, qpn); 151 pqp = get_promisc_qp(dev, 0, steer, qpn);
136 if (pqp) { 152 if (pqp) {
137 dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 153 dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
138 if (!dqp) { 154 if (!dqp) {
@@ -167,7 +183,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
167 /* don't add already existing qpn */ 183 /* don't add already existing qpn */
168 if (pqp->qpn == qpn) 184 if (pqp->qpn == qpn)
169 continue; 185 continue;
170 if (members_count == MLX4_QP_PER_MGM) { 186 if (members_count == dev->caps.num_qp_per_mgm) {
171 /* out of space */ 187 /* out of space */
172 err = -ENOMEM; 188 err = -ENOMEM;
173 goto out_mailbox; 189 goto out_mailbox;
@@ -195,7 +211,7 @@ out_alloc:
195} 211}
196 212
197/* update the data structures with existing steering entry */ 213/* update the data structures with existing steering entry */
198static int existing_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port, 214static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
199 enum mlx4_steer_type steer, 215 enum mlx4_steer_type steer,
200 unsigned int index, u32 qpn) 216 unsigned int index, u32 qpn)
201{ 217{
@@ -203,12 +219,10 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
203 struct mlx4_steer_index *tmp_entry, *entry = NULL; 219 struct mlx4_steer_index *tmp_entry, *entry = NULL;
204 struct mlx4_promisc_qp *pqp; 220 struct mlx4_promisc_qp *pqp;
205 struct mlx4_promisc_qp *dqp; 221 struct mlx4_promisc_qp *dqp;
206 u8 pf_num;
207 222
208 pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1); 223 s_steer = &mlx4_priv(dev)->steer[0];
209 s_steer = &mlx4_priv(dev)->steer[pf_num];
210 224
211 pqp = get_promisc_qp(dev, pf_num, steer, qpn); 225 pqp = get_promisc_qp(dev, 0, steer, qpn);
212 if (!pqp) 226 if (!pqp)
213 return 0; /* nothing to do */ 227 return 0; /* nothing to do */
214 228
@@ -227,7 +241,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
227 * we need to add it as a duplicate to this entry 241 * we need to add it as a duplicate to this entry
228 * for future references */ 242 * for future references */
229 list_for_each_entry(dqp, &entry->duplicates, list) { 243 list_for_each_entry(dqp, &entry->duplicates, list) {
230 if (qpn == dqp->qpn) 244 if (qpn == pqp->qpn)
231 return 0; /* qp is already duplicated */ 245 return 0; /* qp is already duplicated */
232 } 246 }
233 247
@@ -243,20 +257,18 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
243 257
244/* Check whether a qpn is a duplicate on steering entry 258/* Check whether a qpn is a duplicate on steering entry
245 * If so, it should not be removed from mgm */ 259 * If so, it should not be removed from mgm */
246static bool check_duplicate_entry(struct mlx4_dev *dev, u8 vep_num, u8 port, 260static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
247 enum mlx4_steer_type steer, 261 enum mlx4_steer_type steer,
248 unsigned int index, u32 qpn) 262 unsigned int index, u32 qpn)
249{ 263{
250 struct mlx4_steer *s_steer; 264 struct mlx4_steer *s_steer;
251 struct mlx4_steer_index *tmp_entry, *entry = NULL; 265 struct mlx4_steer_index *tmp_entry, *entry = NULL;
252 struct mlx4_promisc_qp *dqp, *tmp_dqp; 266 struct mlx4_promisc_qp *dqp, *tmp_dqp;
253 u8 pf_num;
254 267
255 pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1); 268 s_steer = &mlx4_priv(dev)->steer[0];
256 s_steer = &mlx4_priv(dev)->steer[pf_num];
257 269
258 /* if qp is not promisc, it cannot be duplicated */ 270 /* if qp is not promisc, it cannot be duplicated */
259 if (!get_promisc_qp(dev, pf_num, steer, qpn)) 271 if (!get_promisc_qp(dev, 0, steer, qpn))
260 return false; 272 return false;
261 273
262 /* The qp is promisc qp so it is a duplicate on this index 274 /* The qp is promisc qp so it is a duplicate on this index
@@ -281,7 +293,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
281} 293}
282 294
283/* I a steering entry contains only promisc QPs, it can be removed. */ 295/* I a steering entry contains only promisc QPs, it can be removed. */
284static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port, 296static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
285 enum mlx4_steer_type steer, 297 enum mlx4_steer_type steer,
286 unsigned int index, u32 tqpn) 298 unsigned int index, u32 tqpn)
287{ 299{
@@ -293,10 +305,8 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
293 u32 members_count; 305 u32 members_count;
294 bool ret = false; 306 bool ret = false;
295 int i; 307 int i;
296 u8 pf_num;
297 308
298 pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1); 309 s_steer = &mlx4_priv(dev)->steer[0];
299 s_steer = &mlx4_priv(dev)->steer[pf_num];
300 310
301 mailbox = mlx4_alloc_cmd_mailbox(dev); 311 mailbox = mlx4_alloc_cmd_mailbox(dev);
302 if (IS_ERR(mailbox)) 312 if (IS_ERR(mailbox))
@@ -308,7 +318,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
308 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 318 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
309 for (i = 0; i < members_count; i++) { 319 for (i = 0; i < members_count; i++) {
310 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; 320 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
311 if (!get_promisc_qp(dev, pf_num, steer, qpn) && qpn != tqpn) { 321 if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) {
312 /* the qp is not promisc, the entry can't be removed */ 322 /* the qp is not promisc, the entry can't be removed */
313 goto out; 323 goto out;
314 } 324 }
@@ -334,7 +344,7 @@ out:
334 return ret; 344 return ret;
335} 345}
336 346
337static int add_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port, 347static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
338 enum mlx4_steer_type steer, u32 qpn) 348 enum mlx4_steer_type steer, u32 qpn)
339{ 349{
340 struct mlx4_steer *s_steer; 350 struct mlx4_steer *s_steer;
@@ -349,14 +359,13 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
349 bool found; 359 bool found;
350 int last_index; 360 int last_index;
351 int err; 361 int err;
352 u8 pf_num;
353 struct mlx4_priv *priv = mlx4_priv(dev); 362 struct mlx4_priv *priv = mlx4_priv(dev);
354 pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1); 363
355 s_steer = &mlx4_priv(dev)->steer[pf_num]; 364 s_steer = &mlx4_priv(dev)->steer[0];
356 365
357 mutex_lock(&priv->mcg_table.mutex); 366 mutex_lock(&priv->mcg_table.mutex);
358 367
359 if (get_promisc_qp(dev, pf_num, steer, qpn)) { 368 if (get_promisc_qp(dev, 0, steer, qpn)) {
360 err = 0; /* Noting to do, already exists */ 369 err = 0; /* Noting to do, already exists */
361 goto out_mutex; 370 goto out_mutex;
362 } 371 }
@@ -399,7 +408,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
399 } 408 }
400 if (!found) { 409 if (!found) {
401 /* Need to add the qpn to mgm */ 410 /* Need to add the qpn to mgm */
402 if (members_count == MLX4_QP_PER_MGM) { 411 if (members_count == dev->caps.num_qp_per_mgm) {
403 /* entry is full */ 412 /* entry is full */
404 err = -ENOMEM; 413 err = -ENOMEM;
405 goto out_mailbox; 414 goto out_mailbox;
@@ -422,7 +431,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
422 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 431 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
423 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 432 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
424 433
425 err = mlx4_WRITE_PROMISC(dev, vep_num, port, steer, mailbox); 434 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
426 if (err) 435 if (err)
427 goto out_list; 436 goto out_list;
428 437
@@ -441,7 +450,7 @@ out_mutex:
441 return err; 450 return err;
442} 451}
443 452
444static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port, 453static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
445 enum mlx4_steer_type steer, u32 qpn) 454 enum mlx4_steer_type steer, u32 qpn)
446{ 455{
447 struct mlx4_priv *priv = mlx4_priv(dev); 456 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -456,13 +465,11 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
456 bool back_to_list = false; 465 bool back_to_list = false;
457 int loc, i; 466 int loc, i;
458 int err; 467 int err;
459 u8 pf_num;
460 468
461 pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1); 469 s_steer = &mlx4_priv(dev)->steer[0];
462 s_steer = &mlx4_priv(dev)->steer[pf_num];
463 mutex_lock(&priv->mcg_table.mutex); 470 mutex_lock(&priv->mcg_table.mutex);
464 471
465 pqp = get_promisc_qp(dev, pf_num, steer, qpn); 472 pqp = get_promisc_qp(dev, 0, steer, qpn);
466 if (unlikely(!pqp)) { 473 if (unlikely(!pqp)) {
467 mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); 474 mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);
468 /* nothing to do */ 475 /* nothing to do */
@@ -481,12 +488,13 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
481 goto out_list; 488 goto out_list;
482 } 489 }
483 mgm = mailbox->buf; 490 mgm = mailbox->buf;
491 memset(mgm, 0, sizeof *mgm);
484 members_count = 0; 492 members_count = 0;
485 list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) 493 list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
486 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 494 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
487 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 495 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
488 496
489 err = mlx4_WRITE_PROMISC(dev, vep_num, port, steer, mailbox); 497 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
490 if (err) 498 if (err)
491 goto out_mailbox; 499 goto out_mailbox;
492 500
@@ -651,12 +659,13 @@ int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
651 } 659 }
652 index += dev->caps.num_mgms; 660 index += dev->caps.num_mgms;
653 661
662 new_entry = 1;
654 memset(mgm, 0, sizeof *mgm); 663 memset(mgm, 0, sizeof *mgm);
655 memcpy(mgm->gid, gid, 16); 664 memcpy(mgm->gid, gid, 16);
656 } 665 }
657 666
658 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 667 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
659 if (members_count == MLX4_QP_PER_MGM) { 668 if (members_count == dev->caps.num_qp_per_mgm) {
660 mlx4_err(dev, "MGM at index %x is full.\n", index); 669 mlx4_err(dev, "MGM at index %x is full.\n", index);
661 err = -ENOMEM; 670 err = -ENOMEM;
662 goto out; 671 goto out;
@@ -698,9 +707,9 @@ out:
698 if (prot == MLX4_PROT_ETH) { 707 if (prot == MLX4_PROT_ETH) {
699 /* manage the steering entry for promisc mode */ 708 /* manage the steering entry for promisc mode */
700 if (new_entry) 709 if (new_entry)
701 new_steering_entry(dev, 0, port, steer, index, qp->qpn); 710 new_steering_entry(dev, port, steer, index, qp->qpn);
702 else 711 else
703 existing_steering_entry(dev, 0, port, steer, 712 existing_steering_entry(dev, port, steer,
704 index, qp->qpn); 713 index, qp->qpn);
705 } 714 }
706 if (err && link && index != -1) { 715 if (err && link && index != -1) {
@@ -751,7 +760,7 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
751 760
752 /* if this pq is also a promisc qp, it shouldn't be removed */ 761 /* if this pq is also a promisc qp, it shouldn't be removed */
753 if (prot == MLX4_PROT_ETH && 762 if (prot == MLX4_PROT_ETH &&
754 check_duplicate_entry(dev, 0, port, steer, index, qp->qpn)) 763 check_duplicate_entry(dev, port, steer, index, qp->qpn))
755 goto out; 764 goto out;
756 765
757 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 766 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
@@ -771,7 +780,8 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
771 mgm->qp[i - 1] = 0; 780 mgm->qp[i - 1] = 0;
772 781
773 if (prot == MLX4_PROT_ETH) 782 if (prot == MLX4_PROT_ETH)
774 removed_entry = can_remove_steering_entry(dev, 0, port, steer, index, qp->qpn); 783 removed_entry = can_remove_steering_entry(dev, port, steer,
784 index, qp->qpn);
775 if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) { 785 if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) {
776 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 786 err = mlx4_WRITE_ENTRY(dev, index, mailbox);
777 goto out; 787 goto out;
@@ -830,6 +840,34 @@ out:
830 return err; 840 return err;
831} 841}
832 842
843static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp,
844 u8 gid[16], u8 attach, u8 block_loopback,
845 enum mlx4_protocol prot)
846{
847 struct mlx4_cmd_mailbox *mailbox;
848 int err = 0;
849 int qpn;
850
851 if (!mlx4_is_mfunc(dev))
852 return -EBADF;
853
854 mailbox = mlx4_alloc_cmd_mailbox(dev);
855 if (IS_ERR(mailbox))
856 return PTR_ERR(mailbox);
857
858 memcpy(mailbox->buf, gid, 16);
859 qpn = qp->qpn;
860 qpn |= (prot << 28);
861 if (attach && block_loopback)
862 qpn |= (1 << 31);
863
864 err = mlx4_cmd(dev, mailbox->dma, qpn, attach,
865 MLX4_CMD_QP_ATTACH, MLX4_CMD_TIME_CLASS_A,
866 MLX4_CMD_WRAPPED);
867
868 mlx4_free_cmd_mailbox(dev, mailbox);
869 return err;
870}
833 871
834int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 872int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
835 int block_mcast_loopback, enum mlx4_protocol prot) 873 int block_mcast_loopback, enum mlx4_protocol prot)
@@ -845,9 +883,12 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
845 if (prot == MLX4_PROT_ETH) 883 if (prot == MLX4_PROT_ETH)
846 gid[7] |= (steer << 1); 884 gid[7] |= (steer << 1);
847 885
848 return mlx4_qp_attach_common(dev, qp, gid, 886 if (mlx4_is_mfunc(dev))
849 block_mcast_loopback, prot, 887 return mlx4_QP_ATTACH(dev, qp, gid, 1,
850 steer); 888 block_mcast_loopback, prot);
889
890 return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback,
891 prot, steer);
851} 892}
852EXPORT_SYMBOL_GPL(mlx4_multicast_attach); 893EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
853 894
@@ -862,22 +903,90 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
862 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 903 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
863 return 0; 904 return 0;
864 905
865 if (prot == MLX4_PROT_ETH) { 906 if (prot == MLX4_PROT_ETH)
866 gid[7] |= (steer << 1); 907 gid[7] |= (steer << 1);
867 } 908
909 if (mlx4_is_mfunc(dev))
910 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
868 911
869 return mlx4_qp_detach_common(dev, qp, gid, prot, steer); 912 return mlx4_qp_detach_common(dev, qp, gid, prot, steer);
870} 913}
871EXPORT_SYMBOL_GPL(mlx4_multicast_detach); 914EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
872 915
916static int mlx4_unicast_attach(struct mlx4_dev *dev,
917 struct mlx4_qp *qp, u8 gid[16],
918 int block_mcast_loopback, enum mlx4_protocol prot)
919{
920 if (prot == MLX4_PROT_ETH &&
921 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
922 return 0;
923
924 if (prot == MLX4_PROT_ETH)
925 gid[7] |= (MLX4_UC_STEER << 1);
926
927 if (mlx4_is_mfunc(dev))
928 return mlx4_QP_ATTACH(dev, qp, gid, 1,
929 block_mcast_loopback, prot);
930
931 return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback,
932 prot, MLX4_UC_STEER);
933}
934EXPORT_SYMBOL_GPL(mlx4_unicast_attach);
935
936static int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
937 u8 gid[16], enum mlx4_protocol prot)
938{
939 if (prot == MLX4_PROT_ETH &&
940 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
941 return 0;
942
943 if (prot == MLX4_PROT_ETH)
944 gid[7] |= (MLX4_UC_STEER << 1);
945
946 if (mlx4_is_mfunc(dev))
947 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
948
949 return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_UC_STEER);
950}
951EXPORT_SYMBOL_GPL(mlx4_unicast_detach);
952
953int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave,
954 struct mlx4_vhcr *vhcr,
955 struct mlx4_cmd_mailbox *inbox,
956 struct mlx4_cmd_mailbox *outbox,
957 struct mlx4_cmd_info *cmd)
958{
959 u32 qpn = (u32) vhcr->in_param & 0xffffffff;
960 u8 port = vhcr->in_param >> 62;
961 enum mlx4_steer_type steer = vhcr->in_modifier;
962
963 /* Promiscuous unicast is not allowed in mfunc */
964 if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)
965 return 0;
966
967 if (vhcr->op_modifier)
968 return add_promisc_qp(dev, port, steer, qpn);
969 else
970 return remove_promisc_qp(dev, port, steer, qpn);
971}
972
973static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn,
974 enum mlx4_steer_type steer, u8 add, u8 port)
975{
976 return mlx4_cmd(dev, (u64) qpn | (u64) port << 62, (u32) steer, add,
977 MLX4_CMD_PROMISC, MLX4_CMD_TIME_CLASS_A,
978 MLX4_CMD_WRAPPED);
979}
873 980
874int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 981int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
875{ 982{
876 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 983 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
877 return 0; 984 return 0;
878 985
986 if (mlx4_is_mfunc(dev))
987 return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port);
879 988
880 return add_promisc_qp(dev, 0, port, MLX4_MC_STEER, qpn); 989 return add_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
881} 990}
882EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add); 991EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add);
883 992
@@ -886,8 +995,10 @@ int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
886 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 995 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
887 return 0; 996 return 0;
888 997
998 if (mlx4_is_mfunc(dev))
999 return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port);
889 1000
890 return remove_promisc_qp(dev, 0, port, MLX4_MC_STEER, qpn); 1001 return remove_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
891} 1002}
892EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove); 1003EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove);
893 1004
@@ -896,8 +1007,10 @@ int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
896 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 1007 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
897 return 0; 1008 return 0;
898 1009
1010 if (mlx4_is_mfunc(dev))
1011 return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port);
899 1012
900 return add_promisc_qp(dev, 0, port, MLX4_UC_STEER, qpn); 1013 return add_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
901} 1014}
902EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add); 1015EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add);
903 1016
@@ -906,7 +1019,10 @@ int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
906 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 1019 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
907 return 0; 1020 return 0;
908 1021
909 return remove_promisc_qp(dev, 0, port, MLX4_UC_STEER, qpn); 1022 if (mlx4_is_mfunc(dev))
1023 return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port);
1024
1025 return remove_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
910} 1026}
911EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove); 1027EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove);
912 1028
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 2488be8bb02..a38ffc99736 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -61,9 +61,9 @@ enum {
61}; 61};
62 62
63enum { 63enum {
64 MLX4_MGM_ENTRY_SIZE = 0x100, 64 MLX4_MAX_MGM_ENTRY_SIZE = 0x1000,
65 MLX4_QP_PER_MGM = 4 * (MLX4_MGM_ENTRY_SIZE / 16 - 2), 65 MLX4_MAX_QP_PER_MGM = 4 * (MLX4_MAX_MGM_ENTRY_SIZE / 16 - 2),
66 MLX4_MTT_ENTRY_PER_SEG = 8 66 MLX4_MTT_ENTRY_PER_SEG = 8,
67}; 67};
68 68
69enum { 69enum {
@@ -190,6 +190,8 @@ do { \
190#define mlx4_warn(mdev, format, arg...) \ 190#define mlx4_warn(mdev, format, arg...) \
191 dev_warn(&mdev->pdev->dev, format, ##arg) 191 dev_warn(&mdev->pdev->dev, format, ##arg)
192 192
193extern int mlx4_log_num_mgm_entry_size;
194
193#define MLX4_MAX_NUM_SLAVES (MLX4_MAX_NUM_PF + MLX4_MAX_NUM_VF) 195#define MLX4_MAX_NUM_SLAVES (MLX4_MAX_NUM_PF + MLX4_MAX_NUM_VF)
194#define ALL_SLAVES 0xff 196#define ALL_SLAVES 0xff
195 197
@@ -417,9 +419,6 @@ struct mlx4_comm {
417 u32 slave_read; 419 u32 slave_read;
418}; 420};
419 421
420#define MGM_QPN_MASK 0x00FFFFFF
421#define MGM_BLCK_LB_BIT 30
422
423#define VLAN_FLTR_SIZE 128 422#define VLAN_FLTR_SIZE 128
424 423
425struct mlx4_vlan_fltr { 424struct mlx4_vlan_fltr {
@@ -437,14 +436,6 @@ struct mlx4_steer_index {
437 struct list_head duplicates; 436 struct list_head duplicates;
438}; 437};
439 438
440struct mlx4_mgm {
441 __be32 next_gid_index;
442 __be32 members_count;
443 u32 reserved[2];
444 u8 gid[16];
445 __be32 qp[MLX4_QP_PER_MGM];
446};
447
448struct mlx4_slave_state { 439struct mlx4_slave_state {
449 u8 comm_toggle; 440 u8 comm_toggle;
450 u8 last_cmd; 441 u8 last_cmd;
@@ -1021,6 +1012,9 @@ int mlx4_QUERY_IF_STAT_wrapper(struct mlx4_dev *dev, int slave,
1021 struct mlx4_cmd_mailbox *outbox, 1012 struct mlx4_cmd_mailbox *outbox,
1022 struct mlx4_cmd_info *cmd); 1013 struct mlx4_cmd_info *cmd);
1023 1014
1015int mlx4_get_mgm_entry_size(struct mlx4_dev *dev);
1016int mlx4_get_qp_per_mgm(struct mlx4_dev *dev);
1017
1024static inline void set_param_l(u64 *arg, u32 val) 1018static inline void set_param_l(u64 *arg, u32 val)
1025{ 1019{
1026 *((u32 *)arg) = val; 1020 *((u32 *)arg) = val;
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c
index b967647d0c7..771c4605ef8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/profile.c
+++ b/drivers/net/ethernet/mellanox/mlx4/profile.c
@@ -99,7 +99,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
99 profile[MLX4_RES_DMPT].size = dev_cap->dmpt_entry_sz; 99 profile[MLX4_RES_DMPT].size = dev_cap->dmpt_entry_sz;
100 profile[MLX4_RES_CMPT].size = dev_cap->cmpt_entry_sz; 100 profile[MLX4_RES_CMPT].size = dev_cap->cmpt_entry_sz;
101 profile[MLX4_RES_MTT].size = dev->caps.mtts_per_seg * dev_cap->mtt_entry_sz; 101 profile[MLX4_RES_MTT].size = dev->caps.mtts_per_seg * dev_cap->mtt_entry_sz;
102 profile[MLX4_RES_MCG].size = MLX4_MGM_ENTRY_SIZE; 102 profile[MLX4_RES_MCG].size = mlx4_get_mgm_entry_size(dev);
103 103
104 profile[MLX4_RES_QP].num = request->num_qp; 104 profile[MLX4_RES_QP].num = request->num_qp;
105 profile[MLX4_RES_RDMARC].num = request->num_qp * request->rdmarc_per_qp; 105 profile[MLX4_RES_RDMARC].num = request->num_qp * request->rdmarc_per_qp;
@@ -218,7 +218,8 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
218 dev->caps.num_mgms = profile[i].num >> 1; 218 dev->caps.num_mgms = profile[i].num >> 1;
219 dev->caps.num_amgms = profile[i].num >> 1; 219 dev->caps.num_amgms = profile[i].num >> 1;
220 init_hca->mc_base = profile[i].start; 220 init_hca->mc_base = profile[i].start;
221 init_hca->log_mc_entry_sz = ilog2(MLX4_MGM_ENTRY_SIZE); 221 init_hca->log_mc_entry_sz =
222 ilog2(mlx4_get_mgm_entry_size(dev));
222 init_hca->log_mc_table_sz = profile[i].log_num; 223 init_hca->log_mc_table_sz = profile[i].log_num;
223 init_hca->log_mc_hash_sz = profile[i].log_num - 1; 224 init_hca->log_mc_hash_sz = profile[i].log_num - 1;
224 break; 225 break;