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