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
42static const u8 zero_gid[16];	/* automatically initialized to 0 */
43
44int mlx4_get_mgm_entry_size(struct mlx4_dev *dev)
45{
46	return 1 << dev->oper_log_mgm_entry_size;
47}
48
49int mlx4_get_qp_per_mgm(struct mlx4_dev *dev)
50{
51	return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2);
52}
53
54static int mlx4_QP_FLOW_STEERING_ATTACH(struct mlx4_dev *dev,
55					struct mlx4_cmd_mailbox *mailbox,
56					u32 size,
57					u64 *reg_id)
58{
59	u64 imm;
60	int err = 0;
61
62	err = mlx4_cmd_imm(dev, mailbox->dma, &imm, size, 0,
63			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
64			   MLX4_CMD_NATIVE);
65	if (err)
66		return err;
67	*reg_id = imm;
68
69	return err;
70}
71
72static int mlx4_QP_FLOW_STEERING_DETACH(struct mlx4_dev *dev, u64 regid)
73{
74	int err = 0;
75
76	err = mlx4_cmd(dev, regid, 0, 0,
77		       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
78		       MLX4_CMD_NATIVE);
79
80	return err;
81}
82
83static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index,
84			   struct mlx4_cmd_mailbox *mailbox)
85{
86	return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG,
87			    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
88}
89
90static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index,
91			    struct mlx4_cmd_mailbox *mailbox)
92{
93	return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG,
94			MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
95}
96
97static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 port, u8 steer,
98			      struct mlx4_cmd_mailbox *mailbox)
99{
100	u32 in_mod;
101
102	in_mod = (u32) port << 16 | steer << 1;
103	return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1,
104			MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A,
105			MLX4_CMD_NATIVE);
106}
107
108static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
109			 u16 *hash, u8 op_mod)
110{
111	u64 imm;
112	int err;
113
114	err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod,
115			   MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A,
116			   MLX4_CMD_NATIVE);
117
118	if (!err)
119		*hash = imm;
120
121	return err;
122}
123
124static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port,
125					      enum mlx4_steer_type steer,
126					      u32 qpn)
127{
128	struct mlx4_steer *s_steer;
129	struct mlx4_promisc_qp *pqp;
130
131	if (port < 1 || port > dev->caps.num_ports)
132		return NULL;
133
134	s_steer = &mlx4_priv(dev)->steer[port - 1];
135
136	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
137		if (pqp->qpn == qpn)
138			return pqp;
139	}
140	/* not found */
141	return NULL;
142}
143
144/*
145 * Add new entry to steering data structure.
146 * All promisc QPs should be added as well
147 */
148static int new_steering_entry(struct mlx4_dev *dev, u8 port,
149			      enum mlx4_steer_type steer,
150			      unsigned int index, u32 qpn)
151{
152	struct mlx4_steer *s_steer;
153	struct mlx4_cmd_mailbox *mailbox;
154	struct mlx4_mgm *mgm;
155	u32 members_count;
156	struct mlx4_steer_index *new_entry;
157	struct mlx4_promisc_qp *pqp;
158	struct mlx4_promisc_qp *dqp = NULL;
159	u32 prot;
160	int err;
161
162	if (port < 1 || port > dev->caps.num_ports)
163		return -EINVAL;
164
165	s_steer = &mlx4_priv(dev)->steer[port - 1];
166	new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
167	if (!new_entry)
168		return -ENOMEM;
169
170	INIT_LIST_HEAD(&new_entry->duplicates);
171	new_entry->index = index;
172	list_add_tail(&new_entry->list, &s_steer->steer_entries[steer]);
173
174	/* If the given qpn is also a promisc qp,
175	 * it should be inserted to duplicates list
176	 */
177	pqp = get_promisc_qp(dev, port, steer, qpn);
178	if (pqp) {
179		dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
180		if (!dqp) {
181			err = -ENOMEM;
182			goto out_alloc;
183		}
184		dqp->qpn = qpn;
185		list_add_tail(&dqp->list, &new_entry->duplicates);
186	}
187
188	/* if no promisc qps for this vep, we are done */
189	if (list_empty(&s_steer->promisc_qps[steer]))
190		return 0;
191
192	/* now need to add all the promisc qps to the new
193	 * steering entry, as they should also receive the packets
194	 * destined to this address */
195	mailbox = mlx4_alloc_cmd_mailbox(dev);
196	if (IS_ERR(mailbox)) {
197		err = -ENOMEM;
198		goto out_alloc;
199	}
200	mgm = mailbox->buf;
201
202	err = mlx4_READ_ENTRY(dev, index, mailbox);
203	if (err)
204		goto out_mailbox;
205
206	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
207	prot = be32_to_cpu(mgm->members_count) >> 30;
208	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
209		/* don't add already existing qpn */
210		if (pqp->qpn == qpn)
211			continue;
212		if (members_count == dev->caps.num_qp_per_mgm) {
213			/* out of space */
214			err = -ENOMEM;
215			goto out_mailbox;
216		}
217
218		/* add the qpn */
219		mgm->qp[members_count++] = cpu_to_be32(pqp->qpn & MGM_QPN_MASK);
220	}
221	/* update the qps count and update the entry with all the promisc qps*/
222	mgm->members_count = cpu_to_be32(members_count | (prot << 30));
223	err = mlx4_WRITE_ENTRY(dev, index, mailbox);
224
225out_mailbox:
226	mlx4_free_cmd_mailbox(dev, mailbox);
227	if (!err)
228		return 0;
229out_alloc:
230	if (dqp) {
231		list_del(&dqp->list);
232		kfree(dqp);
233	}
234	list_del(&new_entry->list);
235	kfree(new_entry);
236	return err;
237}
238
239/* update the data structures with existing steering entry */
240static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
241				   enum mlx4_steer_type steer,
242				   unsigned int index, u32 qpn)
243{
244	struct mlx4_steer *s_steer;
245	struct mlx4_steer_index *tmp_entry, *entry = NULL;
246	struct mlx4_promisc_qp *pqp;
247	struct mlx4_promisc_qp *dqp;
248
249	if (port < 1 || port > dev->caps.num_ports)
250		return -EINVAL;
251
252	s_steer = &mlx4_priv(dev)->steer[port - 1];
253
254	pqp = get_promisc_qp(dev, port, steer, qpn);
255	if (!pqp)
256		return 0; /* nothing to do */
257
258	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
259		if (tmp_entry->index == index) {
260			entry = tmp_entry;
261			break;
262		}
263	}
264	if (unlikely(!entry)) {
265		mlx4_warn(dev, "Steering entry at index %x is not registered\n", index);
266		return -EINVAL;
267	}
268
269	/* the given qpn is listed as a promisc qpn
270	 * we need to add it as a duplicate to this entry
271	 * for future references */
272	list_for_each_entry(dqp, &entry->duplicates, list) {
273		if (qpn == dqp->qpn)
274			return 0; /* qp is already duplicated */
275	}
276
277	/* add the qp as a duplicate on this index */
278	dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
279	if (!dqp)
280		return -ENOMEM;
281	dqp->qpn = qpn;
282	list_add_tail(&dqp->list, &entry->duplicates);
283
284	return 0;
285}
286
287/* Check whether a qpn is a duplicate on steering entry
288 * If so, it should not be removed from mgm */
289static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
290				  enum mlx4_steer_type steer,
291				  unsigned int index, u32 qpn)
292{
293	struct mlx4_steer *s_steer;
294	struct mlx4_steer_index *tmp_entry, *entry = NULL;
295	struct mlx4_promisc_qp *dqp, *tmp_dqp;
296
297	if (port < 1 || port > dev->caps.num_ports)
298		return NULL;
299
300	s_steer = &mlx4_priv(dev)->steer[port - 1];
301
302	/* if qp is not promisc, it cannot be duplicated */
303	if (!get_promisc_qp(dev, port, steer, qpn))
304		return false;
305
306	/* The qp is promisc qp so it is a duplicate on this index
307	 * Find the index entry, and remove the duplicate */
308	list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) {
309		if (tmp_entry->index == index) {
310			entry = tmp_entry;
311			break;
312		}
313	}
314	if (unlikely(!entry)) {
315		mlx4_warn(dev, "Steering entry for index %x is not registered\n", index);
316		return false;
317	}
318	list_for_each_entry_safe(dqp, tmp_dqp, &entry->duplicates, list) {
319		if (dqp->qpn == qpn) {
320			list_del(&dqp->list);
321			kfree(dqp);
322		}
323	}
324	return true;
325}
326
327/* Returns true if all the QPs != tqpn contained in this entry
328 * are Promisc QPs. Returns false otherwise.
329 */
330static bool promisc_steering_entry(struct mlx4_dev *dev, u8 port,
331				   enum mlx4_steer_type steer,
332				   unsigned int index, u32 tqpn,
333				   u32 *members_count)
334{
335	struct mlx4_cmd_mailbox *mailbox;
336	struct mlx4_mgm *mgm;
337	u32 m_count;
338	bool ret = false;
339	int i;
340
341	if (port < 1 || port > dev->caps.num_ports)
342		return false;
343
344	mailbox = mlx4_alloc_cmd_mailbox(dev);
345	if (IS_ERR(mailbox))
346		return false;
347	mgm = mailbox->buf;
348
349	if (mlx4_READ_ENTRY(dev, index, mailbox))
350		goto out;
351	m_count = be32_to_cpu(mgm->members_count) & 0xffffff;
352	if (members_count)
353		*members_count = m_count;
354
355	for (i = 0;  i < m_count; i++) {
356		u32 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
357		if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
358			/* the qp is not promisc, the entry can't be removed */
359			goto out;
360		}
361	}
362	ret = true;
363out:
364	mlx4_free_cmd_mailbox(dev, mailbox);
365	return ret;
366}
367
368/* IF a steering entry contains only promisc QPs, it can be removed. */
369static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
370				      enum mlx4_steer_type steer,
371				      unsigned int index, u32 tqpn)
372{
373	struct mlx4_steer *s_steer;
374	struct mlx4_steer_index *entry = NULL, *tmp_entry;
375	u32 members_count;
376	bool ret = false;
377
378	if (port < 1 || port > dev->caps.num_ports)
379		return NULL;
380
381	s_steer = &mlx4_priv(dev)->steer[port - 1];
382
383	if (!promisc_steering_entry(dev, port, steer, index,
384				    tqpn, &members_count))
385		goto out;
386
387	/* All the qps currently registered for this entry are promiscuous,
388	  * Checking for duplicates */
389	ret = true;
390	list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) {
391		if (entry->index == index) {
392			if (list_empty(&entry->duplicates) ||
393			    members_count == 1) {
394				struct mlx4_promisc_qp *pqp, *tmp_pqp;
395				/* If there is only 1 entry in duplicates then
396				 * this is the QP we want to delete, going over
397				 * the list and deleting the entry.
398				 */
399				list_del(&entry->list);
400				list_for_each_entry_safe(pqp, tmp_pqp,
401							 &entry->duplicates,
402							 list) {
403					list_del(&pqp->list);
404					kfree(pqp);
405				}
406				kfree(entry);
407			} else {
408				/* This entry contains duplicates so it shouldn't be removed */
409				ret = false;
410				goto out;
411			}
412		}
413	}
414
415out:
416	return ret;
417}
418
419static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
420			  enum mlx4_steer_type steer, u32 qpn)
421{
422	struct mlx4_steer *s_steer;
423	struct mlx4_cmd_mailbox *mailbox;
424	struct mlx4_mgm *mgm;
425	struct mlx4_steer_index *entry;
426	struct mlx4_promisc_qp *pqp;
427	struct mlx4_promisc_qp *dqp;
428	u32 members_count;
429	u32 prot;
430	int i;
431	bool found;
432	int err;
433	struct mlx4_priv *priv = mlx4_priv(dev);
434
435	if (port < 1 || port > dev->caps.num_ports)
436		return -EINVAL;
437
438	s_steer = &mlx4_priv(dev)->steer[port - 1];
439
440	mutex_lock(&priv->mcg_table.mutex);
441
442	if (get_promisc_qp(dev, port, steer, qpn)) {
443		err = 0;  /* Noting to do, already exists */
444		goto out_mutex;
445	}
446
447	pqp = kmalloc(sizeof *pqp, GFP_KERNEL);
448	if (!pqp) {
449		err = -ENOMEM;
450		goto out_mutex;
451	}
452	pqp->qpn = qpn;
453
454	mailbox = mlx4_alloc_cmd_mailbox(dev);
455	if (IS_ERR(mailbox)) {
456		err = -ENOMEM;
457		goto out_alloc;
458	}
459	mgm = mailbox->buf;
460
461	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
462		/* The promisc QP needs to be added for each one of the steering
463		 * entries. If it already exists, needs to be added as
464		 * a duplicate for this entry.
465		 */
466		list_for_each_entry(entry,
467				    &s_steer->steer_entries[steer],
468				    list) {
469			err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
470			if (err)
471				goto out_mailbox;
472
473			members_count = be32_to_cpu(mgm->members_count) &
474					0xffffff;
475			prot = be32_to_cpu(mgm->members_count) >> 30;
476			found = false;
477			for (i = 0; i < members_count; i++) {
478				if ((be32_to_cpu(mgm->qp[i]) &
479				     MGM_QPN_MASK) == qpn) {
480					/* Entry already exists.
481					 * Add to duplicates.
482					 */
483					dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
484					if (!dqp) {
485						err = -ENOMEM;
486						goto out_mailbox;
487					}
488					dqp->qpn = qpn;
489					list_add_tail(&dqp->list,
490						      &entry->duplicates);
491					found = true;
492				}
493			}
494			if (!found) {
495				/* Need to add the qpn to mgm */
496				if (members_count ==
497				    dev->caps.num_qp_per_mgm) {
498					/* entry is full */
499					err = -ENOMEM;
500					goto out_mailbox;
501				}
502				mgm->qp[members_count++] =
503					cpu_to_be32(qpn & MGM_QPN_MASK);
504				mgm->members_count =
505					cpu_to_be32(members_count |
506						    (prot << 30));
507				err = mlx4_WRITE_ENTRY(dev, entry->index,
508						       mailbox);
509				if (err)
510					goto out_mailbox;
511			}
512		}
513	}
514
515	/* add the new qpn to list of promisc qps */
516	list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
517	/* now need to add all the promisc qps to default entry */
518	memset(mgm, 0, sizeof *mgm);
519	members_count = 0;
520	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) {
521		if (members_count == dev->caps.num_qp_per_mgm) {
522			/* entry is full */
523			err = -ENOMEM;
524			goto out_list;
525		}
526		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
527	}
528	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
529
530	err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
531	if (err)
532		goto out_list;
533
534	mlx4_free_cmd_mailbox(dev, mailbox);
535	mutex_unlock(&priv->mcg_table.mutex);
536	return 0;
537
538out_list:
539	list_del(&pqp->list);
540out_mailbox:
541	mlx4_free_cmd_mailbox(dev, mailbox);
542out_alloc:
543	kfree(pqp);
544out_mutex:
545	mutex_unlock(&priv->mcg_table.mutex);
546	return err;
547}
548
549static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
550			     enum mlx4_steer_type steer, u32 qpn)
551{
552	struct mlx4_priv *priv = mlx4_priv(dev);
553	struct mlx4_steer *s_steer;
554	struct mlx4_cmd_mailbox *mailbox;
555	struct mlx4_mgm *mgm;
556	struct mlx4_steer_index *entry, *tmp_entry;
557	struct mlx4_promisc_qp *pqp;
558	struct mlx4_promisc_qp *dqp;
559	u32 members_count;
560	bool found;
561	bool back_to_list = false;
562	int i;
563	int err;
564
565	if (port < 1 || port > dev->caps.num_ports)
566		return -EINVAL;
567
568	s_steer = &mlx4_priv(dev)->steer[port - 1];
569	mutex_lock(&priv->mcg_table.mutex);
570
571	pqp = get_promisc_qp(dev, port, steer, qpn);
572	if (unlikely(!pqp)) {
573		mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);
574		/* nothing to do */
575		err = 0;
576		goto out_mutex;
577	}
578
579	/*remove from list of promisc qps */
580	list_del(&pqp->list);
581
582	/* set the default entry not to include the removed one */
583	mailbox = mlx4_alloc_cmd_mailbox(dev);
584	if (IS_ERR(mailbox)) {
585		err = -ENOMEM;
586		back_to_list = true;
587		goto out_list;
588	}
589	mgm = mailbox->buf;
590	members_count = 0;
591	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
592		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
593	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
594
595	err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
596	if (err)
597		goto out_mailbox;
598
599	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
600		/* Remove the QP from all the steering entries */
601		list_for_each_entry_safe(entry, tmp_entry,
602					 &s_steer->steer_entries[steer],
603					 list) {
604			found = false;
605			list_for_each_entry(dqp, &entry->duplicates, list) {
606				if (dqp->qpn == qpn) {
607					found = true;
608					break;
609				}
610			}
611			if (found) {
612				/* A duplicate, no need to change the MGM,
613				 * only update the duplicates list
614				 */
615				list_del(&dqp->list);
616				kfree(dqp);
617			} else {
618				int loc = -1;
619
620				err = mlx4_READ_ENTRY(dev,
621						      entry->index,
622						      mailbox);
623					if (err)
624						goto out_mailbox;
625				members_count =
626					be32_to_cpu(mgm->members_count) &
627					0xffffff;
628				if (!members_count) {
629					mlx4_warn(dev, "QP %06x wasn't found in entry %x mcount=0. deleting entry...\n",
630						  qpn, entry->index);
631					list_del(&entry->list);
632					kfree(entry);
633					continue;
634				}
635
636				for (i = 0; i < members_count; ++i)
637					if ((be32_to_cpu(mgm->qp[i]) &
638					     MGM_QPN_MASK) == qpn) {
639						loc = i;
640						break;
641					}
642
643				if (loc < 0) {
644					mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
645						 qpn, entry->index);
646					err = -EINVAL;
647					goto out_mailbox;
648				}
649
650				/* Copy the last QP in this MGM
651				 * over removed QP
652				 */
653				mgm->qp[loc] = mgm->qp[members_count - 1];
654				mgm->qp[members_count - 1] = 0;
655				mgm->members_count =
656					cpu_to_be32(--members_count |
657						    (MLX4_PROT_ETH << 30));
658
659				err = mlx4_WRITE_ENTRY(dev,
660						       entry->index,
661						       mailbox);
662					if (err)
663						goto out_mailbox;
664			}
665		}
666	}
667
668out_mailbox:
669	mlx4_free_cmd_mailbox(dev, mailbox);
670out_list:
671	if (back_to_list)
672		list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
673	else
674		kfree(pqp);
675out_mutex:
676	mutex_unlock(&priv->mcg_table.mutex);
677	return err;
678}
679
680/*
681 * Caller must hold MCG table semaphore.  gid and mgm parameters must
682 * be properly aligned for command interface.
683 *
684 *  Returns 0 unless a firmware command error occurs.
685 *
686 * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1
687 * and *mgm holds MGM entry.
688 *
689 * if GID is found in AMGM, *index = index in AMGM, *prev = index of
690 * previous entry in hash chain and *mgm holds AMGM entry.
691 *
692 * If no AMGM exists for given gid, *index = -1, *prev = index of last
693 * entry in hash chain and *mgm holds end of hash chain.
694 */
695static int find_entry(struct mlx4_dev *dev, u8 port,
696		      u8 *gid, enum mlx4_protocol prot,
697		      struct mlx4_cmd_mailbox *mgm_mailbox,
698		      int *prev, int *index)
699{
700	struct mlx4_cmd_mailbox *mailbox;
701	struct mlx4_mgm *mgm = mgm_mailbox->buf;
702	u8 *mgid;
703	int err;
704	u16 hash;
705	u8 op_mod = (prot == MLX4_PROT_ETH) ?
706		!!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0;
707
708	mailbox = mlx4_alloc_cmd_mailbox(dev);
709	if (IS_ERR(mailbox))
710		return -ENOMEM;
711	mgid = mailbox->buf;
712
713	memcpy(mgid, gid, 16);
714
715	err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod);
716	mlx4_free_cmd_mailbox(dev, mailbox);
717	if (err)
718		return err;
719
720	if (0)
721		mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, hash);
722
723	*index = hash;
724	*prev  = -1;
725
726	do {
727		err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox);
728		if (err)
729			return err;
730
731		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
732			if (*index != hash) {
733				mlx4_err(dev, "Found zero MGID in AMGM\n");
734				err = -EINVAL;
735			}
736			return err;
737		}
738
739		if (!memcmp(mgm->gid, gid, 16) &&
740		    be32_to_cpu(mgm->members_count) >> 30 == prot)
741			return err;
742
743		*prev = *index;
744		*index = be32_to_cpu(mgm->next_gid_index) >> 6;
745	} while (*index);
746
747	*index = -1;
748	return err;
749}
750
751static const u8 __promisc_mode[] = {
752	[MLX4_FS_REGULAR]   = 0x0,
753	[MLX4_FS_ALL_DEFAULT] = 0x1,
754	[MLX4_FS_MC_DEFAULT] = 0x3,
755	[MLX4_FS_UC_SNIFFER] = 0x4,
756	[MLX4_FS_MC_SNIFFER] = 0x5,
757};
758
759int mlx4_map_sw_to_hw_steering_mode(struct mlx4_dev *dev,
760				    enum mlx4_net_trans_promisc_mode flow_type)
761{
762	if (flow_type >= MLX4_FS_MODE_NUM) {
763		mlx4_err(dev, "Invalid flow type. type = %d\n", flow_type);
764		return -EINVAL;
765	}
766	return __promisc_mode[flow_type];
767}
768EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_mode);
769
770static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,
771				  struct mlx4_net_trans_rule_hw_ctrl *hw)
772{
773	u8 flags = 0;
774
775	flags = ctrl->queue_mode == MLX4_NET_TRANS_Q_LIFO ? 1 : 0;
776	flags |= ctrl->exclusive ? (1 << 2) : 0;
777	flags |= ctrl->allow_loopback ? (1 << 3) : 0;
778
779	hw->flags = flags;
780	hw->type = __promisc_mode[ctrl->promisc_mode];
781	hw->prio = cpu_to_be16(ctrl->priority);
782	hw->port = ctrl->port;
783	hw->qpn = cpu_to_be32(ctrl->qpn);
784}
785
786const u16 __sw_id_hw[] = {
787	[MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001,
788	[MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005,
789	[MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003,
790	[MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002,
791	[MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004,
792	[MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006,
793	[MLX4_NET_TRANS_RULE_ID_VXLAN]	 = 0xE008
794};
795
796int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev,
797				  enum mlx4_net_trans_rule_id id)
798{
799	if (id >= MLX4_NET_TRANS_RULE_NUM) {
800		mlx4_err(dev, "Invalid network rule id. id = %d\n", id);
801		return -EINVAL;
802	}
803	return __sw_id_hw[id];
804}
805EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_id);
806
807static const int __rule_hw_sz[] = {
808	[MLX4_NET_TRANS_RULE_ID_ETH] =
809		sizeof(struct mlx4_net_trans_rule_hw_eth),
810	[MLX4_NET_TRANS_RULE_ID_IB] =
811		sizeof(struct mlx4_net_trans_rule_hw_ib),
812	[MLX4_NET_TRANS_RULE_ID_IPV6] = 0,
813	[MLX4_NET_TRANS_RULE_ID_IPV4] =
814		sizeof(struct mlx4_net_trans_rule_hw_ipv4),
815	[MLX4_NET_TRANS_RULE_ID_TCP] =
816		sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
817	[MLX4_NET_TRANS_RULE_ID_UDP] =
818		sizeof(struct mlx4_net_trans_rule_hw_tcp_udp),
819	[MLX4_NET_TRANS_RULE_ID_VXLAN] =
820		sizeof(struct mlx4_net_trans_rule_hw_vxlan)
821};
822
823int mlx4_hw_rule_sz(struct mlx4_dev *dev,
824	       enum mlx4_net_trans_rule_id id)
825{
826	if (id >= MLX4_NET_TRANS_RULE_NUM) {
827		mlx4_err(dev, "Invalid network rule id. id = %d\n", id);
828		return -EINVAL;
829	}
830
831	return __rule_hw_sz[id];
832}
833EXPORT_SYMBOL_GPL(mlx4_hw_rule_sz);
834
835static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,
836			    struct _rule_hw *rule_hw)
837{
838	if (mlx4_hw_rule_sz(dev, spec->id) < 0)
839		return -EINVAL;
840	memset(rule_hw, 0, mlx4_hw_rule_sz(dev, spec->id));
841	rule_hw->id = cpu_to_be16(__sw_id_hw[spec->id]);
842	rule_hw->size = mlx4_hw_rule_sz(dev, spec->id) >> 2;
843
844	switch (spec->id) {
845	case MLX4_NET_TRANS_RULE_ID_ETH:
846		memcpy(rule_hw->eth.dst_mac, spec->eth.dst_mac, ETH_ALEN);
847		memcpy(rule_hw->eth.dst_mac_msk, spec->eth.dst_mac_msk,
848		       ETH_ALEN);
849		memcpy(rule_hw->eth.src_mac, spec->eth.src_mac, ETH_ALEN);
850		memcpy(rule_hw->eth.src_mac_msk, spec->eth.src_mac_msk,
851		       ETH_ALEN);
852		if (spec->eth.ether_type_enable) {
853			rule_hw->eth.ether_type_enable = 1;
854			rule_hw->eth.ether_type = spec->eth.ether_type;
855		}
856		rule_hw->eth.vlan_tag = spec->eth.vlan_id;
857		rule_hw->eth.vlan_tag_msk = spec->eth.vlan_id_msk;
858		break;
859
860	case MLX4_NET_TRANS_RULE_ID_IB:
861		rule_hw->ib.l3_qpn = spec->ib.l3_qpn;
862		rule_hw->ib.qpn_mask = spec->ib.qpn_msk;
863		memcpy(&rule_hw->ib.dst_gid, &spec->ib.dst_gid, 16);
864		memcpy(&rule_hw->ib.dst_gid_msk, &spec->ib.dst_gid_msk, 16);
865		break;
866
867	case MLX4_NET_TRANS_RULE_ID_IPV6:
868		return -EOPNOTSUPP;
869
870	case MLX4_NET_TRANS_RULE_ID_IPV4:
871		rule_hw->ipv4.src_ip = spec->ipv4.src_ip;
872		rule_hw->ipv4.src_ip_msk = spec->ipv4.src_ip_msk;
873		rule_hw->ipv4.dst_ip = spec->ipv4.dst_ip;
874		rule_hw->ipv4.dst_ip_msk = spec->ipv4.dst_ip_msk;
875		break;
876
877	case MLX4_NET_TRANS_RULE_ID_TCP:
878	case MLX4_NET_TRANS_RULE_ID_UDP:
879		rule_hw->tcp_udp.dst_port = spec->tcp_udp.dst_port;
880		rule_hw->tcp_udp.dst_port_msk = spec->tcp_udp.dst_port_msk;
881		rule_hw->tcp_udp.src_port = spec->tcp_udp.src_port;
882		rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk;
883		break;
884
885	case MLX4_NET_TRANS_RULE_ID_VXLAN:
886		rule_hw->vxlan.vni =
887			cpu_to_be32(be32_to_cpu(spec->vxlan.vni) << 8);
888		rule_hw->vxlan.vni_mask =
889			cpu_to_be32(be32_to_cpu(spec->vxlan.vni_mask) << 8);
890		break;
891
892	default:
893		return -EINVAL;
894	}
895
896	return __rule_hw_sz[spec->id];
897}
898
899static void mlx4_err_rule(struct mlx4_dev *dev, char *str,
900			  struct mlx4_net_trans_rule *rule)
901{
902#define BUF_SIZE 256
903	struct mlx4_spec_list *cur;
904	char buf[BUF_SIZE];
905	int len = 0;
906
907	mlx4_err(dev, "%s", str);
908	len += snprintf(buf + len, BUF_SIZE - len,
909			"port = %d prio = 0x%x qp = 0x%x ",
910			rule->port, rule->priority, rule->qpn);
911
912	list_for_each_entry(cur, &rule->list, list) {
913		switch (cur->id) {
914		case MLX4_NET_TRANS_RULE_ID_ETH:
915			len += snprintf(buf + len, BUF_SIZE - len,
916					"dmac = %pM ", &cur->eth.dst_mac);
917			if (cur->eth.ether_type)
918				len += snprintf(buf + len, BUF_SIZE - len,
919						"ethertype = 0x%x ",
920						be16_to_cpu(cur->eth.ether_type));
921			if (cur->eth.vlan_id)
922				len += snprintf(buf + len, BUF_SIZE - len,
923						"vlan-id = %d ",
924						be16_to_cpu(cur->eth.vlan_id));
925			break;
926
927		case MLX4_NET_TRANS_RULE_ID_IPV4:
928			if (cur->ipv4.src_ip)
929				len += snprintf(buf + len, BUF_SIZE - len,
930						"src-ip = %pI4 ",
931						&cur->ipv4.src_ip);
932			if (cur->ipv4.dst_ip)
933				len += snprintf(buf + len, BUF_SIZE - len,
934						"dst-ip = %pI4 ",
935						&cur->ipv4.dst_ip);
936			break;
937
938		case MLX4_NET_TRANS_RULE_ID_TCP:
939		case MLX4_NET_TRANS_RULE_ID_UDP:
940			if (cur->tcp_udp.src_port)
941				len += snprintf(buf + len, BUF_SIZE - len,
942						"src-port = %d ",
943						be16_to_cpu(cur->tcp_udp.src_port));
944			if (cur->tcp_udp.dst_port)
945				len += snprintf(buf + len, BUF_SIZE - len,
946						"dst-port = %d ",
947						be16_to_cpu(cur->tcp_udp.dst_port));
948			break;
949
950		case MLX4_NET_TRANS_RULE_ID_IB:
951			len += snprintf(buf + len, BUF_SIZE - len,
952					"dst-gid = %pI6\n", cur->ib.dst_gid);
953			len += snprintf(buf + len, BUF_SIZE - len,
954					"dst-gid-mask = %pI6\n",
955					cur->ib.dst_gid_msk);
956			break;
957
958		case MLX4_NET_TRANS_RULE_ID_VXLAN:
959			len += snprintf(buf + len, BUF_SIZE - len,
960					"VNID = %d ", be32_to_cpu(cur->vxlan.vni));
961			break;
962		case MLX4_NET_TRANS_RULE_ID_IPV6:
963			break;
964
965		default:
966			break;
967		}
968	}
969	len += snprintf(buf + len, BUF_SIZE - len, "\n");
970	mlx4_err(dev, "%s", buf);
971
972	if (len >= BUF_SIZE)
973		mlx4_err(dev, "Network rule error message was truncated, print buffer is too small\n");
974}
975
976int mlx4_flow_attach(struct mlx4_dev *dev,
977		     struct mlx4_net_trans_rule *rule, u64 *reg_id)
978{
979	struct mlx4_cmd_mailbox *mailbox;
980	struct mlx4_spec_list *cur;
981	u32 size = 0;
982	int ret;
983
984	mailbox = mlx4_alloc_cmd_mailbox(dev);
985	if (IS_ERR(mailbox))
986		return PTR_ERR(mailbox);
987
988	trans_rule_ctrl_to_hw(rule, mailbox->buf);
989
990	size += sizeof(struct mlx4_net_trans_rule_hw_ctrl);
991
992	list_for_each_entry(cur, &rule->list, list) {
993		ret = parse_trans_rule(dev, cur, mailbox->buf + size);
994		if (ret < 0) {
995			mlx4_free_cmd_mailbox(dev, mailbox);
996			return ret;
997		}
998		size += ret;
999	}
1000
1001	ret = mlx4_QP_FLOW_STEERING_ATTACH(dev, mailbox, size >> 2, reg_id);
1002	if (ret == -ENOMEM) {
1003		mlx4_err_rule(dev,
1004			      "mcg table is full. Fail to register network rule\n",
1005			      rule);
1006	} else if (ret) {
1007		if (ret == -ENXIO) {
1008			if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED)
1009				mlx4_err_rule(dev,
1010					      "DMFS is not enabled, "
1011					      "failed to register network rule.\n",
1012					      rule);
1013			else
1014				mlx4_err_rule(dev,
1015					      "Rule exceeds the dmfs_high_rate_mode limitations, "
1016					      "failed to register network rule.\n",
1017					      rule);
1018
1019		} else {
1020			mlx4_err_rule(dev, "Fail to register network rule.\n", rule);
1021		}
1022	}
1023
1024	mlx4_free_cmd_mailbox(dev, mailbox);
1025
1026	return ret;
1027}
1028EXPORT_SYMBOL_GPL(mlx4_flow_attach);
1029
1030int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id)
1031{
1032	int err;
1033
1034	err = mlx4_QP_FLOW_STEERING_DETACH(dev, reg_id);
1035	if (err)
1036		mlx4_err(dev, "Fail to detach network rule. registration id = 0x%llx\n",
1037			 reg_id);
1038	return err;
1039}
1040EXPORT_SYMBOL_GPL(mlx4_flow_detach);
1041
1042int mlx4_tunnel_steer_add(struct mlx4_dev *dev, unsigned char *addr,
1043			  int port, int qpn, u16 prio, u64 *reg_id)
1044{
1045	int err;
1046	struct mlx4_spec_list spec_eth_outer = { {NULL} };
1047	struct mlx4_spec_list spec_vxlan     = { {NULL} };
1048	struct mlx4_spec_list spec_eth_inner = { {NULL} };
1049
1050	struct mlx4_net_trans_rule rule = {
1051		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
1052		.exclusive = 0,
1053		.allow_loopback = 1,
1054		.promisc_mode = MLX4_FS_REGULAR,
1055	};
1056
1057	__be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);
1058
1059	rule.port = port;
1060	rule.qpn = qpn;
1061	rule.priority = prio;
1062	INIT_LIST_HEAD(&rule.list);
1063
1064	spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH;
1065	memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN);
1066	memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN);
1067
1068	spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN;    /* any vxlan header */
1069	spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH;	 /* any inner eth header */
1070
1071	list_add_tail(&spec_eth_outer.list, &rule.list);
1072	list_add_tail(&spec_vxlan.list,     &rule.list);
1073	list_add_tail(&spec_eth_inner.list, &rule.list);
1074
1075	err = mlx4_flow_attach(dev, &rule, reg_id);
1076	return err;
1077}
1078EXPORT_SYMBOL(mlx4_tunnel_steer_add);
1079
1080int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
1081				      u32 max_range_qpn)
1082{
1083	int err;
1084	u64 in_param;
1085
1086	in_param = ((u64) min_range_qpn) << 32;
1087	in_param |= ((u64) max_range_qpn) & 0xFFFFFFFF;
1088
1089	err = mlx4_cmd(dev, in_param, 0, 0,
1090			MLX4_FLOW_STEERING_IB_UC_QP_RANGE,
1091			MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
1092
1093	return err;
1094}
1095EXPORT_SYMBOL_GPL(mlx4_FLOW_STEERING_IB_UC_QP_RANGE);
1096
1097int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
1098			  int block_mcast_loopback, enum mlx4_protocol prot,
1099			  enum mlx4_steer_type steer)
1100{
1101	struct mlx4_priv *priv = mlx4_priv(dev);
1102	struct mlx4_cmd_mailbox *mailbox;
1103	struct mlx4_mgm *mgm;
1104	u32 members_count;
1105	int index, prev;
1106	int link = 0;
1107	int i;
1108	int err;
1109	u8 port = gid[5];
1110	u8 new_entry = 0;
1111
1112	mailbox = mlx4_alloc_cmd_mailbox(dev);
1113	if (IS_ERR(mailbox))
1114		return PTR_ERR(mailbox);
1115	mgm = mailbox->buf;
1116
1117	mutex_lock(&priv->mcg_table.mutex);
1118	err = find_entry(dev, port, gid, prot,
1119			 mailbox, &prev, &index);
1120	if (err)
1121		goto out;
1122
1123	if (index != -1) {
1124		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
1125			new_entry = 1;
1126			memcpy(mgm->gid, gid, 16);
1127		}
1128	} else {
1129		link = 1;
1130
1131		index = mlx4_bitmap_alloc(&priv->mcg_table.bitmap);
1132		if (index == -1) {
1133			mlx4_err(dev, "No AMGM entries left\n");
1134			err = -ENOMEM;
1135			goto out;
1136		}
1137		index += dev->caps.num_mgms;
1138
1139		new_entry = 1;
1140		memset(mgm, 0, sizeof *mgm);
1141		memcpy(mgm->gid, gid, 16);
1142	}
1143
1144	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
1145	if (members_count == dev->caps.num_qp_per_mgm) {
1146		mlx4_err(dev, "MGM at index %x is full\n", index);
1147		err = -ENOMEM;
1148		goto out;
1149	}
1150
1151	for (i = 0; i < members_count; ++i)
1152		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
1153			mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn);
1154			err = 0;
1155			goto out;
1156		}
1157
1158	if (block_mcast_loopback)
1159		mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) |
1160						       (1U << MGM_BLCK_LB_BIT));
1161	else
1162		mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);
1163
1164	mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30);
1165
1166	err = mlx4_WRITE_ENTRY(dev, index, mailbox);
1167	if (err)
1168		goto out;
1169
1170	if (!link)
1171		goto out;
1172
1173	err = mlx4_READ_ENTRY(dev, prev, mailbox);
1174	if (err)
1175		goto out;
1176
1177	mgm->next_gid_index = cpu_to_be32(index << 6);
1178
1179	err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
1180	if (err)
1181		goto out;
1182
1183out:
1184	if (prot == MLX4_PROT_ETH) {
1185		/* manage the steering entry for promisc mode */
1186		if (new_entry)
1187			new_steering_entry(dev, port, steer, index, qp->qpn);
1188		else
1189			existing_steering_entry(dev, port, steer,
1190						index, qp->qpn);
1191	}
1192	if (err && link && index != -1) {
1193		if (index < dev->caps.num_mgms)
1194			mlx4_warn(dev, "Got AMGM index %d < %d\n",
1195				  index, dev->caps.num_mgms);
1196		else
1197			mlx4_bitmap_free(&priv->mcg_table.bitmap,
1198					 index - dev->caps.num_mgms, MLX4_USE_RR);
1199	}
1200	mutex_unlock(&priv->mcg_table.mutex);
1201
1202	mlx4_free_cmd_mailbox(dev, mailbox);
1203	return err;
1204}
1205
1206int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
1207			  enum mlx4_protocol prot, enum mlx4_steer_type steer)
1208{
1209	struct mlx4_priv *priv = mlx4_priv(dev);
1210	struct mlx4_cmd_mailbox *mailbox;
1211	struct mlx4_mgm *mgm;
1212	u32 members_count;
1213	int prev, index;
1214	int i, loc = -1;
1215	int err;
1216	u8 port = gid[5];
1217	bool removed_entry = false;
1218
1219	mailbox = mlx4_alloc_cmd_mailbox(dev);
1220	if (IS_ERR(mailbox))
1221		return PTR_ERR(mailbox);
1222	mgm = mailbox->buf;
1223
1224	mutex_lock(&priv->mcg_table.mutex);
1225
1226	err = find_entry(dev, port, gid, prot,
1227			 mailbox, &prev, &index);
1228	if (err)
1229		goto out;
1230
1231	if (index == -1) {
1232		mlx4_err(dev, "MGID %pI6 not found\n", gid);
1233		err = -EINVAL;
1234		goto out;
1235	}
1236
1237	/* If this QP is also a promisc QP, it shouldn't be removed only if
1238	 * at least one none promisc QP is also attached to this MCG
1239	 */
1240	if (prot == MLX4_PROT_ETH &&
1241	    check_duplicate_entry(dev, port, steer, index, qp->qpn) &&
1242	    !promisc_steering_entry(dev, port, steer, index, qp->qpn, NULL))
1243			goto out;
1244
1245	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
1246	for (i = 0; i < members_count; ++i)
1247		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
1248			loc = i;
1249			break;
1250		}
1251
1252	if (loc == -1) {
1253		mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
1254		err = -EINVAL;
1255		goto out;
1256	}
1257
1258	/* copy the last QP in this MGM over removed QP */
1259	mgm->qp[loc] = mgm->qp[members_count - 1];
1260	mgm->qp[members_count - 1] = 0;
1261	mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
1262
1263	if (prot == MLX4_PROT_ETH)
1264		removed_entry = can_remove_steering_entry(dev, port, steer,
1265								index, qp->qpn);
1266	if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) {
1267		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
1268		goto out;
1269	}
1270
1271	/* We are going to delete the entry, members count should be 0 */
1272	mgm->members_count = cpu_to_be32((u32) prot << 30);
1273
1274	if (prev == -1) {
1275		/* Remove entry from MGM */
1276		int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6;
1277		if (amgm_index) {
1278			err = mlx4_READ_ENTRY(dev, amgm_index, mailbox);
1279			if (err)
1280				goto out;
1281		} else
1282			memset(mgm->gid, 0, 16);
1283
1284		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
1285		if (err)
1286			goto out;
1287
1288		if (amgm_index) {
1289			if (amgm_index < dev->caps.num_mgms)
1290				mlx4_warn(dev, "MGM entry %d had AMGM index %d < %d\n",
1291					  index, amgm_index, dev->caps.num_mgms);
1292			else
1293				mlx4_bitmap_free(&priv->mcg_table.bitmap,
1294						 amgm_index - dev->caps.num_mgms, MLX4_USE_RR);
1295		}
1296	} else {
1297		/* Remove entry from AMGM */
1298		int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6;
1299		err = mlx4_READ_ENTRY(dev, prev, mailbox);
1300		if (err)
1301			goto out;
1302
1303		mgm->next_gid_index = cpu_to_be32(cur_next_index << 6);
1304
1305		err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
1306		if (err)
1307			goto out;
1308
1309		if (index < dev->caps.num_mgms)
1310			mlx4_warn(dev, "entry %d had next AMGM index %d < %d\n",
1311				  prev, index, dev->caps.num_mgms);
1312		else
1313			mlx4_bitmap_free(&priv->mcg_table.bitmap,
1314					 index - dev->caps.num_mgms, MLX4_USE_RR);
1315	}
1316
1317out:
1318	mutex_unlock(&priv->mcg_table.mutex);
1319
1320	mlx4_free_cmd_mailbox(dev, mailbox);
1321	if (err && dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR)
1322		/* In case device is under an error, return success as a closing command */
1323		err = 0;
1324	return err;
1325}
1326
1327static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp,
1328			  u8 gid[16], u8 attach, u8 block_loopback,
1329			  enum mlx4_protocol prot)
1330{
1331	struct mlx4_cmd_mailbox *mailbox;
1332	int err = 0;
1333	int qpn;
1334
1335	if (!mlx4_is_mfunc(dev))
1336		return -EBADF;
1337
1338	mailbox = mlx4_alloc_cmd_mailbox(dev);
1339	if (IS_ERR(mailbox))
1340		return PTR_ERR(mailbox);
1341
1342	memcpy(mailbox->buf, gid, 16);
1343	qpn = qp->qpn;
1344	qpn |= (prot << 28);
1345	if (attach && block_loopback)
1346		qpn |= (1 << 31);
1347
1348	err = mlx4_cmd(dev, mailbox->dma, qpn, attach,
1349		       MLX4_CMD_QP_ATTACH, MLX4_CMD_TIME_CLASS_A,
1350		       MLX4_CMD_WRAPPED);
1351
1352	mlx4_free_cmd_mailbox(dev, mailbox);
1353	if (err && !attach &&
1354	    dev->persist->state & MLX4_DEVICE_STATE_INTERNAL_ERROR)
1355		err = 0;
1356	return err;
1357}
1358
1359int mlx4_trans_to_dmfs_attach(struct mlx4_dev *dev, struct mlx4_qp *qp,
1360			      u8 gid[16], u8 port,
1361			      int block_mcast_loopback,
1362			      enum mlx4_protocol prot, u64 *reg_id)
1363{
1364		struct mlx4_spec_list spec = { {NULL} };
1365		__be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);
1366
1367		struct mlx4_net_trans_rule rule = {
1368			.queue_mode = MLX4_NET_TRANS_Q_FIFO,
1369			.exclusive = 0,
1370			.promisc_mode = MLX4_FS_REGULAR,
1371			.priority = MLX4_DOMAIN_NIC,
1372		};
1373
1374		rule.allow_loopback = !block_mcast_loopback;
1375		rule.port = port;
1376		rule.qpn = qp->qpn;
1377		INIT_LIST_HEAD(&rule.list);
1378
1379		switch (prot) {
1380		case MLX4_PROT_ETH:
1381			spec.id = MLX4_NET_TRANS_RULE_ID_ETH;
1382			memcpy(spec.eth.dst_mac, &gid[10], ETH_ALEN);
1383			memcpy(spec.eth.dst_mac_msk, &mac_mask, ETH_ALEN);
1384			break;
1385
1386		case MLX4_PROT_IB_IPV6:
1387			spec.id = MLX4_NET_TRANS_RULE_ID_IB;
1388			memcpy(spec.ib.dst_gid, gid, 16);
1389			memset(&spec.ib.dst_gid_msk, 0xff, 16);
1390			break;
1391		default:
1392			return -EINVAL;
1393		}
1394		list_add_tail(&spec.list, &rule.list);
1395
1396		return mlx4_flow_attach(dev, &rule, reg_id);
1397}
1398
1399int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
1400			  u8 port, int block_mcast_loopback,
1401			  enum mlx4_protocol prot, u64 *reg_id)
1402{
1403	switch (dev->caps.steering_mode) {
1404	case MLX4_STEERING_MODE_A0:
1405		if (prot == MLX4_PROT_ETH)
1406			return 0;
1407
1408	case MLX4_STEERING_MODE_B0:
1409		if (prot == MLX4_PROT_ETH)
1410			gid[7] |= (MLX4_MC_STEER << 1);
1411
1412		if (mlx4_is_mfunc(dev))
1413			return mlx4_QP_ATTACH(dev, qp, gid, 1,
1414					      block_mcast_loopback, prot);
1415		return mlx4_qp_attach_common(dev, qp, gid,
1416					     block_mcast_loopback, prot,
1417					     MLX4_MC_STEER);
1418
1419	case MLX4_STEERING_MODE_DEVICE_MANAGED:
1420		return mlx4_trans_to_dmfs_attach(dev, qp, gid, port,
1421						 block_mcast_loopback,
1422						 prot, reg_id);
1423	default:
1424		return -EINVAL;
1425	}
1426}
1427EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
1428
1429int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
1430			  enum mlx4_protocol prot, u64 reg_id)
1431{
1432	switch (dev->caps.steering_mode) {
1433	case MLX4_STEERING_MODE_A0:
1434		if (prot == MLX4_PROT_ETH)
1435			return 0;
1436
1437	case MLX4_STEERING_MODE_B0:
1438		if (prot == MLX4_PROT_ETH)
1439			gid[7] |= (MLX4_MC_STEER << 1);
1440
1441		if (mlx4_is_mfunc(dev))
1442			return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
1443
1444		return mlx4_qp_detach_common(dev, qp, gid, prot,
1445					     MLX4_MC_STEER);
1446
1447	case MLX4_STEERING_MODE_DEVICE_MANAGED:
1448		return mlx4_flow_detach(dev, reg_id);
1449
1450	default:
1451		return -EINVAL;
1452	}
1453}
1454EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
1455
1456int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
1457				u32 qpn, enum mlx4_net_trans_promisc_mode mode)
1458{
1459	struct mlx4_net_trans_rule rule;
1460	u64 *regid_p;
1461
1462	switch (mode) {
1463	case MLX4_FS_ALL_DEFAULT:
1464		regid_p = &dev->regid_promisc_array[port];
1465		break;
1466	case MLX4_FS_MC_DEFAULT:
1467		regid_p = &dev->regid_allmulti_array[port];
1468		break;
1469	default:
1470		return -1;
1471	}
1472
1473	if (*regid_p != 0)
1474		return -1;
1475
1476	rule.promisc_mode = mode;
1477	rule.port = port;
1478	rule.qpn = qpn;
1479	INIT_LIST_HEAD(&rule.list);
1480	mlx4_err(dev, "going promisc on %x\n", port);
1481
1482	return  mlx4_flow_attach(dev, &rule, regid_p);
1483}
1484EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_add);
1485
1486int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
1487				   enum mlx4_net_trans_promisc_mode mode)
1488{
1489	int ret;
1490	u64 *regid_p;
1491
1492	switch (mode) {
1493	case MLX4_FS_ALL_DEFAULT:
1494		regid_p = &dev->regid_promisc_array[port];
1495		break;
1496	case MLX4_FS_MC_DEFAULT:
1497		regid_p = &dev->regid_allmulti_array[port];
1498		break;
1499	default:
1500		return -1;
1501	}
1502
1503	if (*regid_p == 0)
1504		return -1;
1505
1506	ret =  mlx4_flow_detach(dev, *regid_p);
1507	if (ret == 0)
1508		*regid_p = 0;
1509
1510	return ret;
1511}
1512EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_remove);
1513
1514int mlx4_unicast_attach(struct mlx4_dev *dev,
1515			struct mlx4_qp *qp, u8 gid[16],
1516			int block_mcast_loopback, enum mlx4_protocol prot)
1517{
1518	if (prot == MLX4_PROT_ETH)
1519		gid[7] |= (MLX4_UC_STEER << 1);
1520
1521	if (mlx4_is_mfunc(dev))
1522		return mlx4_QP_ATTACH(dev, qp, gid, 1,
1523					block_mcast_loopback, prot);
1524
1525	return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback,
1526					prot, MLX4_UC_STEER);
1527}
1528EXPORT_SYMBOL_GPL(mlx4_unicast_attach);
1529
1530int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
1531			       u8 gid[16], enum mlx4_protocol prot)
1532{
1533	if (prot == MLX4_PROT_ETH)
1534		gid[7] |= (MLX4_UC_STEER << 1);
1535
1536	if (mlx4_is_mfunc(dev))
1537		return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
1538
1539	return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_UC_STEER);
1540}
1541EXPORT_SYMBOL_GPL(mlx4_unicast_detach);
1542
1543int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave,
1544			 struct mlx4_vhcr *vhcr,
1545			 struct mlx4_cmd_mailbox *inbox,
1546			 struct mlx4_cmd_mailbox *outbox,
1547			 struct mlx4_cmd_info *cmd)
1548{
1549	u32 qpn = (u32) vhcr->in_param & 0xffffffff;
1550	int port = mlx4_slave_convert_port(dev, slave, vhcr->in_param >> 62);
1551	enum mlx4_steer_type steer = vhcr->in_modifier;
1552
1553	if (port < 0)
1554		return -EINVAL;
1555
1556	/* Promiscuous unicast is not allowed in mfunc */
1557	if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)
1558		return 0;
1559
1560	if (vhcr->op_modifier)
1561		return add_promisc_qp(dev, port, steer, qpn);
1562	else
1563		return remove_promisc_qp(dev, port, steer, qpn);
1564}
1565
1566static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn,
1567			enum mlx4_steer_type steer, u8 add, u8 port)
1568{
1569	return mlx4_cmd(dev, (u64) qpn | (u64) port << 62, (u32) steer, add,
1570			MLX4_CMD_PROMISC, MLX4_CMD_TIME_CLASS_A,
1571			MLX4_CMD_WRAPPED);
1572}
1573
1574int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
1575{
1576	if (mlx4_is_mfunc(dev))
1577		return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port);
1578
1579	return add_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
1580}
1581EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add);
1582
1583int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
1584{
1585	if (mlx4_is_mfunc(dev))
1586		return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port);
1587
1588	return remove_promisc_qp(dev, port, MLX4_MC_STEER, qpn);
1589}
1590EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove);
1591
1592int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
1593{
1594	if (mlx4_is_mfunc(dev))
1595		return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port);
1596
1597	return add_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
1598}
1599EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add);
1600
1601int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
1602{
1603	if (mlx4_is_mfunc(dev))
1604		return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port);
1605
1606	return remove_promisc_qp(dev, port, MLX4_UC_STEER, qpn);
1607}
1608EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove);
1609
1610int mlx4_init_mcg_table(struct mlx4_dev *dev)
1611{
1612	struct mlx4_priv *priv = mlx4_priv(dev);
1613	int err;
1614
1615	/* No need for mcg_table when fw managed the mcg table*/
1616	if (dev->caps.steering_mode ==
1617	    MLX4_STEERING_MODE_DEVICE_MANAGED)
1618		return 0;
1619	err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms,
1620			       dev->caps.num_amgms - 1, 0, 0);
1621	if (err)
1622		return err;
1623
1624	mutex_init(&priv->mcg_table.mutex);
1625
1626	return 0;
1627}
1628
1629void mlx4_cleanup_mcg_table(struct mlx4_dev *dev)
1630{
1631	if (dev->caps.steering_mode !=
1632	    MLX4_STEERING_MODE_DEVICE_MANAGED)
1633		mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap);
1634}
1635