blob: 4fc020ebdeab807bf199b77a5d524781456aa893 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/******************************************************************************
2 *
3 * <:copyright-BRCM:2016:DUAL/GPL:standard
4 *
5 * Copyright (c) 2016 Broadcom
6 * All Rights Reserved
7 *
8 * Unless you and Broadcom execute a separate written software license
9 * agreement governing use of this software, this software is licensed
10 * to you under the terms of the GNU General Public License version 2
11 * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
12 * with the following added to such license:
13 *
14 * As a special exception, the copyright holders of this software give
15 * you permission to link this software with independent modules, and
16 * to copy and distribute the resulting executable under terms of your
17 * choice, provided that you also meet, for each linked independent
18 * module, the terms and conditions of the license of that module.
19 * An independent module is a module which is not derived from this
20 * software. The special exception does not apply to any modifications
21 * of the software.
22 *
23 * Not withstanding the above, under no circumstances may you combine
24 * this software in any way with any other Broadcom software provided
25 * under a license other than the GPL, without Broadcom's express prior
26 * written consent.
27 *
28 * :>
29 *
30 *****************************************************************************/
31
32/**
33 * @file bal_switch_group.c
34 * @brief BAL Switch util functions that handle group requests
35 * @addtogroup sw_util
36 */
37
38 /*@{*/
39#include <bal_common.h>
40#include <bcm_dev_log.h>
41#include <bal_msg.h>
42#include "bcmos_errno.h"
43#include "bal_switch_util.h" /* include bal_util.msg.h for bal_util_oper_group */
44#include "group_fsm.h" /* for struct group_inst */
45
46
47#include "bal_dpp_group.h"
48#include "bal_switch_acc_term.h"
49
50#ifdef TEST_SW_UTIL_LOOPBACK
51/* nothing to check in loop back mode */
52bcmos_errno sw_util_group_info_validate(void *p_msg)
53{
54 return BCM_ERR_OK;
55}
56
57#else
58/**
59 * @brief The group check function validate the group parameters from the core
60 *
61 * @param p_msg A pointer to the group object to validate
62 * @return error code
63 */
64bcmos_errno sw_util_group_info_validate(void *p_msg)
65{
66 bcmbal_group_cfg *p_grp = (bcmbal_group_cfg *)p_msg;
67 int i, num_of_pon;
68
69 if (p_grp == NULL)
70 {
71 BCM_LOG(ERROR, log_id_sw_util,
72 " No group specified during validation\n" );
73 return BCM_ERR_PARM;
74 }
75
76 /* if members field is set, make sure the PON interfaces are valid */
77 if (BCMBAL_CFG_PROP_IS_SET(p_grp, group, members))
78 {
79 num_of_pon = bal_bcm_pon_inf_map_size_get();
80 for(i=0; i<p_grp->data.members.len; i++)
81 {
82 bcmbal_group_member_info *p_member = &p_grp->data.members.val[i];
83
84 if (p_member->intf_id >= num_of_pon)
85 {
86 BCM_LOG(ERROR, log_id_sw_util,
87 " invalid group member with pon id = %d\n", p_member->intf_id );
88 return BCM_ERR_PARM;
89 }
90 }
91 }
92
93 /* member action is not supported yet */
94 return BCM_ERR_OK;
95}
96
97/**
98 * @brief The group remove function program switch to release resource that have
99 * been allocated during the group add operation.
100 *
101 * @param p_group_inst A pointer to the group instance being referenced
102 * @return error code
103 */
104static bcmos_errno bal_sw_util_group_remove(group_inst *p_group_inst)
105{
106 bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
107 bcmos_errno ret = BCM_ERR_OK;
108 int unit;
109 uint32_t dev_type;
110
111 BCM_LOG(INFO, log_id_sw_util,
112 " Got a group remove request - group_id=%d \n", p_group->key.group_id);
113
114 /* remove must have at least one member */
115 if(p_group->data.members.len == 0)
116 {
117 BCM_LOG(ERROR, log_id_sw_util, "group remove request must have at least one member\n");
118 return BCM_ERR_PARM;
119 }
120
121 unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
122 dev_type = bal_bcm_dev_type_get(unit);
123
124 /* call the group add function based on device type */
125 if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
126 {
127 ret = bal_sw_util_dpp_group_rem(unit, p_group);
128 }
129 else
130 {
131 BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group remove: 0x%x\n", dev_type );
132 ret = BCM_ERR_INTERNAL;
133 }
134
135 BCM_LOG(INFO, log_id_sw_util, " Return group remove request with %d on device 0x%x\n", ret, dev_type );
136
137 return ret;
138}
139/**
140 * @brief The group add function program switch to add a member interface to the group
141 *
142 * @param p_group_inst A pointer to the group instance being referenced
143 * @return error code
144 */
145static bcmos_errno bal_sw_util_group_add(group_inst *p_group_inst)
146{
147 bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
148 bcmos_errno ret = BCM_ERR_OK;
149 int unit;
150 uint32_t dev_type;
151
152 BCM_LOG(INFO, log_id_sw_util,
153 " Got a group add request - group_id=%d \n", p_group->key.group_id);
154
155 /* add must have at least one member */
156 if(p_group->data.members.len == 0)
157 {
158 BCM_LOG(ERROR, log_id_sw_util, "group add request must have at least one member\n");
159 return BCM_ERR_PARM;
160 }
161
162 unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
163 dev_type = bal_bcm_dev_type_get(unit);
164
165 /* call the group add function based on device type */
166 if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
167 {
168 ret = bal_sw_util_dpp_group_add(unit, p_group);
169 }
170 else
171 {
172 BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group add: 0x%x\n", dev_type );
173 ret = BCM_ERR_INTERNAL;
174 }
175
176 BCM_LOG(INFO, log_id_sw_util, " Return group add request with %d on device 0x%x\n", ret, dev_type );
177
178 return ret;
179}
180
181/**
182 * @brief The group set function program switch to replace member interfaces of a group
183 *
184 * @param p_group_inst A pointer to the group instance being referenced
185 * @return error code
186 */
187static bcmos_errno bal_sw_util_group_set(group_inst *p_group_inst)
188{
189 bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
190 bcmos_errno ret = BCM_ERR_OK;
191 int unit;
192 uint32_t dev_type;
193
194 BCM_LOG(INFO, log_id_sw_util,
195 " Got a group set request - group_id=%d \n", p_group->key.group_id);
196
197 if(p_group->data.members.len == 0)
198 {
199 unit = bal_bcm_dft_dev_get();
200 }
201 else
202 {
203 unit = bal_bcm_pon_inf_dev_get(p_group->data.members.val[0].intf_id);
204 }
205 dev_type = bal_bcm_dev_type_get(unit);
206
207 /* call the group set function based on device type */
208 if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
209 {
210 ret = bal_sw_util_dpp_group_set(unit, p_group);
211 }
212 else
213 {
214 BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group set: 0x%x\n", dev_type );
215 ret = BCM_ERR_INTERNAL;
216 }
217
218 BCM_LOG(INFO, log_id_sw_util, " Return group set request with %d on device 0x%x\n", ret, dev_type );
219
220 return ret;
221}
222/**
223 * @brief The group create function program switch to create an empty group
224 *
225 * @param p_group_inst A pointer to the group instance being referenced
226 * @return error code
227 */
228static bcmos_errno bal_sw_util_group_create(group_inst *p_group_inst)
229{
230 bcmbal_group_cfg *p_group = &p_group_inst->api_req_group_info;
231 bcmos_errno ret = BCM_ERR_OK;
232 int unit;
233 uint32_t dev_type;
234
235 BCM_LOG(INFO, log_id_sw_util,
236 " Got a group create request - group_id=%d \n", p_group->key.group_id);
237
238
239 /* For now, only one switch device for a system. If multiple devices support is required,
240 need to loop through all devices to create the group */
241 unit = bal_bcm_dft_dev_get();
242 dev_type = bal_bcm_dev_type_get(unit);
243
244 /* call the group create function based on device type */
245 if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
246 {
247 if( NULL == bal_sw_util_dpp_group_create(unit, p_group))
248 {
249 BCM_LOG(ERROR, log_id_sw_util, " switch group create failed\n");
250 ret = BCM_ERR_INTERNAL;
251 }
252 }
253 else
254 {
255 BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group create: 0x%x\n", dev_type );
256 ret = BCM_ERR_INTERNAL;
257 }
258
259 BCM_LOG(INFO, log_id_sw_util, " Return group create request with %d on device 0x%x\n", ret, dev_type );
260
261 return ret;
262}
263/**
264 * @brief The group destroy function program switch to release all resource used in a group
265 *
266 * @param p_group_inst A pointer to the group instance being referenced
267 * @return error code
268 */
269static bcmos_errno bal_sw_util_group_destroy(group_inst *p_group_inst)
270{
271 bcmbal_group_cfg *p_group = &p_group_inst->current_group_info;
272 bcmos_errno ret = BCM_ERR_OK;
273 int unit;
274 uint32_t dev_type;
275
276 BCM_LOG(INFO, log_id_sw_util,
277 " Got a group destroy request - group_id=%d \n", p_group->key.group_id);
278
279
280 /* For now, only one switch device for a system. If multiple devices support is required,
281 need to loop through all devices to create the group */
282 unit = bal_bcm_dft_dev_get();
283 dev_type = bal_bcm_dev_type_get(unit);
284
285 /* call the group destroy function based on device type */
286 if (dev_type == BCM_DEVICE_ARAD || dev_type == BCM_DEVICE_ARAD_PLUS || dev_type == BCM_DEVICE_QAX)
287 {
288 ret = bal_sw_util_dpp_group_destroy(unit, p_group);
289 }
290 else
291 {
292 BCM_LOG(ERROR, log_id_sw_util, " Unknown device type found on group destroy: 0x%x\n", dev_type );
293 ret = BCM_ERR_INTERNAL;
294 }
295
296 BCM_LOG(INFO, log_id_sw_util, " Return group destroy request with %d on device 0x%x\n", ret, dev_type );
297
298 return ret;
299}
300
301static uint32_t g_group_inited = 0;
302
303#endif
304/**
305 * @brief SWITCH module: group SET handler
306 *
307 * This routine is called by group_fsm in the BAL core upon
308 * SET request for group object.
309 *
310 * @param p_group_inst Pointer to group instance
311 * @param opt_type Operation type on group instance
312 *
313 * @return bcmos_errno
314 */
315bcmos_errno sw_util_group_set(group_inst *p_group_inst, bal_util_oper_group opt_type)
316{
317 bcmos_errno ret = BCM_ERR_OK;
318
319#ifndef TEST_SW_UTIL_LOOPBACK
320 bal_sw_util_vsi_list_init();
321 if (g_group_inited == 0)
322 {
323 /* initialized the internal group link list */
324 bal_sw_util_dpp_group_list_init();
325
326 g_group_inited = 1;
327 }
328
329 if(p_group_inst == NULL)
330 {
331 BCM_LOG(ERROR, log_id_sw_util, "group set request with NULL pointer to the group instance\n");
332 return BCM_ERR_PARM;
333 }
334
335 if (opt_type == BAL_UTIL_OPER_GROUP_CREATE)
336 {
337 ret = bal_sw_util_group_create(p_group_inst);
338 }
339 else if (opt_type == BAL_UTIL_OPER_GROUP_ADD)
340 {
341 ret = bal_sw_util_group_add(p_group_inst);
342 }
343 else if( BAL_UTIL_OPER_GROUP_REMOVE == opt_type )
344 {
345 ret = bal_sw_util_group_remove(p_group_inst);
346 }
347 else if( BAL_UTIL_OPER_GROUP_SET == opt_type )
348 {
349 ret = bal_sw_util_group_set(p_group_inst);
350 }
351 else if( BAL_UTIL_OPER_GROUP_DESTROY == opt_type )
352 {
353 ret = bal_sw_util_group_destroy(p_group_inst);
354 }
355 else
356 {
357 BCM_LOG(ERROR, log_id_sw_util, "Only CREATE/ADD/REMOVE/SET/DESTROY request is supported for GROUP object\n");
358 return BCM_ERR_NOT_SUPPORTED;
359 }
360#else
361 BCM_LOG(INFO, log_id_sw_util, "dummy group %s SUCCESS\n",
362 BCMBAL_UTIL_GROUP_OPER_STR_GET(opt_type));
363#endif
364
365 return ret;
366}
367
368/**
369 * @brief SWITCH module: group clean up function
370 *
371 * This routine is called from the bal_switch_util() when Core calls the finish function.
372 *
373 * @return bcmos_errno
374 */
375bcmos_errno sw_util_group_finish()
376{
377 bcmos_errno ret = BCM_ERR_OK;
378
379#ifndef TEST_SW_UTIL_LOOPBACK
380 if (g_group_inited)
381 {
382 /* release the internal group link list */
383 bal_sw_util_dpp_group_list_finish();
384
385 g_group_inited = 0;
386 }
387#endif
388 return ret;
389}
390/*@}*/
391
392