xref: /linux/drivers/net/ethernet/mellanox/mlx4/mcg.c (revision f2ee442115c9b6219083c019939a9cc0c9abb2f8)
1 /*
2  * Copyright (c) 2006, 2007 Cisco Systems, Inc.  All rights reserved.
3  * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33 
34 #include <linux/string.h>
35 #include <linux/etherdevice.h>
36 
37 #include <linux/mlx4/cmd.h>
38 #include <linux/export.h>
39 
40 #include "mlx4.h"
41 
42 #define MGM_QPN_MASK       0x00FFFFFF
43 #define MGM_BLCK_LB_BIT    30
44 
45 static const u8 zero_gid[16];	/* automatically initialized to 0 */
46 
47 static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index,
48 			   struct mlx4_cmd_mailbox *mailbox)
49 {
50 	return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG,
51 			    MLX4_CMD_TIME_CLASS_A);
52 }
53 
54 static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index,
55 			    struct mlx4_cmd_mailbox *mailbox)
56 {
57 	return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG,
58 			MLX4_CMD_TIME_CLASS_A);
59 }
60 
61 static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 vep_num, u8 port, u8 steer,
62 			      struct mlx4_cmd_mailbox *mailbox)
63 {
64 	u32 in_mod;
65 
66 	in_mod = (u32) vep_num << 24 | (u32) port << 16 | steer << 1;
67 	return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1,
68 			MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A);
69 }
70 
71 static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
72 			 u16 *hash, u8 op_mod)
73 {
74 	u64 imm;
75 	int err;
76 
77 	err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod,
78 			   MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A);
79 
80 	if (!err)
81 		*hash = imm;
82 
83 	return err;
84 }
85 
86 static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num,
87 					      enum mlx4_steer_type steer,
88 					      u32 qpn)
89 {
90 	struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num];
91 	struct mlx4_promisc_qp *pqp;
92 
93 	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
94 		if (pqp->qpn == qpn)
95 			return pqp;
96 	}
97 	/* not found */
98 	return NULL;
99 }
100 
101 /*
102  * Add new entry to steering data structure.
103  * All promisc QPs should be added as well
104  */
105 static int new_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
106 			      enum mlx4_steer_type steer,
107 			      unsigned int index, u32 qpn)
108 {
109 	struct mlx4_steer *s_steer;
110 	struct mlx4_cmd_mailbox *mailbox;
111 	struct mlx4_mgm *mgm;
112 	u32 members_count;
113 	struct mlx4_steer_index *new_entry;
114 	struct mlx4_promisc_qp *pqp;
115 	struct mlx4_promisc_qp *dqp = NULL;
116 	u32 prot;
117 	int err;
118 	u8 pf_num;
119 
120 	pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1);
121 	s_steer = &mlx4_priv(dev)->steer[pf_num];
122 	new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
123 	if (!new_entry)
124 		return -ENOMEM;
125 
126 	INIT_LIST_HEAD(&new_entry->duplicates);
127 	new_entry->index = index;
128 	list_add_tail(&new_entry->list, &s_steer->steer_entries[steer]);
129 
130 	/* If the given qpn is also a promisc qp,
131 	 * it should be inserted to duplicates list
132 	 */
133 	pqp = get_promisc_qp(dev, pf_num, steer, qpn);
134 	if (pqp) {
135 		dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
136 		if (!dqp) {
137 			err = -ENOMEM;
138 			goto out_alloc;
139 		}
140 		dqp->qpn = qpn;
141 		list_add_tail(&dqp->list, &new_entry->duplicates);
142 	}
143 
144 	/* if no promisc qps for this vep, we are done */
145 	if (list_empty(&s_steer->promisc_qps[steer]))
146 		return 0;
147 
148 	/* now need to add all the promisc qps to the new
149 	 * steering entry, as they should also receive the packets
150 	 * destined to this address */
151 	mailbox = mlx4_alloc_cmd_mailbox(dev);
152 	if (IS_ERR(mailbox)) {
153 		err = -ENOMEM;
154 		goto out_alloc;
155 	}
156 	mgm = mailbox->buf;
157 
158 	err = mlx4_READ_ENTRY(dev, index, mailbox);
159 	if (err)
160 		goto out_mailbox;
161 
162 	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
163 	prot = be32_to_cpu(mgm->members_count) >> 30;
164 	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
165 		/* don't add already existing qpn */
166 		if (pqp->qpn == qpn)
167 			continue;
168 		if (members_count == MLX4_QP_PER_MGM) {
169 			/* out of space */
170 			err = -ENOMEM;
171 			goto out_mailbox;
172 		}
173 
174 		/* add the qpn */
175 		mgm->qp[members_count++] = cpu_to_be32(pqp->qpn & MGM_QPN_MASK);
176 	}
177 	/* update the qps count and update the entry with all the promisc qps*/
178 	mgm->members_count = cpu_to_be32(members_count | (prot << 30));
179 	err = mlx4_WRITE_ENTRY(dev, index, mailbox);
180 
181 out_mailbox:
182 	mlx4_free_cmd_mailbox(dev, mailbox);
183 	if (!err)
184 		return 0;
185 out_alloc:
186 	if (dqp) {
187 		list_del(&dqp->list);
188 		kfree(dqp);
189 	}
190 	list_del(&new_entry->list);
191 	kfree(new_entry);
192 	return err;
193 }
194 
195 /* update the data structures with existing steering entry */
196 static int existing_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
197 				   enum mlx4_steer_type steer,
198 				   unsigned int index, u32 qpn)
199 {
200 	struct mlx4_steer *s_steer;
201 	struct mlx4_steer_index *tmp_entry, *entry = NULL;
202 	struct mlx4_promisc_qp *pqp;
203 	struct mlx4_promisc_qp *dqp;
204 	u8 pf_num;
205 
206 	pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1);
207 	s_steer = &mlx4_priv(dev)->steer[pf_num];
208 
209 	pqp = get_promisc_qp(dev, pf_num, steer, qpn);
210 	if (!pqp)
211 		return 0; /* nothing to do */
212 
213 	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
214 		if (tmp_entry->index == index) {
215 			entry = tmp_entry;
216 			break;
217 		}
218 	}
219 	if (unlikely(!entry)) {
220 		mlx4_warn(dev, "Steering entry at index %x is not registered\n", index);
221 		return -EINVAL;
222 	}
223 
224 	/* the given qpn is listed as a promisc qpn
225 	 * we need to add it as a duplicate to this entry
226 	 * for future references */
227 	list_for_each_entry(dqp, &entry->duplicates, list) {
228 		if (qpn == dqp->qpn)
229 			return 0; /* qp is already duplicated */
230 	}
231 
232 	/* add the qp as a duplicate on this index */
233 	dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
234 	if (!dqp)
235 		return -ENOMEM;
236 	dqp->qpn = qpn;
237 	list_add_tail(&dqp->list, &entry->duplicates);
238 
239 	return 0;
240 }
241 
242 /* Check whether a qpn is a duplicate on steering entry
243  * If so, it should not be removed from mgm */
244 static bool check_duplicate_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
245 				  enum mlx4_steer_type steer,
246 				  unsigned int index, u32 qpn)
247 {
248 	struct mlx4_steer *s_steer;
249 	struct mlx4_steer_index *tmp_entry, *entry = NULL;
250 	struct mlx4_promisc_qp *dqp, *tmp_dqp;
251 	u8 pf_num;
252 
253 	pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1);
254 	s_steer = &mlx4_priv(dev)->steer[pf_num];
255 
256 	/* if qp is not promisc, it cannot be duplicated */
257 	if (!get_promisc_qp(dev, pf_num, steer, qpn))
258 		return false;
259 
260 	/* The qp is promisc qp so it is a duplicate on this index
261 	 * Find the index entry, and remove the duplicate */
262 	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
263 		if (tmp_entry->index == index) {
264 			entry = tmp_entry;
265 			break;
266 		}
267 	}
268 	if (unlikely(!entry)) {
269 		mlx4_warn(dev, "Steering entry for index %x is not registered\n", index);
270 		return false;
271 	}
272 	list_for_each_entry_safe(dqp, tmp_dqp, &entry->duplicates, list) {
273 		if (dqp->qpn == qpn) {
274 			list_del(&dqp->list);
275 			kfree(dqp);
276 		}
277 	}
278 	return true;
279 }
280 
281 /* I a steering entry contains only promisc QPs, it can be removed. */
282 static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port,
283 				      enum mlx4_steer_type steer,
284 				      unsigned int index, u32 tqpn)
285 {
286 	struct mlx4_steer *s_steer;
287 	struct mlx4_cmd_mailbox *mailbox;
288 	struct mlx4_mgm *mgm;
289 	struct mlx4_steer_index *entry = NULL, *tmp_entry;
290 	u32 qpn;
291 	u32 members_count;
292 	bool ret = false;
293 	int i;
294 	u8 pf_num;
295 
296 	pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1);
297 	s_steer = &mlx4_priv(dev)->steer[pf_num];
298 
299 	mailbox = mlx4_alloc_cmd_mailbox(dev);
300 	if (IS_ERR(mailbox))
301 		return false;
302 	mgm = mailbox->buf;
303 
304 	if (mlx4_READ_ENTRY(dev, index, mailbox))
305 		goto out;
306 	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
307 	for (i = 0;  i < members_count; i++) {
308 		qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
309 		if (!get_promisc_qp(dev, pf_num, steer, qpn) && qpn != tqpn) {
310 			/* the qp is not promisc, the entry can't be removed */
311 			goto out;
312 		}
313 	}
314 	 /* All the qps currently registered for this entry are promiscuous,
315 	  * Checking for duplicates */
316 	ret = true;
317 	list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) {
318 		if (entry->index == index) {
319 			if (list_empty(&entry->duplicates)) {
320 				list_del(&entry->list);
321 				kfree(entry);
322 			} else {
323 				/* This entry contains duplicates so it shouldn't be removed */
324 				ret = false;
325 				goto out;
326 			}
327 		}
328 	}
329 
330 out:
331 	mlx4_free_cmd_mailbox(dev, mailbox);
332 	return ret;
333 }
334 
335 static int add_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
336 			  enum mlx4_steer_type steer, u32 qpn)
337 {
338 	struct mlx4_steer *s_steer;
339 	struct mlx4_cmd_mailbox *mailbox;
340 	struct mlx4_mgm *mgm;
341 	struct mlx4_steer_index *entry;
342 	struct mlx4_promisc_qp *pqp;
343 	struct mlx4_promisc_qp *dqp;
344 	u32 members_count;
345 	u32 prot;
346 	int i;
347 	bool found;
348 	int last_index;
349 	int err;
350 	u8 pf_num;
351 	struct mlx4_priv *priv = mlx4_priv(dev);
352 	pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1);
353 	s_steer = &mlx4_priv(dev)->steer[pf_num];
354 
355 	mutex_lock(&priv->mcg_table.mutex);
356 
357 	if (get_promisc_qp(dev, pf_num, steer, qpn)) {
358 		err = 0;  /* Noting to do, already exists */
359 		goto out_mutex;
360 	}
361 
362 	pqp = kmalloc(sizeof *pqp, GFP_KERNEL);
363 	if (!pqp) {
364 		err = -ENOMEM;
365 		goto out_mutex;
366 	}
367 	pqp->qpn = qpn;
368 
369 	mailbox = mlx4_alloc_cmd_mailbox(dev);
370 	if (IS_ERR(mailbox)) {
371 		err = -ENOMEM;
372 		goto out_alloc;
373 	}
374 	mgm = mailbox->buf;
375 
376 	/* the promisc qp needs to be added for each one of the steering
377 	 * entries, if it already exists, needs to be added as a duplicate
378 	 * for this entry */
379 	list_for_each_entry(entry, &s_steer->steer_entries[steer], list) {
380 		err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
381 		if (err)
382 			goto out_mailbox;
383 
384 		members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
385 		prot = be32_to_cpu(mgm->members_count) >> 30;
386 		found = false;
387 		for (i = 0; i < members_count; i++) {
388 			if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) {
389 				/* Entry already exists, add to duplicates */
390 				dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
391 				if (!dqp)
392 					goto out_mailbox;
393 				dqp->qpn = qpn;
394 				list_add_tail(&dqp->list, &entry->duplicates);
395 				found = true;
396 			}
397 		}
398 		if (!found) {
399 			/* Need to add the qpn to mgm */
400 			if (members_count == MLX4_QP_PER_MGM) {
401 				/* entry is full */
402 				err = -ENOMEM;
403 				goto out_mailbox;
404 			}
405 			mgm->qp[members_count++] = cpu_to_be32(qpn & MGM_QPN_MASK);
406 			mgm->members_count = cpu_to_be32(members_count | (prot << 30));
407 			err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
408 			if (err)
409 				goto out_mailbox;
410 		}
411 		last_index = entry->index;
412 	}
413 
414 	/* add the new qpn to list of promisc qps */
415 	list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
416 	/* now need to add all the promisc qps to default entry */
417 	memset(mgm, 0, sizeof *mgm);
418 	members_count = 0;
419 	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
420 		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
421 	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
422 
423 	err = mlx4_WRITE_PROMISC(dev, vep_num, port, steer, mailbox);
424 	if (err)
425 		goto out_list;
426 
427 	mlx4_free_cmd_mailbox(dev, mailbox);
428 	mutex_unlock(&priv->mcg_table.mutex);
429 	return 0;
430 
431 out_list:
432 	list_del(&pqp->list);
433 out_mailbox:
434 	mlx4_free_cmd_mailbox(dev, mailbox);
435 out_alloc:
436 	kfree(pqp);
437 out_mutex:
438 	mutex_unlock(&priv->mcg_table.mutex);
439 	return err;
440 }
441 
442 static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
443 			     enum mlx4_steer_type steer, u32 qpn)
444 {
445 	struct mlx4_priv *priv = mlx4_priv(dev);
446 	struct mlx4_steer *s_steer;
447 	struct mlx4_cmd_mailbox *mailbox;
448 	struct mlx4_mgm *mgm;
449 	struct mlx4_steer_index *entry;
450 	struct mlx4_promisc_qp *pqp;
451 	struct mlx4_promisc_qp *dqp;
452 	u32 members_count;
453 	bool found;
454 	bool back_to_list = false;
455 	int loc, i;
456 	int err;
457 	u8 pf_num;
458 
459 	pf_num = (dev->caps.num_ports == 1) ? vep_num : (vep_num << 1) | (port - 1);
460 	s_steer = &mlx4_priv(dev)->steer[pf_num];
461 	mutex_lock(&priv->mcg_table.mutex);
462 
463 	pqp = get_promisc_qp(dev, pf_num, steer, qpn);
464 	if (unlikely(!pqp)) {
465 		mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);
466 		/* nothing to do */
467 		err = 0;
468 		goto out_mutex;
469 	}
470 
471 	/*remove from list of promisc qps */
472 	list_del(&pqp->list);
473 
474 	/* set the default entry not to include the removed one */
475 	mailbox = mlx4_alloc_cmd_mailbox(dev);
476 	if (IS_ERR(mailbox)) {
477 		err = -ENOMEM;
478 		back_to_list = true;
479 		goto out_list;
480 	}
481 	mgm = mailbox->buf;
482 	members_count = 0;
483 	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
484 		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
485 	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
486 
487 	err = mlx4_WRITE_PROMISC(dev, vep_num, port, steer, mailbox);
488 	if (err)
489 		goto out_mailbox;
490 
491 	/* remove the qp from all the steering entries*/
492 	list_for_each_entry(entry, &s_steer->steer_entries[steer], list) {
493 		found = false;
494 		list_for_each_entry(dqp, &entry->duplicates, list) {
495 			if (dqp->qpn == qpn) {
496 				found = true;
497 				break;
498 			}
499 		}
500 		if (found) {
501 			/* a duplicate, no need to change the mgm,
502 			 * only update the duplicates list */
503 			list_del(&dqp->list);
504 			kfree(dqp);
505 		} else {
506 			err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
507 				if (err)
508 					goto out_mailbox;
509 			members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
510 			for (loc = -1, i = 0; i < members_count; ++i)
511 				if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn)
512 					loc = i;
513 
514 			mgm->members_count = cpu_to_be32(--members_count |
515 							 (MLX4_PROT_ETH << 30));
516 			mgm->qp[loc] = mgm->qp[i - 1];
517 			mgm->qp[i - 1] = 0;
518 
519 			err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
520 				if (err)
521 					goto out_mailbox;
522 		}
523 
524 	}
525 
526 out_mailbox:
527 	mlx4_free_cmd_mailbox(dev, mailbox);
528 out_list:
529 	if (back_to_list)
530 		list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
531 	else
532 		kfree(pqp);
533 out_mutex:
534 	mutex_unlock(&priv->mcg_table.mutex);
535 	return err;
536 }
537 
538 /*
539  * Caller must hold MCG table semaphore.  gid and mgm parameters must
540  * be properly aligned for command interface.
541  *
542  *  Returns 0 unless a firmware command error occurs.
543  *
544  * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1
545  * and *mgm holds MGM entry.
546  *
547  * if GID is found in AMGM, *index = index in AMGM, *prev = index of
548  * previous entry in hash chain and *mgm holds AMGM entry.
549  *
550  * If no AMGM exists for given gid, *index = -1, *prev = index of last
551  * entry in hash chain and *mgm holds end of hash chain.
552  */
553 static int find_entry(struct mlx4_dev *dev, u8 port,
554 		      u8 *gid, enum mlx4_protocol prot,
555 		      enum mlx4_steer_type steer,
556 		      struct mlx4_cmd_mailbox *mgm_mailbox,
557 		      u16 *hash, int *prev, int *index)
558 {
559 	struct mlx4_cmd_mailbox *mailbox;
560 	struct mlx4_mgm *mgm = mgm_mailbox->buf;
561 	u8 *mgid;
562 	int err;
563 	u8 op_mod = (prot == MLX4_PROT_ETH) ?
564 		!!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0;
565 
566 	mailbox = mlx4_alloc_cmd_mailbox(dev);
567 	if (IS_ERR(mailbox))
568 		return -ENOMEM;
569 	mgid = mailbox->buf;
570 
571 	memcpy(mgid, gid, 16);
572 
573 	err = mlx4_GID_HASH(dev, mailbox, hash, op_mod);
574 	mlx4_free_cmd_mailbox(dev, mailbox);
575 	if (err)
576 		return err;
577 
578 	if (0)
579 		mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, *hash);
580 
581 	*index = *hash;
582 	*prev  = -1;
583 
584 	do {
585 		err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox);
586 		if (err)
587 			return err;
588 
589 		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
590 			if (*index != *hash) {
591 				mlx4_err(dev, "Found zero MGID in AMGM.\n");
592 				err = -EINVAL;
593 			}
594 			return err;
595 		}
596 
597 		if (!memcmp(mgm->gid, gid, 16) &&
598 		    be32_to_cpu(mgm->members_count) >> 30 == prot)
599 			return err;
600 
601 		*prev = *index;
602 		*index = be32_to_cpu(mgm->next_gid_index) >> 6;
603 	} while (*index);
604 
605 	*index = -1;
606 	return err;
607 }
608 
609 int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
610 			  int block_mcast_loopback, enum mlx4_protocol prot,
611 			  enum mlx4_steer_type steer)
612 {
613 	struct mlx4_priv *priv = mlx4_priv(dev);
614 	struct mlx4_cmd_mailbox *mailbox;
615 	struct mlx4_mgm *mgm;
616 	u32 members_count;
617 	u16 hash;
618 	int index, prev;
619 	int link = 0;
620 	int i;
621 	int err;
622 	u8 port = gid[5];
623 	u8 new_entry = 0;
624 
625 	mailbox = mlx4_alloc_cmd_mailbox(dev);
626 	if (IS_ERR(mailbox))
627 		return PTR_ERR(mailbox);
628 	mgm = mailbox->buf;
629 
630 	mutex_lock(&priv->mcg_table.mutex);
631 	err = find_entry(dev, port, gid, prot, steer,
632 			 mailbox, &hash, &prev, &index);
633 	if (err)
634 		goto out;
635 
636 	if (index != -1) {
637 		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
638 			new_entry = 1;
639 			memcpy(mgm->gid, gid, 16);
640 		}
641 	} else {
642 		link = 1;
643 
644 		index = mlx4_bitmap_alloc(&priv->mcg_table.bitmap);
645 		if (index == -1) {
646 			mlx4_err(dev, "No AMGM entries left\n");
647 			err = -ENOMEM;
648 			goto out;
649 		}
650 		index += dev->caps.num_mgms;
651 
652 		memset(mgm, 0, sizeof *mgm);
653 		memcpy(mgm->gid, gid, 16);
654 	}
655 
656 	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
657 	if (members_count == MLX4_QP_PER_MGM) {
658 		mlx4_err(dev, "MGM at index %x is full.\n", index);
659 		err = -ENOMEM;
660 		goto out;
661 	}
662 
663 	for (i = 0; i < members_count; ++i)
664 		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
665 			mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn);
666 			err = 0;
667 			goto out;
668 		}
669 
670 	if (block_mcast_loopback)
671 		mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) |
672 						       (1U << MGM_BLCK_LB_BIT));
673 	else
674 		mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);
675 
676 	mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30);
677 
678 	err = mlx4_WRITE_ENTRY(dev, index, mailbox);
679 	if (err)
680 		goto out;
681 
682 	if (!link)
683 		goto out;
684 
685 	err = mlx4_READ_ENTRY(dev, prev, mailbox);
686 	if (err)
687 		goto out;
688 
689 	mgm->next_gid_index = cpu_to_be32(index << 6);
690 
691 	err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
692 	if (err)
693 		goto out;
694 
695 out:
696 	if (prot == MLX4_PROT_ETH) {
697 		/* manage the steering entry for promisc mode */
698 		if (new_entry)
699 			new_steering_entry(dev, 0, port, steer, index, qp->qpn);
700 		else
701 			existing_steering_entry(dev, 0, port, steer,
702 						index, qp->qpn);
703 	}
704 	if (err && link && index != -1) {
705 		if (index < dev->caps.num_mgms)
706 			mlx4_warn(dev, "Got AMGM index %d < %d",
707 				  index, dev->caps.num_mgms);
708 		else
709 			mlx4_bitmap_free(&priv->mcg_table.bitmap,
710 					 index - dev->caps.num_mgms);
711 	}
712 	mutex_unlock(&priv->mcg_table.mutex);
713 
714 	mlx4_free_cmd_mailbox(dev, mailbox);
715 	return err;
716 }
717 
718 int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
719 			  enum mlx4_protocol prot, enum mlx4_steer_type steer)
720 {
721 	struct mlx4_priv *priv = mlx4_priv(dev);
722 	struct mlx4_cmd_mailbox *mailbox;
723 	struct mlx4_mgm *mgm;
724 	u32 members_count;
725 	u16 hash;
726 	int prev, index;
727 	int i, loc;
728 	int err;
729 	u8 port = gid[5];
730 	bool removed_entry = false;
731 
732 	mailbox = mlx4_alloc_cmd_mailbox(dev);
733 	if (IS_ERR(mailbox))
734 		return PTR_ERR(mailbox);
735 	mgm = mailbox->buf;
736 
737 	mutex_lock(&priv->mcg_table.mutex);
738 
739 	err = find_entry(dev, port, gid, prot, steer,
740 			 mailbox, &hash, &prev, &index);
741 	if (err)
742 		goto out;
743 
744 	if (index == -1) {
745 		mlx4_err(dev, "MGID %pI6 not found\n", gid);
746 		err = -EINVAL;
747 		goto out;
748 	}
749 
750 	/* if this pq is also a promisc qp, it shouldn't be removed */
751 	if (prot == MLX4_PROT_ETH &&
752 	    check_duplicate_entry(dev, 0, port, steer, index, qp->qpn))
753 		goto out;
754 
755 	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
756 	for (loc = -1, i = 0; i < members_count; ++i)
757 		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
758 			loc = i;
759 
760 	if (loc == -1) {
761 		mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
762 		err = -EINVAL;
763 		goto out;
764 	}
765 
766 
767 	mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
768 	mgm->qp[loc]       = mgm->qp[i - 1];
769 	mgm->qp[i - 1]     = 0;
770 
771 	if (prot == MLX4_PROT_ETH)
772 		removed_entry = can_remove_steering_entry(dev, 0, port, steer, index, qp->qpn);
773 	if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) {
774 		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
775 		goto out;
776 	}
777 
778 	/* We are going to delete the entry, members count should be 0 */
779 	mgm->members_count = cpu_to_be32((u32) prot << 30);
780 
781 	if (prev == -1) {
782 		/* Remove entry from MGM */
783 		int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6;
784 		if (amgm_index) {
785 			err = mlx4_READ_ENTRY(dev, amgm_index, mailbox);
786 			if (err)
787 				goto out;
788 		} else
789 			memset(mgm->gid, 0, 16);
790 
791 		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
792 		if (err)
793 			goto out;
794 
795 		if (amgm_index) {
796 			if (amgm_index < dev->caps.num_mgms)
797 				mlx4_warn(dev, "MGM entry %d had AMGM index %d < %d",
798 					  index, amgm_index, dev->caps.num_mgms);
799 			else
800 				mlx4_bitmap_free(&priv->mcg_table.bitmap,
801 						 amgm_index - dev->caps.num_mgms);
802 		}
803 	} else {
804 		/* Remove entry from AMGM */
805 		int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6;
806 		err = mlx4_READ_ENTRY(dev, prev, mailbox);
807 		if (err)
808 			goto out;
809 
810 		mgm->next_gid_index = cpu_to_be32(cur_next_index << 6);
811 
812 		err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
813 		if (err)
814 			goto out;
815 
816 		if (index < dev->caps.num_mgms)
817 			mlx4_warn(dev, "entry %d had next AMGM index %d < %d",
818 				  prev, index, dev->caps.num_mgms);
819 		else
820 			mlx4_bitmap_free(&priv->mcg_table.bitmap,
821 					 index - dev->caps.num_mgms);
822 	}
823 
824 out:
825 	mutex_unlock(&priv->mcg_table.mutex);
826 
827 	mlx4_free_cmd_mailbox(dev, mailbox);
828 	return err;
829 }
830 
831 
832 int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
833 			  int block_mcast_loopback, enum mlx4_protocol prot)
834 {
835 	enum mlx4_steer_type steer;
836 
837 	steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER;
838 
839 	if (prot == MLX4_PROT_ETH &&
840 			!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
841 		return 0;
842 
843 	if (prot == MLX4_PROT_ETH)
844 		gid[7] |= (steer << 1);
845 
846 	return mlx4_qp_attach_common(dev, qp, gid,
847 				     block_mcast_loopback, prot,
848 				     steer);
849 }
850 EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
851 
852 int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
853 			  enum mlx4_protocol prot)
854 {
855 	enum mlx4_steer_type steer;
856 
857 	steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER;
858 
859 	if (prot == MLX4_PROT_ETH &&
860 			!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
861 		return 0;
862 
863 	if (prot == MLX4_PROT_ETH) {
864 		gid[7] |= (steer << 1);
865 	}
866 
867 	return mlx4_qp_detach_common(dev, qp, gid, prot, steer);
868 }
869 EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
870 
871 
872 int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
873 {
874 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
875 		return 0;
876 
877 
878 	return add_promisc_qp(dev, 0, port, MLX4_MC_STEER, qpn);
879 }
880 EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add);
881 
882 int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
883 {
884 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
885 		return 0;
886 
887 
888 	return remove_promisc_qp(dev, 0, port, MLX4_MC_STEER, qpn);
889 }
890 EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove);
891 
892 int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
893 {
894 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
895 		return 0;
896 
897 
898 	return add_promisc_qp(dev, 0, port, MLX4_UC_STEER, qpn);
899 }
900 EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add);
901 
902 int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
903 {
904 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
905 		return 0;
906 
907 	return remove_promisc_qp(dev, 0, port, MLX4_UC_STEER, qpn);
908 }
909 EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove);
910 
911 int mlx4_init_mcg_table(struct mlx4_dev *dev)
912 {
913 	struct mlx4_priv *priv = mlx4_priv(dev);
914 	int err;
915 
916 	err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms,
917 			       dev->caps.num_amgms - 1, 0, 0);
918 	if (err)
919 		return err;
920 
921 	mutex_init(&priv->mcg_table.mutex);
922 
923 	return 0;
924 }
925 
926 void mlx4_cleanup_mcg_table(struct mlx4_dev *dev)
927 {
928 	mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap);
929 }
930