xref: /freebsd/sys/dev/irdma/irdma_uda.c (revision 01fbb869)
1cdcd52d4SBartosz Sobczak /*-
2cdcd52d4SBartosz Sobczak  * SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
3cdcd52d4SBartosz Sobczak  *
401fbb869SBartosz Sobczak  * Copyright (c) 2016 - 2023 Intel Corporation
5cdcd52d4SBartosz Sobczak  *
6cdcd52d4SBartosz Sobczak  * This software is available to you under a choice of one of two
7cdcd52d4SBartosz Sobczak  * licenses.  You may choose to be licensed under the terms of the GNU
8cdcd52d4SBartosz Sobczak  * General Public License (GPL) Version 2, available from the file
9cdcd52d4SBartosz Sobczak  * COPYING in the main directory of this source tree, or the
10cdcd52d4SBartosz Sobczak  * OpenFabrics.org BSD license below:
11cdcd52d4SBartosz Sobczak  *
12cdcd52d4SBartosz Sobczak  *   Redistribution and use in source and binary forms, with or
13cdcd52d4SBartosz Sobczak  *   without modification, are permitted provided that the following
14cdcd52d4SBartosz Sobczak  *   conditions are met:
15cdcd52d4SBartosz Sobczak  *
16cdcd52d4SBartosz Sobczak  *    - Redistributions of source code must retain the above
17cdcd52d4SBartosz Sobczak  *	copyright notice, this list of conditions and the following
18cdcd52d4SBartosz Sobczak  *	disclaimer.
19cdcd52d4SBartosz Sobczak  *
20cdcd52d4SBartosz Sobczak  *    - Redistributions in binary form must reproduce the above
21cdcd52d4SBartosz Sobczak  *	copyright notice, this list of conditions and the following
22cdcd52d4SBartosz Sobczak  *	disclaimer in the documentation and/or other materials
23cdcd52d4SBartosz Sobczak  *	provided with the distribution.
24cdcd52d4SBartosz Sobczak  *
25cdcd52d4SBartosz Sobczak  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26cdcd52d4SBartosz Sobczak  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27cdcd52d4SBartosz Sobczak  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28cdcd52d4SBartosz Sobczak  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29cdcd52d4SBartosz Sobczak  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30cdcd52d4SBartosz Sobczak  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31cdcd52d4SBartosz Sobczak  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32cdcd52d4SBartosz Sobczak  * SOFTWARE.
33cdcd52d4SBartosz Sobczak  */
34cdcd52d4SBartosz Sobczak 
35cdcd52d4SBartosz Sobczak #include "osdep.h"
36cdcd52d4SBartosz Sobczak #include "irdma_hmc.h"
37cdcd52d4SBartosz Sobczak #include "irdma_defs.h"
38cdcd52d4SBartosz Sobczak #include "irdma_type.h"
39cdcd52d4SBartosz Sobczak #include "irdma_protos.h"
40cdcd52d4SBartosz Sobczak #include "irdma_uda.h"
41cdcd52d4SBartosz Sobczak #include "irdma_uda_d.h"
42cdcd52d4SBartosz Sobczak 
43cdcd52d4SBartosz Sobczak /**
44cdcd52d4SBartosz Sobczak  * irdma_sc_access_ah() - Create, modify or delete AH
45cdcd52d4SBartosz Sobczak  * @cqp: struct for cqp hw
46cdcd52d4SBartosz Sobczak  * @info: ah information
47cdcd52d4SBartosz Sobczak  * @op: Operation
48cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
49cdcd52d4SBartosz Sobczak  */
50cdcd52d4SBartosz Sobczak int
irdma_sc_access_ah(struct irdma_sc_cqp * cqp,struct irdma_ah_info * info,u32 op,u64 scratch)51cdcd52d4SBartosz Sobczak irdma_sc_access_ah(struct irdma_sc_cqp *cqp, struct irdma_ah_info *info,
52cdcd52d4SBartosz Sobczak 		   u32 op, u64 scratch)
53cdcd52d4SBartosz Sobczak {
54cdcd52d4SBartosz Sobczak 	__le64 *wqe;
55cdcd52d4SBartosz Sobczak 	u64 qw1, qw2;
56cdcd52d4SBartosz Sobczak 
57cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
58cdcd52d4SBartosz Sobczak 	if (!wqe)
59cdcd52d4SBartosz Sobczak 		return -ENOSPC;
60cdcd52d4SBartosz Sobczak 
6101fbb869SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0,
6201fbb869SBartosz Sobczak 		      FIELD_PREP(IRDMAQPC_MACADDRESS, irdma_mac_to_u64(info->mac_addr)));
63cdcd52d4SBartosz Sobczak 
64777e472cSBartosz Sobczak 	qw1 = FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_PDINDEXLO, info->pd_idx) |
65777e472cSBartosz Sobczak 	    FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_TC, info->tc_tos) |
66777e472cSBartosz Sobczak 	    FIELD_PREP(IRDMA_UDAQPC_VLANTAG, info->vlan_tag);
67cdcd52d4SBartosz Sobczak 
68777e472cSBartosz Sobczak 	qw2 = FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ARPINDEX, info->dst_arpindex) |
69777e472cSBartosz Sobczak 	    FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_FLOWLABEL, info->flow_label) |
70777e472cSBartosz Sobczak 	    FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_HOPLIMIT, info->hop_ttl) |
71777e472cSBartosz Sobczak 	    FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_PDINDEXHI, info->pd_idx >> 16);
72cdcd52d4SBartosz Sobczak 
73cdcd52d4SBartosz Sobczak 	if (!info->ipv4_valid) {
74cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_40,
75777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->dest_ip_addr[0]) |
76777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->dest_ip_addr[1]));
77cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_32,
78777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->dest_ip_addr[2]) |
79777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[3]));
80cdcd52d4SBartosz Sobczak 
81cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_56,
82777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->src_ip_addr[0]) |
83777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->src_ip_addr[1]));
84cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
85777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->src_ip_addr[2]) |
86777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->src_ip_addr[3]));
87cdcd52d4SBartosz Sobczak 	} else {
88cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_32,
89777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[0]));
90cdcd52d4SBartosz Sobczak 
91cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
92777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->src_ip_addr[0]));
93cdcd52d4SBartosz Sobczak 	}
94cdcd52d4SBartosz Sobczak 
95cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8, qw1);
96cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16, qw2);
97cdcd52d4SBartosz Sobczak 
98cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* need write block before writing WQE header */
99cdcd52d4SBartosz Sobczak 
100cdcd52d4SBartosz Sobczak 	set_64bit_val(
101cdcd52d4SBartosz Sobczak 		      wqe, IRDMA_BYTE_24,
102777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_WQEVALID, cqp->polarity) |
103777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_OPCODE, op) |
104777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_DOLOOPBACKK, info->do_lpbk) |
105777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_IPV4VALID, info->ipv4_valid) |
106777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_AVIDX, info->ah_idx) |
107777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_INSERTVLANTAG, info->insert_vlan_tag));
108cdcd52d4SBartosz Sobczak 
109cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_AH WQE", wqe,
110cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
111cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
112cdcd52d4SBartosz Sobczak 
113cdcd52d4SBartosz Sobczak 	return 0;
114cdcd52d4SBartosz Sobczak }
115cdcd52d4SBartosz Sobczak 
116cdcd52d4SBartosz Sobczak /**
117cdcd52d4SBartosz Sobczak  * irdma_create_mg_ctx() - create a mcg context
118cdcd52d4SBartosz Sobczak  * @info: multicast group context info
119cdcd52d4SBartosz Sobczak  */
12035105900SBartosz Sobczak static void
irdma_create_mg_ctx(struct irdma_mcast_grp_info * info)121cdcd52d4SBartosz Sobczak irdma_create_mg_ctx(struct irdma_mcast_grp_info *info)
122cdcd52d4SBartosz Sobczak {
123cdcd52d4SBartosz Sobczak 	struct irdma_mcast_grp_ctx_entry_info *entry_info = NULL;
124cdcd52d4SBartosz Sobczak 	u8 idx = 0;		/* index in the array */
125cdcd52d4SBartosz Sobczak 	u8 ctx_idx = 0;		/* index in the MG context */
126cdcd52d4SBartosz Sobczak 
127cdcd52d4SBartosz Sobczak 	memset(info->dma_mem_mc.va, 0, IRDMA_MAX_MGS_PER_CTX * sizeof(u64));
128cdcd52d4SBartosz Sobczak 
129cdcd52d4SBartosz Sobczak 	for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) {
130cdcd52d4SBartosz Sobczak 		entry_info = &info->mg_ctx_info[idx];
131cdcd52d4SBartosz Sobczak 		if (entry_info->valid_entry) {
132cdcd52d4SBartosz Sobczak 			set_64bit_val((__le64 *) info->dma_mem_mc.va,
133cdcd52d4SBartosz Sobczak 				      ctx_idx * sizeof(u64),
134777e472cSBartosz Sobczak 				      FIELD_PREP(IRDMA_UDA_MGCTX_DESTPORT, entry_info->dest_port) |
135777e472cSBartosz Sobczak 				      FIELD_PREP(IRDMA_UDA_MGCTX_VALIDENT, entry_info->valid_entry) |
136777e472cSBartosz Sobczak 				      FIELD_PREP(IRDMA_UDA_MGCTX_QPID, entry_info->qp_id));
137cdcd52d4SBartosz Sobczak 			ctx_idx++;
138cdcd52d4SBartosz Sobczak 		}
139cdcd52d4SBartosz Sobczak 	}
140cdcd52d4SBartosz Sobczak }
141cdcd52d4SBartosz Sobczak 
142cdcd52d4SBartosz Sobczak /**
143cdcd52d4SBartosz Sobczak  * irdma_access_mcast_grp() - Access mcast group based on op
144cdcd52d4SBartosz Sobczak  * @cqp: Control QP
145cdcd52d4SBartosz Sobczak  * @info: multicast group context info
146cdcd52d4SBartosz Sobczak  * @op: operation to perform
147cdcd52d4SBartosz Sobczak  * @scratch: u64 saved to be used during cqp completion
148cdcd52d4SBartosz Sobczak  */
149cdcd52d4SBartosz Sobczak int
irdma_access_mcast_grp(struct irdma_sc_cqp * cqp,struct irdma_mcast_grp_info * info,u32 op,u64 scratch)150cdcd52d4SBartosz Sobczak irdma_access_mcast_grp(struct irdma_sc_cqp *cqp,
151cdcd52d4SBartosz Sobczak 		       struct irdma_mcast_grp_info *info, u32 op,
152cdcd52d4SBartosz Sobczak 		       u64 scratch)
153cdcd52d4SBartosz Sobczak {
154cdcd52d4SBartosz Sobczak 	__le64 *wqe;
155cdcd52d4SBartosz Sobczak 
156cdcd52d4SBartosz Sobczak 	if (info->mg_id >= IRDMA_UDA_MAX_FSI_MGS) {
157cdcd52d4SBartosz Sobczak 		irdma_debug(cqp->dev, IRDMA_DEBUG_WQE, "mg_id out of range\n");
158cdcd52d4SBartosz Sobczak 		return -EINVAL;
159cdcd52d4SBartosz Sobczak 	}
160cdcd52d4SBartosz Sobczak 
161cdcd52d4SBartosz Sobczak 	wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
162cdcd52d4SBartosz Sobczak 	if (!wqe) {
163cdcd52d4SBartosz Sobczak 		irdma_debug(cqp->dev, IRDMA_DEBUG_WQE, "ring full\n");
164cdcd52d4SBartosz Sobczak 		return -ENOSPC;
165cdcd52d4SBartosz Sobczak 	}
166cdcd52d4SBartosz Sobczak 
16735105900SBartosz Sobczak 	irdma_create_mg_ctx(info);
168cdcd52d4SBartosz Sobczak 
169cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_32, info->dma_mem_mc.pa);
170cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_16,
171777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MG_VLANID, info->vlan_id) |
172777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_QS_HANDLE, info->qs_handle));
17301fbb869SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_0, irdma_mac_to_u64(info->dest_mac_addr));
174cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_8,
175777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MG_HMC_FCN_ID, info->hmc_fcn_id));
176cdcd52d4SBartosz Sobczak 
177cdcd52d4SBartosz Sobczak 	if (!info->ipv4_valid) {
178cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_56,
179777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->dest_ip_addr[0]) |
180777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->dest_ip_addr[1]));
181cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
182777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->dest_ip_addr[2]) |
183777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[3]));
184cdcd52d4SBartosz Sobczak 	} else {
185cdcd52d4SBartosz Sobczak 		set_64bit_val(wqe, IRDMA_BYTE_48,
186777e472cSBartosz Sobczak 			      FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[0]));
187cdcd52d4SBartosz Sobczak 	}
188cdcd52d4SBartosz Sobczak 
189cdcd52d4SBartosz Sobczak 	irdma_wmb();		/* need write memory block before writing the WQE header. */
190cdcd52d4SBartosz Sobczak 
191cdcd52d4SBartosz Sobczak 	set_64bit_val(wqe, IRDMA_BYTE_24,
192777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MG_WQEVALID, cqp->polarity) |
193777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MG_OPCODE, op) |
194777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MG_MGIDX, info->mg_id) |
195777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MG_VLANVALID, info->vlan_valid) |
196777e472cSBartosz Sobczak 		      FIELD_PREP(IRDMA_UDA_CQPSQ_MG_IPV4VALID, info->ipv4_valid));
197cdcd52d4SBartosz Sobczak 
198cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_MCG WQE", wqe,
199cdcd52d4SBartosz Sobczak 			IRDMA_CQP_WQE_SIZE * 8);
200cdcd52d4SBartosz Sobczak 	irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MCG_HOST CTX WQE",
201cdcd52d4SBartosz Sobczak 			info->dma_mem_mc.va, IRDMA_MAX_MGS_PER_CTX * 8);
202cdcd52d4SBartosz Sobczak 	irdma_sc_cqp_post_sq(cqp);
203cdcd52d4SBartosz Sobczak 
204cdcd52d4SBartosz Sobczak 	return 0;
205cdcd52d4SBartosz Sobczak }
206cdcd52d4SBartosz Sobczak 
207cdcd52d4SBartosz Sobczak /**
208cdcd52d4SBartosz Sobczak  * irdma_compare_mgs - Compares two multicast group structures
209cdcd52d4SBartosz Sobczak  * @entry1: Multcast group info
210cdcd52d4SBartosz Sobczak  * @entry2: Multcast group info in context
211cdcd52d4SBartosz Sobczak  */
212cdcd52d4SBartosz Sobczak static bool
irdma_compare_mgs(struct irdma_mcast_grp_ctx_entry_info * entry1,struct irdma_mcast_grp_ctx_entry_info * entry2)213cdcd52d4SBartosz Sobczak irdma_compare_mgs(struct irdma_mcast_grp_ctx_entry_info *entry1,
214cdcd52d4SBartosz Sobczak 		  struct irdma_mcast_grp_ctx_entry_info *entry2)
215cdcd52d4SBartosz Sobczak {
216cdcd52d4SBartosz Sobczak 	if (entry1->dest_port == entry2->dest_port &&
217cdcd52d4SBartosz Sobczak 	    entry1->qp_id == entry2->qp_id)
218cdcd52d4SBartosz Sobczak 		return true;
219cdcd52d4SBartosz Sobczak 
220cdcd52d4SBartosz Sobczak 	return false;
221cdcd52d4SBartosz Sobczak }
222cdcd52d4SBartosz Sobczak 
223cdcd52d4SBartosz Sobczak /**
224cdcd52d4SBartosz Sobczak  * irdma_sc_add_mcast_grp - Allocates mcast group entry in ctx
225cdcd52d4SBartosz Sobczak  * @ctx: Multcast group context
226cdcd52d4SBartosz Sobczak  * @mg: Multcast group info
227cdcd52d4SBartosz Sobczak  */
228cdcd52d4SBartosz Sobczak int
irdma_sc_add_mcast_grp(struct irdma_mcast_grp_info * ctx,struct irdma_mcast_grp_ctx_entry_info * mg)229cdcd52d4SBartosz Sobczak irdma_sc_add_mcast_grp(struct irdma_mcast_grp_info *ctx,
230cdcd52d4SBartosz Sobczak 		       struct irdma_mcast_grp_ctx_entry_info *mg)
231cdcd52d4SBartosz Sobczak {
232cdcd52d4SBartosz Sobczak 	u32 idx;
233cdcd52d4SBartosz Sobczak 	bool free_entry_found = false;
234cdcd52d4SBartosz Sobczak 	u32 free_entry_idx = 0;
235cdcd52d4SBartosz Sobczak 
236cdcd52d4SBartosz Sobczak 	/* find either an identical or a free entry for a multicast group */
237cdcd52d4SBartosz Sobczak 	for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) {
238cdcd52d4SBartosz Sobczak 		if (ctx->mg_ctx_info[idx].valid_entry) {
239cdcd52d4SBartosz Sobczak 			if (irdma_compare_mgs(&ctx->mg_ctx_info[idx], mg)) {
240cdcd52d4SBartosz Sobczak 				ctx->mg_ctx_info[idx].use_cnt++;
241cdcd52d4SBartosz Sobczak 				return 0;
242cdcd52d4SBartosz Sobczak 			}
243cdcd52d4SBartosz Sobczak 			continue;
244cdcd52d4SBartosz Sobczak 		}
245cdcd52d4SBartosz Sobczak 		if (!free_entry_found) {
246cdcd52d4SBartosz Sobczak 			free_entry_found = true;
247cdcd52d4SBartosz Sobczak 			free_entry_idx = idx;
248cdcd52d4SBartosz Sobczak 		}
249cdcd52d4SBartosz Sobczak 	}
250cdcd52d4SBartosz Sobczak 
251cdcd52d4SBartosz Sobczak 	if (free_entry_found) {
252cdcd52d4SBartosz Sobczak 		ctx->mg_ctx_info[free_entry_idx] = *mg;
253cdcd52d4SBartosz Sobczak 		ctx->mg_ctx_info[free_entry_idx].valid_entry = true;
254cdcd52d4SBartosz Sobczak 		ctx->mg_ctx_info[free_entry_idx].use_cnt = 1;
255cdcd52d4SBartosz Sobczak 		ctx->no_of_mgs++;
256cdcd52d4SBartosz Sobczak 		return 0;
257cdcd52d4SBartosz Sobczak 	}
258cdcd52d4SBartosz Sobczak 
259cdcd52d4SBartosz Sobczak 	return -ENOMEM;
260cdcd52d4SBartosz Sobczak }
261cdcd52d4SBartosz Sobczak 
262cdcd52d4SBartosz Sobczak /**
263cdcd52d4SBartosz Sobczak  * irdma_sc_del_mcast_grp - Delete mcast group
264cdcd52d4SBartosz Sobczak  * @ctx: Multcast group context
265cdcd52d4SBartosz Sobczak  * @mg: Multcast group info
266cdcd52d4SBartosz Sobczak  *
267cdcd52d4SBartosz Sobczak  * Finds and removes a specific mulicast group from context, all
268cdcd52d4SBartosz Sobczak  * parameters must match to remove a multicast group.
269cdcd52d4SBartosz Sobczak  */
270cdcd52d4SBartosz Sobczak int
irdma_sc_del_mcast_grp(struct irdma_mcast_grp_info * ctx,struct irdma_mcast_grp_ctx_entry_info * mg)271cdcd52d4SBartosz Sobczak irdma_sc_del_mcast_grp(struct irdma_mcast_grp_info *ctx,
272cdcd52d4SBartosz Sobczak 		       struct irdma_mcast_grp_ctx_entry_info *mg)
273cdcd52d4SBartosz Sobczak {
274cdcd52d4SBartosz Sobczak 	u32 idx;
275cdcd52d4SBartosz Sobczak 
276cdcd52d4SBartosz Sobczak 	/* find an entry in multicast group context */
277cdcd52d4SBartosz Sobczak 	for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) {
278cdcd52d4SBartosz Sobczak 		if (!ctx->mg_ctx_info[idx].valid_entry)
279cdcd52d4SBartosz Sobczak 			continue;
280cdcd52d4SBartosz Sobczak 
281cdcd52d4SBartosz Sobczak 		if (irdma_compare_mgs(mg, &ctx->mg_ctx_info[idx])) {
282cdcd52d4SBartosz Sobczak 			ctx->mg_ctx_info[idx].use_cnt--;
283cdcd52d4SBartosz Sobczak 
284cdcd52d4SBartosz Sobczak 			if (!ctx->mg_ctx_info[idx].use_cnt) {
285cdcd52d4SBartosz Sobczak 				ctx->mg_ctx_info[idx].valid_entry = false;
286cdcd52d4SBartosz Sobczak 				ctx->no_of_mgs--;
287cdcd52d4SBartosz Sobczak 				/* Remove gap if element was not the last */
288cdcd52d4SBartosz Sobczak 				if (idx != ctx->no_of_mgs &&
289cdcd52d4SBartosz Sobczak 				    ctx->no_of_mgs > 0) {
290cdcd52d4SBartosz Sobczak 					irdma_memcpy(&ctx->mg_ctx_info[idx],
291cdcd52d4SBartosz Sobczak 						     &ctx->mg_ctx_info[ctx->no_of_mgs - 1],
292cdcd52d4SBartosz Sobczak 						     sizeof(ctx->mg_ctx_info[idx]));
293cdcd52d4SBartosz Sobczak 					ctx->mg_ctx_info[ctx->no_of_mgs - 1].valid_entry = false;
294cdcd52d4SBartosz Sobczak 				}
295cdcd52d4SBartosz Sobczak 			}
296cdcd52d4SBartosz Sobczak 
297cdcd52d4SBartosz Sobczak 			return 0;
298cdcd52d4SBartosz Sobczak 		}
299cdcd52d4SBartosz Sobczak 	}
300cdcd52d4SBartosz Sobczak 
301cdcd52d4SBartosz Sobczak 	return -EINVAL;
302cdcd52d4SBartosz Sobczak }
303