aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4
diff options
context:
space:
mode:
authorEugenia Emantayev <eugenia@mellanox.co.il>2011-12-12 23:16:02 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-13 13:56:07 -0500
commit0ec2c0f86d31ab36547307f133b0016006bdc6b5 (patch)
treeba799abcd07816fc7ca17b1f1b1f22e2dec31848 /drivers/net/ethernet/mellanox/mlx4
parent8e59d254feb3826230d19fb643691c89eabd71f8 (diff)
mlx4: Traffic steering management support for SRIOV
Let multicast/unicast attaching flow go through resource tracker. The PF is the one responsible for managing all the steering entries. Define and use module parameter that determines the number of qps per multicast group. Minor changes in function calls according to changed prototype. Signed-off-by: Eugenia Emantayev <eugenia@mellanox.co.il> Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: David S. Miller <davem@davemloft.net>
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;