blob: b08efd6947525a6b2e8b780dd82da53a4f53d00c [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_mac_util_gpon.c
34 *
35 * @brief mac util interfaces definition used by Bal Core, for GPON
36 *
37 * This file expose the APIs to the core to configure the mac
38 * with regarding to the operation of access terminal, interface, subscriber terminal and flow.
39 *
40 * @addtogroup mac_util
41 */
42
43/*@{*/
44
45#include <bal_mac_util.h>
46#include <bal_mac_util_common_itu_pon.h>
47
48static bcmos_errno mac_util_indication_handle_for_gpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg);
49static bcmos_errno mac_util_indication_handle_for_gpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg);
50static bcmos_errno mac_util_indication_handle_for_gpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg);
51static bcmos_errno mac_util_indication_handle_for_gpon_gem_port (bcmolt_devid device_id, bcmolt_msg *p_msg);
52
53/** @brief array stores the list of GPON related auto indications from Maple to subscribe */
54static mac_util_ind_obj_and_handlers mac_util_gpon_ind_handlers[] =
55{
56 {BCMOLT_OBJ_ID_GPON_NI, "BCMOLT_OBJ_ID_GPON_NI", mac_util_indication_handle_for_gpon_ni},
57 {BCMOLT_OBJ_ID_GPON_ONU, "BCMOLT_OBJ_ID_GPON_ONU", mac_util_indication_handle_for_gpon_onu},
58 {BCMOLT_OBJ_ID_GPON_ALLOC, "BCMOLT_OBJ_ID_GPON_ALLOC", mac_util_indication_handle_for_gpon_alloc_id},
59 {BCMOLT_OBJ_ID_GPON_GEM_PORT, "BCMOLT_OBJ_ID_GPON_GEM_PORT", mac_util_indication_handle_for_gpon_gem_port}
60};
61
62
63/**
64 * @brief Map bal GPON transceiver type to bcm68620 transceiver type
65 */
66static bcmolt_trx_type mac_gpon_bal_trx_type2bcm68620_trx_type(bcmbal_trx_type bal_trx_type, bcmbal_intf_id intf_id)
67{
68 bcmolt_trx_type trx_type = BCMOLT_TRX_TYPE__NUM_OF;
69
70 switch (bal_trx_type)
71 {
72 case BCMBAL_TRX_TYPE_GPON_SPS_43_48:
73 trx_type = BCMOLT_TRX_TYPE_SPS_43_48_H_HP_CDE_SD_2013;
74 break;
75 case BCMBAL_TRX_TYPE_GPON_SPS_SOG_4321:
76 trx_type = BCMOLT_TRX_TYPE_SOG_4321_PSGB;
77 break;
78 case BCMBAL_TRX_TYPE_GPON_LTE_3680_M:
79 trx_type = BCMOLT_TRX_TYPE_LTE_3680_M;
80 break;
81 case BCMBAL_TRX_TYPE_GPON_SOURCE_PHOTONICS:
82 trx_type = BCMOLT_TRX_TYPE_SOURCE_PHOTONICS;
83 break;
84 case BCMBAL_TRX_TYPE_GPON_LTE_3680_P:
85 trx_type = BCMOLT_TRX_TYPE_LTE_3680_P_TYPE_C_PLUS;
86 break;
87 default:
88 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_id), "Invalid trx_type %d\n", bal_trx_type);
89 }
90 return trx_type;
91}
92
93
94
95
96/**
97 * @brief all the maple indication handlers for gpon
98 *
99 * @param device_id the maple device id generating the current indication
100 * @param p_msg pointer to the maple indication message
101 *
102 */
103bcmos_errno mac_util_handle_all_olt_ind_for_gpon (bcmolt_devid device_id, bcmolt_msg *p_msg)
104{
105 BCM_LOG(DEBUG, log_id_mac_util,
106 "mac_util_indication_cb received indication obj=%d/%s group=%d subgroup=%d\n",
107 p_msg->obj_type, mac_util_indication_get_obj_type_str(p_msg->obj_type, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers)),
108 p_msg->group, p_msg->subgroup);
109
110 return mac_util_handle_indication(device_id, p_msg, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers));
111}
112
113/**
114 * @brief Handler function for Maple auto indications for GPON NI
115 *
116 * @param device_id the maple device id generating the current indication
117 * @param p_msg pointer to the maple indication message
118 *
119 * @return bcmos_errno
120 */
121static bcmos_errno mac_util_indication_handle_for_gpon_ni (bcmolt_devid device_id, bcmolt_msg *p_msg)
122{
123 bcmos_errno rc = BCM_ERR_OK;
124 uint32_t logical_pon;
125
126 do
127 {
128
129 /* PON activation */
130 if (BCMOLT_GPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED == p_msg->subgroup)
131 {
132 bcmolt_gpon_ni_state_change_completed * p_ind = (bcmolt_gpon_ni_state_change_completed*)p_msg;
133
134 rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
135 if (BCM_ERR_OK != rc)
136 {
137 BCM_LOG(ERROR, log_id_mac_util,
138 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
139 break;
140 }
141
142 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon), "Pon if %d is %s.\n", logical_pon,
143 BCMOLT_PON_STATE_ACTIVE_WORKING == p_ind->data.new_state ? "up" : "down");
144
145 /* if we got something from MAC HW, then it has to be PON interface */
146 mac_util_report_if_event(logical_pon, BCMBAL_INTF_TYPE_PON, p_msg->err,
147 p_ind->data.result, p_ind->data.new_state);
148
149 }
150 else if(BCMOLT_GPON_NI_AUTO_CFG_ID_ONU_DISCOVERED == p_msg->subgroup)
151 {
152 bcmolt_gpon_ni_onu_discovered *p_ind =
153 (bcmolt_gpon_ni_onu_discovered *)p_msg;
154
155 rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
156 if (BCM_ERR_OK != rc)
157 {
158 BCM_LOG(ERROR, log_id_mac_util,
159 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
160 break;
161 }
162
163 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
164 "Pon if %d (ONUID:%d) found ONU serial number "
165 "%c%c%c%c%d%d%d%d%d%d%d%d\n",
166 logical_pon,
167 p_ind->data.onu_id,
168 p_ind->data.serial_number.vendor_id[0],
169 p_ind->data.serial_number.vendor_id[1],
170 p_ind->data.serial_number.vendor_id[2],
171 p_ind->data.serial_number.vendor_id[3],
172 p_ind->data.serial_number.vendor_specific[0]>>4 & 0x0f,
173 p_ind->data.serial_number.vendor_specific[0] & 0x0f,
174 p_ind->data.serial_number.vendor_specific[1]>>4 & 0x0f,
175 p_ind->data.serial_number.vendor_specific[1] & 0x0f,
176 p_ind->data.serial_number.vendor_specific[2]>>4 & 0x0f,
177 p_ind->data.serial_number.vendor_specific[2] & 0x0f,
178 p_ind->data.serial_number.vendor_specific[3]>>4 & 0x0f,
179 p_ind->data.serial_number.vendor_specific[3] & 0x0f
180 );
181
182 bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
183 mac_util_report_sub_term_event(logical_pon,
184 p_ind->data.onu_id,
185 &p_ind->data.serial_number,
186 BAL_UTIL_OPER_SUB_TERM_DISCOVERY,
187 p_msg->err, BCMOLT_RESULT_SUCCESS,
188 BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
189 }
190 else
191 {
192 /* just get the pon key by typecasting to a dummy structure */
193 bcmolt_gpon_ni_key *p_pon_key = &(((bcmolt_gpon_ni_state_change_completed*)p_msg)->key);
194
195 rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
196 if (BCM_ERR_OK != rc)
197 {
198 BCM_LOG(ERROR, log_id_mac_util,
199 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
200 break;
201 }
202
203 BCM_LOG(WARNING, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
204 "Unhandled message indication for obj Gpon_NI group %d "
205 "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
206 }
207
208 }
209 while(0);
210 return rc;
211}
212
213
214
215/**
216 * @brief Handler function for Maple auto indications for GPON ONU
217 *
218 * @param device_id the maple device id generating the current indication
219 * @param p_msg pointer to the maple indication message
220 *
221 * @return bcmos_errno
222 */
223static bcmos_errno mac_util_indication_handle_for_gpon_onu (bcmolt_devid device_id, bcmolt_msg *p_msg)
224{
225 bcmos_errno rc = BCM_ERR_OK;
226 uint32_t logical_pon;
227
228 /* just get the pon key by typecasting to a dummy structure */
229 bcmolt_gpon_onu_key *p_gpon_onu_key = &(((bcmolt_gpon_onu_onu_activation_completed*)p_msg)->key);
230
231 do
232 {
233 if (BCMOLT_GPON_ONU_AUTO_CFG_ID_ONU_ACTIVATION_COMPLETED == p_msg->subgroup)
234 {
235 bcmolt_gpon_onu_onu_activation_completed *p_ind = (bcmolt_gpon_onu_onu_activation_completed*) p_msg;
236
237 rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
238 if (BCM_ERR_OK != rc)
239 {
240 BCM_LOG(ERROR, log_id_mac_util,
241 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
242 break;
243 }
244
245 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_ind->key.pon_ni),
246 "sub_term %d (PON%d) activation indication (%s)\n",
247 p_ind->key.onu_id,
248 p_ind->key.pon_ni,
249 bcmos_strerror(p_msg->err));
250
251 mac_util_report_sub_term_event(logical_pon,
252 p_ind->key.onu_id,
253 (bcmolt_serial_number *)NULL,
254 BAL_UTIL_OPER_SUB_TERM_ADD,
255 p_msg->err, p_ind->data.status,
256 p_ind->data.fail_reason, BCMBAL_INVALID_TUNNEL_ID);
257
258 }
259 else if(BCMOLT_GPON_ONU_AUTO_CFG_ID_ONU_DEACTIVATION_COMPLETED == p_msg->subgroup)
260 {
261 bcmolt_gpon_onu_onu_deactivation_completed *p_ind = (bcmolt_gpon_onu_onu_deactivation_completed*) p_msg;
262
263 rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
264 if (BCM_ERR_OK != rc)
265 {
266 BCM_LOG(ERROR, log_id_mac_util,
267 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
268 break;
269 }
270
271 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
272 "sub_term %d (PON%d) deactivation indication (%s)\n",
273 p_ind->key.onu_id,
274 logical_pon,
275 bcmos_strerror(p_msg->err));
276 mac_util_report_sub_term_event(logical_pon,
277 p_ind->key.onu_id,
278 (bcmolt_serial_number *)NULL,
279 BAL_UTIL_OPER_SUB_TERM_REMOVE,
280 p_msg->err, p_ind->data.status,
281 MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
282 }
283 else
284 {
285 rc = bcm_topo_pon_get_physical2logical(device_id, p_gpon_onu_key->pon_ni, &logical_pon);
286 if (BCM_ERR_OK != rc)
287 {
288 BCM_LOG(ERROR, log_id_mac_util,
289 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_gpon_onu_key->pon_ni, bcmos_strerror(rc));
290 break;
291 }
292
293 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
294 "Unhandled message indication for obj GPON_ONU group %d "
295 "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
296 break;
297 }
298
299 rc = mac_util_update_flows_w_sub_term_update(logical_pon, p_gpon_onu_key->onu_id, maple_gpon_mac_check_gem_port_id, maple_gpon_mac_get_alloc_id_config);
300 if (BCM_ERR_OK != rc)
301 {
302 BCM_LOG(ERROR, log_id_mac_util,
303 "Failed to update related flows pon_id = %d onu_id = %d (%s)\n", logical_pon, p_gpon_onu_key->onu_id, bcmos_strerror(rc));
304 break;
305 }
306
307 }
308 while(0);
309 return rc;
310}
311
312
313/**
314 * @brief Handler function for Maple auto indications for GPON Alloc Id
315 *
316 * @param device_id the maple device id generating the current indication
317 * @param p_msg pointer to the maple indication message
318 *
319 * @return bcmos_errno
320 */
321static bcmos_errno mac_util_indication_handle_for_gpon_alloc_id (bcmolt_devid device_id, bcmolt_msg *p_msg)
322{
323 bcmos_errno rc = BCM_ERR_OK;
324 uint32_t logical_pon;
325 tm_sched_inst* p_tm_sched_inst = NULL;
326 do
327 {
328 if (BCMOLT_GPON_ALLOC_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
329 {
330 bcmolt_gpon_alloc_configuration_completed *p_ind = (bcmolt_gpon_alloc_configuration_completed*) p_msg;
331
332 rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
333 if (BCM_ERR_OK != rc)
334 {
335 BCM_LOG(ERROR, log_id_mac_util,
336 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
337 break;
338 }
339
340 /* Find tn_mode inst owned by that alloc_id and ni */
341 p_tm_sched_inst = tm_sched_find_agg_port_node(logical_pon, p_ind->key.alloc_id);
342 if (NULL == p_tm_sched_inst )
343 {
344 BCM_LOG(ERROR, log_id_mac_util,
345 "Failed to find tm sched owned by that agg port (intf %d id %d)\n", logical_pon,p_ind->key.alloc_id);
346 rc = BCM_ERR_NOENT;
347 break;
348 }
349 /*the tm owned by that alloc found, update it with the ind*/
350 mac_util_report_tm_sched_set_indication(p_tm_sched_inst->req_tm_sched_info.key ,p_msg->err, p_ind->data.status);
351 }
352 else
353 {
354 /* just get the pon key by typecasting to a dummy structure */
355 bcmolt_gpon_alloc_key *p_pon_key = &(((bcmolt_gpon_alloc_configuration_completed*)p_msg)->key);
356
357 rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
358 if (BCM_ERR_OK != rc)
359 {
360 BCM_LOG(ERROR, log_id_mac_util,
361 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
362 break;
363 }
364 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
365 "Unhandled message indication for obj GPON_ALLOC group %d "
366 "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
367 }
368 }while (0);
369 return rc;
370}
371
372
373/**
374 * @brief Handler function for Maple auto indications for GPON GEM Port
375 *
376 * @param device_id the maple device id generating the current indication
377 * @param p_msg pointer to the maple indication message
378 *
379 * @return bcmos_errno
380 */
381static bcmos_errno mac_util_indication_handle_for_gpon_gem_port (bcmolt_devid device_id, bcmolt_msg *p_msg)
382{
383 bcmos_errno rc = BCM_ERR_OK;
384 uint32_t logical_pon;
385 flow_list_entry *p_current_entry = NULL;
386 void *p_rsc_mgr_curr_entry = NULL;
387 void *p_rsc_mgr_next_entry = NULL;
388
389 do
390 {
391
392 if (BCMOLT_GPON_GEM_PORT_AUTO_CFG_ID_CONFIGURATION_COMPLETED == p_msg->subgroup)
393 {
394 bcmolt_gpon_gem_port_configuration_completed *p_ind =
395 (bcmolt_gpon_gem_port_configuration_completed *) p_msg;
396
397
398 rc = bcm_topo_pon_get_physical2logical(device_id, p_ind->key.pon_ni, &logical_pon);
399 if (BCM_ERR_OK != rc)
400 {
401 BCM_LOG(ERROR, log_id_mac_util,
402 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_ind->key.pon_ni, bcmos_strerror(rc));
403 break;
404 }
405
406 /* Find all entries in flows list matching the gem port id and pon ni */
407 /* use safe walk here because an entry can be removed from list during the walk */
408 /* get first */
409 p_current_entry = _mac_util_db_flow_get_next_w_gem (logical_pon, p_ind->key.gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
410 while (NULL != p_current_entry)
411 {
412 /** @note For now this assumes that there is only one op type (add or remove) ,
413 * that all the flows in an onu are waiting for. We can not have flows waiting on same
414 * gem for multiple op types, because Maple does not allow multiple configs with
415 * different op types at the same time.
416 */
417 /* update gem port complete configuration indication received */
418 p_current_entry->is_waiting_for_svc_port_active = BCMOS_FALSE;
419 /* check if should send flow configuration indication complete to bal core */
420 rc = check_send_flow_bal_ind_msg(p_current_entry, p_msg->err, p_ind->data.status);
421
422 /* any DB cleanup for error should be triggered by Core fsm
423 * (mac util should not cleanup on its own)
424 * */
425 if (BCM_ERR_OK != rc)
426 {
427 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
428 "Failed to send flow configured ind: Error %s, gem port id = %d, pon ni = %d\n",
429 bcmos_strerror(rc), p_ind->key.gem_port_id, logical_pon);
430 /* don't break, but continue to check if more flows use the same gem port id */
431 }
432
433 /* get next */
434 p_current_entry = _mac_util_db_flow_get_next_w_gem (logical_pon, p_ind->key.gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
435 }
436 }
437 else
438 {
439 /* just get the pon key by typecasting to a dummy structure */
440 bcmolt_gpon_gem_port_key *p_pon_key = &(((bcmolt_gpon_gem_port_configuration_completed*)p_msg)->key);
441
442 rc = bcm_topo_pon_get_physical2logical(device_id, p_pon_key->pon_ni, &logical_pon);
443 if (BCM_ERR_OK != rc)
444 {
445 BCM_LOG(ERROR, log_id_mac_util,
446 "Failed to get logical if from physical if (device_id %d physical %d ) (%s)\n", device_id, p_pon_key->pon_ni, bcmos_strerror(rc));
447 break;
448 }
449
450 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
451 "Unhandled message indication for obj GPON_GEM_PORT group %d "
452 "subgroup %d (Ignored)\n", p_msg->group, p_msg->subgroup);
453 }
454
455 }
456 while(0);
457 return rc;
458}
459
460/**
461 * @brief Maple auto indication register for specific GPON based indications
462 *
463 * @param p_rx_cfg handler config structure
464 * @param device_id specific device id (for multiple devices support)
465 *
466 * @return bcmos_errno
467 */
468bcmos_errno mac_util_register_for_gpon_auto_indications (struct bcmolt_rx_cfg *p_rx_cfg, bcmolt_devid device_id)
469{
470 return _mac_util_register_for_auto_indications (p_rx_cfg, mac_util_gpon_ind_handlers, BCM_SIZEOFARRAY(mac_util_gpon_ind_handlers), device_id);
471}
472
473/*****************************************************************************/
474/**
475 * @brief Map iwf_mode to bcmolt_iwf_mode
476 *
477 * @param bal_iwf_mode BAL iwfmode
478 * @return bcm68620 iwf mode
479 */
480static bcmolt_iwf_mode bal_iwf_mode2iwf_mode(bcmbal_iwf_mode bal_iwf_mode)
481{
482 bcmolt_iwf_mode iwf_mode = BCMOLT_IWF_MODE__NUM_OF;
483 switch (bal_iwf_mode)
484 {
485 case BCMBAL_IWF_MODE_DIRECT_MAPPING:
486 iwf_mode = BCMOLT_IWF_MODE_DIRECT_MAPPING_MODE;
487 break;
488 case BCMBAL_IWF_MODE_PER_FLOW:
489 iwf_mode = BCMOLT_IWF_MODE_PER_FLOW_MODE;
490 break;
491 default:
492 BCM_LOG(ERROR, log_id_mac_util, "Invalid iwf_mode %d\n", bal_iwf_mode);
493 }
494 return iwf_mode;
495}
496
497static bcmos_errno mac_util_access_terminal_set_for_gpon (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_system_mode system_mode, bcmolt_devid device_id)
498{
499 bcmolt_device_key key = {};
500 bcmolt_device_nni_speed nni_speed_cfg;
501 bcmolt_device_cfg dev_cfg;
502 bcmolt_iwf_mode iwf_mode;
503 uint32_t logical_pon;
504
505 if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&(p_acc_term->api_req_acc_term_obj_info), access_terminal, iwf_mode))
506 {
507 iwf_mode = bal_iwf_mode2iwf_mode(p_acc_term->api_req_acc_term_obj_info.data.iwf_mode);
508 }
509 else
510 {
511 iwf_mode = BCMOLT_IWF_MODE_DIRECT_MAPPING_MODE;
512 }
513
514 BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
515 {
516 mac_util_topo_pon_context *topo_context, *old_topo_context;
517
518 old_topo_context = bcm_topo_pon_get_context(logical_pon, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
519 if (old_topo_context)
520 bcmos_free(old_topo_context);
521
522 topo_context = bcmos_calloc(sizeof(*topo_context));
523 topo_context->iwf_mode = iwf_mode;
524 bcm_topo_pon_set_context(logical_pon, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL, topo_context);
525 }
526
527 BCMOLT_CFG_INIT(&dev_cfg, device, key);
528 BCMOLT_CFG_PROP_SET(&dev_cfg, device, system_mode, acc_term_connectivity.devices[device_id].system_mode);
529
530#ifdef QAX_SWITCH
531 /* until speed is configurable through topology settings hardcode it based on switch type */
532 BCM_LOG(INFO, log_id_mac_util, "nni speed is: 10G\n");
533 nni_speed_cfg.first_half = BCMOLT_NNI_SPEED_GBPS_10;
534 nni_speed_cfg.second_half = BCMOLT_NNI_SPEED_GBPS_10;
535 BCMOLT_CFG_PROP_SET(&dev_cfg, device, nni_speed, nni_speed_cfg);
536#endif
537
538 return bcmolt_cfg_set(device_id, &dev_cfg.hdr);
539}
540
541/**
542 * @brief access terminal set for gpon_16
543 */
544bcmos_errno mac_util_access_terminal_set_for_gpon_16 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
545{
546 bcmos_errno rc;
547 rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
548 if (rc != BCM_ERR_OK)
549 return rc;
550 rc = mac_util_access_terminal_set_for_gpon(p_acc_term, op_type, BCMOLT_SYSTEM_MODE_GPON__16_X, device_id);
551 if (rc != BCM_ERR_OK)
552 return rc;
553 return maple_access_terminal_connect_common(device_id);
554
555}
556
557/**
558 * @brief access terminal set for gpon_8
559 */
560bcmos_errno mac_util_access_terminal_set_for_gpon_8 (acc_term_inst *p_acc_term, bal_util_oper_acc_term op_type, bcmolt_devid device_id)
561{
562 bcmos_errno rc;
563
564 rc = maple_access_terminal_set_common(p_acc_term, op_type, device_id);
565 if (rc != BCM_ERR_OK)
566 return rc;
567 rc = mac_util_access_terminal_set_for_gpon(p_acc_term, op_type, BCMOLT_SYSTEM_MODE_GPON__8_X, device_id);
568 if (rc != BCM_ERR_OK)
569 return rc;
570 return maple_access_terminal_connect_common(device_id);
571}
572
573/**
574 * @brief post access terminal up configurations on Maple
575 */
576bcmos_errno mac_util_access_terminal_post_indication_set_for_gpon(bcmolt_devid device_id)
577{
578 bcmos_errno rc = BCM_ERR_OK;
579 bcmolt_devid dummy;
580 uint32_t physical_if_id;
581 uint32_t logical_pon = BCM_TOPO_PON_INVALID;
582 bcmolt_gpon_ni_key ni_key = {};
583 bcmolt_gpon_ni_cfg ni_cfg = {};
584 bcmolt_gpon_sn_acquisition sn_acquisition_cfg = {};
585 bcmolt_gpon_ni_auto_cfg gpon_ni_auto_cfg = {}; /* main auto cfg api struct */
586
587 /* configure one time settings for all the interfaces on this device */
588 BCM_TOPO_DEV_FOR_EACH_PON(device_id, logical_pon)
589 {
590 /* get physical interface from logical interface */
591 rc = bcm_topo_pon_get_logical2physical (logical_pon, &dummy, &physical_if_id);
592 if (BCM_ERR_OK != rc)
593 {
594 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
595 "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
596 break;
597 }
598
599 ni_key.pon_ni = physical_if_id;
600
601
602 /* Set the SN acquisition mode to enable */
603 BCMOLT_CFG_INIT(&ni_cfg, gpon_ni, ni_key);
604
605 sn_acquisition_cfg.control = BCMOLT_CONTROL_STATE_ENABLE;
606 sn_acquisition_cfg.interval = 5000;
607 sn_acquisition_cfg.onu_post_discovery_mode = BCMOLT_ONU_POST_DISCOVERY_MODE_NONE;
608
609 BCMOLT_CFG_PROP_SET(&ni_cfg, gpon_ni, sn_acquisition, sn_acquisition_cfg);
610
611 rc = bcmolt_cfg_set(device_id, &ni_cfg.hdr);
612 if (rc != BCM_ERR_OK)
613 {
614 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
615 "Failed to set sn acquisition configuration (%s), err_text=%s)\n",
616 bcmos_strerror(rc), ni_cfg.hdr.hdr.err_text);
617 break;
618 }
619
620
621 /* turn off the auto indication messages for gpon_ni.serial_number_acquisition_cycle_start */
622 BCMOLT_AUTO_CFG_INIT(&gpon_ni_auto_cfg, gpon_ni, ni_key);
623 BCMOLT_AUTO_CFG_PROP_SET(&gpon_ni_auto_cfg, gpon_ni, serial_number_acquisition_cycle_start, BCMOS_FALSE);
624 rc = bcmolt_auto_cfg_set(device_id, &gpon_ni_auto_cfg.hdr);
625 if (rc != BCM_ERR_OK)
626 {
627 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(logical_pon),
628 "bcmolt_auto_cfg_set for gpon_ni.serial_number_acquisition_cycle_start, Failed (%s), err_text=%s)\n",
629 bcmos_strerror(rc), gpon_ni_auto_cfg.hdr.hdr.err_text);
630
631 /* ignore any error, just continue anyway */
632 }
633 }
634
635 return rc;
636}
637
638/**
639 * @brief Command Set setup routine for interface up to mac application for GPON
640 *
641 * This routine is called by if_fsm in the BAL core to initialize the command
642 * set to up the interface of the mac application. The cmdset actually
643 * consists of two commands, one is to send the if up request message to the mac
644 * App and handle the relevant response, the other is to handle the indication message
645 * from the mac APP when the operation is completed.
646 *
647 * @param p_interface_inst Pointer to interface instance
648 * @param op_type Operation type on access terminal/interface instance
649 *
650 * @return bcmos_errno
651 *
652 */
653bcmos_errno mac_util_interface_set_for_gpon(acc_term_interface *p_interface_inst, bal_util_oper_if op_type)
654{
655 bcmos_errno rc = BCM_ERR_OK;
656
657 bcmbal_interface_cfg *p_interface_req = &(p_interface_inst->api_req_int_obj_info);
658 bcmbal_interface_key intf_key = p_interface_req->key;
659 mac_util_topo_pon_context *topo_context;
660
661 do
662 {
663 bcmolt_devid device_id;
664 uint32_t physical_if_id;
665 /* get physical interface from logical interface */
666 rc = bcm_topo_pon_get_logical2physical (intf_key.intf_id, &device_id, &physical_if_id);
667 if (BCM_ERR_OK != rc)
668 {
669 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
670 "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
671 break;
672 }
673
674
675 bcmolt_gpon_ni_set_pon_state oper_ni;
676 bcmolt_gpon_ni_key ni_key = { .pon_ni = physical_if_id };
677 bcmolt_gpon_trx_cfg cfg = {};
678 bcmolt_gpon_trx_key trx_key = { .pon_ni = physical_if_id };
679 bcmolt_trx_type trx_type;
680 bcmolt_gpon_iwf_key iwf_key = { .pon_ni = physical_if_id };
681 bcmolt_gpon_iwf_cfg iwf_cfg = {};
682 bcmolt_mac_table_configuration mac_table_configuration = {};
683
684 if (BAL_UTIL_OPER_IF_UP == op_type)
685 {
686
687 /* set the pon_ni transceiver configuration */
688 BCMOLT_CFG_INIT(&cfg, gpon_trx, trx_key);
689
690 /* If the user didn't specify a transceiver, then use the default */
691 if (BCMOS_TRUE != BCMBAL_CFG_PROP_IS_SET(p_interface_req, interface, transceiver_type))
692 {
693 /* The user didn't choose a transceiver type, so override it here
694 * with the default value for GPON
695 */
696 BCMBAL_CFG_PROP_SET(p_interface_req, interface, transceiver_type, BCMBAL_MAC_UTIL_TRX_TYPE_DEFAULT_GPON);
697 }
698
699 /* Set the (default or chosen) transceiver configuration into the MAC device */
700 trx_type = mac_gpon_bal_trx_type2bcm68620_trx_type(p_interface_req->data.transceiver_type, intf_key.intf_id);
701 BCMOLT_CFG_PROP_SET(&cfg, gpon_trx, transceiver_type, trx_type);
702
703 rc = bcmolt_cfg_set(device_id, &cfg.hdr);
704 if (rc != BCM_ERR_OK)
705 {
706 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
707 "Failed to set trx configuration (%s), err_text=%s\n", bcmos_strerror(rc), cfg.hdr.hdr.err_text);
708 break;
709 }
710
711
712 /* Configure pon_ni interworking and mac table configuration based on the system global interworking mode
713 *
714 * We only have to change the mode if the user has chosen per-flow, because direct mode is the default
715 * iwf mode in MAPLE
716 */
717 topo_context = bcm_topo_pon_get_context(intf_key.intf_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
718 if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
719 {
720 /* set the iwf configuration */
721 BCMOLT_CFG_INIT(&iwf_cfg, gpon_iwf, iwf_key);
722 BCMOLT_CFG_PROP_SET(&iwf_cfg, gpon_iwf, iwf_mode, BCMOLT_IWF_MODE_PER_FLOW_MODE);
723 /* set the mac table configuration */
724 mac_table_configuration.aging_time = 10000;
725 mac_table_configuration.automatic_mac_move = BCMOLT_CONTROL_STATE_DISABLE;
726 mac_table_configuration.automatic_static_mode = BCMOLT_CONTROL_STATE_DISABLE;
727 mac_table_configuration.default_flow_id = 0;
728 mac_table_configuration.learning_mode = BCMOLT_MAC_TABLE_LEARNING_MODE_NORMAL;
729 mac_table_configuration.miss_fallback = BCMOLT_MAC_TABLE_MISS_FALLBACK_DROP;
730 mac_table_configuration.automatic_mac_learning = BCMOLT_CONTROL_STATE_ENABLE;
731 mac_table_configuration.automatic_mac_aging = BCMOLT_CONTROL_STATE_ENABLE;
732 BCMOLT_CFG_PROP_SET(&iwf_cfg, gpon_iwf, mac_table_configuration, mac_table_configuration);
733
734 rc = bcmolt_cfg_set(device_id, &iwf_cfg.hdr);
735 if (rc != BCM_ERR_OK)
736 {
737 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
738 "Failed to set iwf / mac table configuration (%s), err_text=%s)\n",
739 bcmos_strerror(rc), iwf_cfg.hdr.hdr.err_text);
740 break;
741 }
742 }
743 }
744
745
746 /* invoke the pon_ni state change to the requested state */
747 BCMOLT_OPER_INIT(&oper_ni, gpon_ni, set_pon_state, ni_key);
748 BCMOLT_OPER_PROP_SET(&oper_ni, gpon_ni, set_pon_state, pon_state,
749 (BAL_UTIL_OPER_IF_UP == op_type) ?
750 BCMOLT_PON_OPERATION_ACTIVE_WORKING : BCMOLT_PON_OPERATION_INACTIVE);
751 rc = bcmolt_oper_submit(device_id, &oper_ni.hdr);
752 if (rc != BCM_ERR_OK)
753 {
754 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
755 "Failed to %s (submit) pon interface (%s), err_text=%s\n",
756 (BAL_UTIL_OPER_IF_UP == op_type) ? "activate" : "deactivate",
757 bcmos_strerror(rc), oper_ni.hdr.hdr.err_text);
758 }
759
760 } while (0);
761
762 if (BCM_ERR_OK == rc)
763 {
764 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(intf_key.intf_id),
765 "Submitted INTERFACE-%s operation for IF %d\n",
766 (BAL_UTIL_OPER_IF_UP == op_type) ? "UP" : "DOWN",
767 intf_key.intf_id);
768 }
769
770 return rc;
771}
772
773
774/**
775 * @brief maple_mac_ds_iwf_cfg
776 *
777 * This routine is used to configure the relevant downstream ingress and egress iwf at the device
778 *
779 * @param p_flow Pointer to the flow info
780 * @param per_flow_mode_vlan_id vlan id for GEM port mapping in per flow mode
781 * @param is_pbit_enabled Flag indicating whether or not to resolve pbits to GEM IDs
782 *
783 * @return bcmos_errno
784 */
785static bcmos_errno maple_mac_ds_iwf_cfg(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id, bcmos_bool is_pbit_enabled)
786{
787 bcmos_errno rc = BCM_ERR_OK;
788 bcmolt_gpon_iwf_ds_ingress_flow_key in_key = {};
789 bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg = {};
790 bcmolt_gpon_iwf_ds_egress_flow_key egr_key = {};
791 bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg = {};
792 bcmolt_devid device_id;
793 uint32_t physical_if_id;
794
795
796 do
797 {
798 /* get physical interface from logical interface */
799 rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
800 if (BCM_ERR_OK != rc)
801 {
802 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
803 "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
804 break;
805 }
806
807 /* configure the new ds ingress flow */
808 in_key.pon_ni = physical_if_id;
809 in_key.vlan_id = per_flow_mode_vlan_id;
810 BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);
811 if (BCMOS_TRUE == p_flow->data.resolve_mac)
812 {
813 /* mapping method */
814 BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
815 BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_MACPLUSVID);
816 }
817 else
818 {
819 /* mapping method */
820 BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_method,
821 BCMOLT_VLAN_TO_FLOW_MAPPING_METHOD_VID);
822 }
823
824 /* mapping tag */
825 BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, mapping_tag,
826 BCMOLT_MAPPING_TAG_METHOD_OUTER_VID);
827 BCMOLT_CFG_PROP_SET(&in_cfg, gpon_iwf_ds_ingress_flow, vlan_action, BCMOLT_DS_VLAN_ACTION_TRANSPARENT);
828
829 rc = bcmolt_cfg_set(device_id, &in_cfg.hdr);
830 if (BCM_ERR_OK != rc)
831 {
832 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
833 "Failed to configure ingress flow pon_ni = %d vlan_id = %d rc = %s (%d), err_text=%s\n",
834 in_key.pon_ni,
835 in_key.vlan_id,
836 bcmos_strerror(rc),
837 rc,
838 in_cfg.hdr.hdr.err_text);
839 break;
840 }
841
842
843 /* configure the new ds egress flow */
844 egr_key.pon_ni = physical_if_id;
845 egr_key.flow_id = p_flow->data.svc_port_id;
846
847 /* Configure DS egress handling: flow -> GEM */
848 BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);
849 BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, gem_port, p_flow->data.svc_port_id);
850 BCMOLT_CFG_PROP_SET(&egr_cfg, gpon_iwf_ds_egress_flow, pbit_control, is_pbit_enabled);
851
852 rc = bcmolt_cfg_set(device_id, &egr_cfg.hdr);
853 if (BCM_ERR_OK != rc)
854 {
855 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
856 "Failed to configure egress flow pon_ni = %d flow_id = %d rc = %s (%d), err_text=%s\n",
857 egr_key.pon_ni,
858 egr_key.flow_id,
859 bcmos_strerror(rc),
860 rc,
861 egr_cfg.hdr.hdr.err_text);
862 }
863
864 } while (0);
865
866 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
867 "going out of %s rc = %s (%d)\n",
868 __FUNCTION__,
869 bcmos_strerror(rc), rc);
870 return rc;
871}
872
873
874/**
875 * @brief maple_mac_ds_iwf_cfg_remove
876 *
877 * This routine is used to remove configuration from Maple of the relevant downstream ingress and egress iwf
878 *
879 * @param p_flow Pointer to the flow info
880 * @param per_flow_mode_vlan_id vlan id for per flow mode
881 *
882 * @return bcmos_errno
883 */
884static bcmos_errno maple_mac_ds_iwf_cfg_remove(bcmbal_flow_cfg *p_flow, uint16_t per_flow_mode_vlan_id)
885{
886 bcmos_errno rc = BCM_ERR_OK;
887 bcmolt_gpon_iwf_ds_ingress_flow_key in_key = {};
888 bcmolt_gpon_iwf_ds_ingress_flow_cfg in_cfg = {};
889 bcmolt_gpon_iwf_ds_egress_flow_key egr_key = {};
890 bcmolt_gpon_iwf_ds_egress_flow_cfg egr_cfg = {};
891 bcmolt_devid device_id;
892 uint32_t physical_if_id;
893
894 do
895 {
896 /* config clear ds ingress flow */
897 rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
898 if (BCM_ERR_OK != rc)
899 {
900 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
901 "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
902 break;
903 }
904
905 in_key.pon_ni = physical_if_id;
906 in_key.vlan_id = per_flow_mode_vlan_id;
907 BCMOLT_CFG_INIT(&in_cfg, gpon_iwf_ds_ingress_flow, in_key);
908
909 rc = bcmolt_cfg_clear(device_id, &in_cfg.hdr);
910 if (BCM_ERR_OK != rc)
911 {
912 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
913 "Failed to Clear ingress flow pon_ni = %d vlan_id = %d rc = %s (%d)\n",
914 in_key.pon_ni,
915 in_key.vlan_id,
916 bcmos_strerror(rc),
917 rc);
918 break;
919 }
920
921
922 /* config clear ds egress flow */
923 egr_key.pon_ni = physical_if_id;
924 egr_key.flow_id = p_flow->data.svc_port_id;
925
926 /* Configure DS egress handling: flow -> GEM */
927 BCMOLT_CFG_INIT(&egr_cfg, gpon_iwf_ds_egress_flow, egr_key);
928
929 rc = bcmolt_cfg_clear(device_id, &egr_cfg.hdr);
930 if (BCM_ERR_OK != rc)
931 {
932 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
933 "Failed to Clear egress flow pon_ni = %d flow_id = %d rc = %s (%d)\n",
934 egr_key.pon_ni,
935 egr_key.flow_id,
936 bcmos_strerror(rc),
937 rc);
938 }
939
940 } while (0);
941
942 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
943 "%s: config clear: rc = %s (%d)\n",
944 __FUNCTION__,
945 bcmos_strerror(rc), rc);
946
947 return rc;
948}
949
950
951/**
952 * @brief maple_mac_us_iwf_cfg
953 *
954 * This routine is used to configure the relevant upstream iwf at the device
955 *
956 * @param p_flow A pointer to a flow object
957 *
958 * @param pbit A pbit value being configured for the specified flow
959 *
960 * @return bcmos_errno
961 */
962static bcmos_errno maple_mac_us_iwf_cfg(bcmbal_flow_cfg *p_flow, uint8_t pbit)
963{
964 bcmos_errno rc = BCM_ERR_PARM;
965 bcmolt_gpon_iwf_us_flow_key us_key = {};
966 bcmolt_gpon_iwf_us_flow_cfg us_cfg = {};
967 bcmolt_devid device_id;
968 uint32_t physical_if_id;
969
970 /* get physical interface from logical interface */
971 rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
972 if (BCM_ERR_OK != rc)
973 {
974 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
975 "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
976 }
977 else
978 {
979 /* configure the related iwf us flow */
980 us_key.pon_ni = physical_if_id;
981 us_key.gem_port_id = p_flow->data.svc_port_id;
982 BCMOLT_CFG_INIT(&us_cfg, gpon_iwf_us_flow, us_key);
983 BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, flow_id, p_flow->data.svc_port_id);
984 if (BCMOS_TRUE == p_flow->data.resolve_mac)
985 {
986 BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, mac_learning, BCMOS_TRUE);
987 }
988 else
989 {
990 BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, mac_learning, BCMOS_FALSE);
991 }
992 BCMOLT_CFG_PROP_SET(&us_cfg, gpon_iwf_us_flow, vlan_action, BCMOLT_US_VLAN_ACTION_TRANSPARENT);
993
994 rc = bcmolt_cfg_set(device_id, &us_cfg.hdr);
995 }
996
997 if(BCM_ERR_OK != rc)
998 {
999 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
1000 "%s FAILED, rc = %s (%d), err_text = %s\n",
1001 __FUNCTION__,
1002 bcmos_strerror(rc), rc, us_cfg.hdr.hdr.err_text);
1003 }
1004 return rc;
1005}
1006
1007
1008/**
1009 * @brief maple_mac_us_iwf_cfg_remove
1010 *
1011 * This routine is used to remove configuration from Maple of the relevant upstream iwf
1012 *
1013 * @param p_flow A pointer to a flow object
1014 *
1015 * @return bcmos_errno
1016 */
1017static bcmos_errno maple_mac_us_iwf_cfg_remove(bcmbal_flow_cfg *p_flow)
1018{
1019 bcmos_errno rc = BCM_ERR_PARM;
1020 bcmolt_gpon_iwf_us_flow_key us_key = {};
1021 bcmolt_gpon_iwf_us_flow_cfg us_cfg = {};
1022 bcmolt_devid device_id;
1023 uint32_t physical_if_id;
1024
1025 /* configure the related iwf us flow */
1026 rc = bcm_topo_pon_get_logical2physical (p_flow->data.access_int_id, &device_id, &physical_if_id);
1027 if (BCM_ERR_OK != rc)
1028 {
1029 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
1030 "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
1031 return rc;
1032 }
1033
1034 us_key.pon_ni = physical_if_id;
1035 us_key.gem_port_id = p_flow->data.svc_port_id;
1036 BCMOLT_CFG_INIT(&us_cfg, gpon_iwf_us_flow, us_key);
1037
1038 rc = bcmolt_cfg_clear(device_id, &us_cfg.hdr);
1039 if(BCM_ERR_OK != rc)
1040 {
1041 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow->data.access_int_id),
1042 "%s FAILED, rc = %s (%d)\n",
1043 __FUNCTION__,
1044 bcmos_strerror(rc), rc);
1045 }
1046
1047 return rc;
1048}
1049
1050
1051/**
1052 * @brief mac_util_validate_subscriber_terminal_info_for_gpon
1053 *
1054 * This routine is used to validate all input attributes required for a sub term setting
1055 * received from core for GPON
1056 *
1057 * @param p_sub_term_req A pointer to a subscriber terminal object
1058 *
1059 * @return bcmos_errno
1060 */
1061bcmos_errno mac_util_validate_subscriber_terminal_info_for_gpon(const bcmbal_subscriber_terminal_cfg *p_sub_term_req)
1062{
1063 if(BCMBAL_STATE_UP == p_sub_term_req->data.admin_state)
1064 {
1065 if (!BCMBAL_CFG_PROP_IS_SET (p_sub_term_req, subscriber_terminal, serial_number))
1066 {
1067 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1068 "Serial number is a mandatory parameter for a gpon subscriber terminal, and it is not set\n");
1069 return BCM_ERR_MANDATORY_PARM_IS_MISSING;
1070 }
1071
1072 if (!BCMBAL_CFG_PROP_IS_SET(p_sub_term_req, subscriber_terminal, password))
1073 {
1074 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1075 "Password is a mandatory parameter for a gpon subscriber terminal, and it is not set\n");
1076 return BCM_ERR_MANDATORY_PARM_IS_MISSING;
1077 }
1078 }
1079
1080 return BCM_ERR_OK;
1081}
1082
1083
1084/**
1085 * @brief Command Set setup routine for subscriber terminal connect to mac application for GPON
1086 *
1087 * This routine is called by sub_term_fsm in the BAL core to initialize the command
1088 * set to connect the subscriber terminal of the mac application. The cmdset actually
1089 * consists of two commands, one is to send the sub_term request message to the mac
1090 * App and handle the relevant response, the other is to handle the indication message
1091 * from the mac APP when the operation is completed.
1092 *
1093 * @param p_sub_term_inst A pointer to a subscriber terminal instance
1094 * @param op_type Type of operation being performed on the subscriber terminal instance
1095 * @param is_post_discovery Used for ADD, indicates if this is a request after a ONU discovery
1096 *
1097 * @return bcmos_errno
1098 *
1099 * @note we configure Maple for ONU in 2 stages:
1100 * \li Stage 1: do cfg_set with the serial num, password, omci port, as part of first sub_term_set from Core
1101 * \li Stage 2: set the ONU state to ACTIVE using oper_submit, as part of second sub_term_set from Core (after
1102 * receiving a Discovery indication)
1103 */
1104bcmos_errno mac_util_subscriber_terminal_set_for_gpon(sub_term_inst *p_sub_term_inst, bal_util_oper_sub_term op_type, bcmos_bool is_post_discovery)
1105{
1106 bcmos_errno rc = BCM_ERR_OK;
1107
1108 bcmbal_subscriber_terminal_cfg *p_sub_term_req = &p_sub_term_inst->api_req_sub_term_info;
1109
1110 do
1111 {
1112 bcmolt_devid device_id;
1113 uint32_t physical_if_id;
1114 /* get physical interface from logical interface */
1115 rc = bcm_topo_pon_get_logical2physical (p_sub_term_req->key.intf_id, &device_id, &physical_if_id);
1116 if (BCM_ERR_OK != rc)
1117 {
1118 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1119 "Failed to get physical if from logical if (%s)\n", bcmos_strerror(rc));
1120 break;
1121 }
1122
1123 bcmolt_gpon_onu_cfg cfg = {};
1124 bcmolt_gpon_onu_cfg onu_cfg_get = {};
1125 bcmolt_gpon_onu_set_onu_state oper = {};
1126 bcmolt_gpon_onu_key key = {};
1127 bcmolt_onu_operation new_onu_state;
1128 bcmolt_gpon_onu_auto_cfg gpon_onu_auto_cfg = {}; /* main auto cfg api struct */
1129
1130 /* set the onu key - set it to the physical if id */
1131 key.pon_ni = physical_if_id;
1132 key.onu_id = p_sub_term_req->key.sub_term_id;
1133
1134 /* set the onu key */
1135 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
1136
1137 /* invoke onu state change operation to the new state */
1138 BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
1139
1140 if(BAL_UTIL_OPER_SUB_TERM_CLEAR == op_type)
1141 {
1142 /* Delete the configuration of the ONU */
1143 rc = bcmolt_cfg_clear(device_id, &cfg.hdr);
1144 if (BCM_ERR_OK != rc)
1145 {
1146 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1147 "Failed to clear onu configuration(%s)\n",
1148 bcmos_strerror(rc));
1149 }
1150
1151 /* No indication from Maple will result from the clear operation
1152 * so fake it here
1153 */
1154 mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
1155 p_sub_term_req->key.sub_term_id,
1156 (bcmolt_serial_number *)NULL,
1157 BAL_UTIL_OPER_SUB_TERM_CLEAR,
1158 rc, rc,
1159 MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
1160
1161 /* No further processing is required for the CLEAR operation */
1162 break;
1163
1164
1165 }
1166 else if(BAL_UTIL_OPER_SUB_TERM_ADD == op_type)
1167 {
1168 /* first do a get, to see if onu is in active state already */
1169 BCMOLT_CFG_INIT(&onu_cfg_get, gpon_onu, key);
1170 BCMOLT_CFG_PROP_GET(&onu_cfg_get, gpon_onu, onu_state);
1171 rc = bcmolt_cfg_get(device_id, &onu_cfg_get.hdr);
1172 if (rc != BCM_ERR_OK)
1173 {
1174 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1175 "Failed to get onu configuration(%s), err_text=%s, ... continue to configure\n",
1176 bcmos_strerror(rc), onu_cfg_get.hdr.hdr.err_text);
1177
1178 /* don't break, but continue with the set anyways */
1179 }
1180 else
1181 {
1182 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1183 "%s: ONU state = %d, [pon_ni=%d, onu_id=%d], BEFORE doing cfg_set on Maple\n",
1184 __FUNCTION__, onu_cfg_get.data.onu_state, onu_cfg_get.key.pon_ni, onu_cfg_get.key.onu_id);
1185 }
1186
1187
1188 if ((BCM_ERR_OK == rc) && (BCMOLT_ONU_STATE_ACTIVE == onu_cfg_get.data.onu_state))
1189 {
1190 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1191 "%s: ONU already in active state during ADD. Skipping further config\n",
1192 __FUNCTION__);
1193
1194 mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
1195 p_sub_term_req->key.sub_term_id,
1196 (bcmolt_serial_number *)NULL,
1197 BAL_UTIL_OPER_SUB_TERM_ADD,
1198 rc, rc,
1199 BCMOLT_ACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
1200 break;
1201 }
1202
1203
1204 /* set the sn & password only if it being configured for the first time */
1205 if (BCMOS_FALSE == is_post_discovery)
1206 {
1207 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, serial_number,
1208 *((bcmolt_serial_number *)&p_sub_term_req->data.serial_number));
1209
1210 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, password,
1211 *((bcmolt_arr_u8_10 *)&p_sub_term_req->data.password));
1212
1213 /* set the onu configuration */
1214 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, auto_password_learning, BCMOS_TRUE);
1215 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, us_fec, BCMOS_FALSE);
1216
1217 /* set the onu management channel port */
1218 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, omci_port_id, p_sub_term_req->data.svc_port_id);
1219
1220
1221 rc = bcmolt_cfg_set(device_id, &cfg.hdr);
1222 if (rc != BCM_ERR_OK)
1223 {
1224 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1225 "Failed to set onu configuration(%s), err_text=%s\n",
1226 bcmos_strerror(rc), cfg.hdr.hdr.err_text);
1227 break;
1228 }
1229
1230 /**
1231 * @note If this is first time set for ADD, then skip setting the ONU state for now.
1232 * Wait until ONU Discovery is received.
1233 */
1234 break;
1235 }
1236
1237
1238 /* turn off the auto indication messages for gpon_onu.rei */
1239 BCMOLT_AUTO_CFG_INIT(&gpon_onu_auto_cfg, gpon_onu, key);
1240 BCMOLT_AUTO_CFG_PROP_SET(&gpon_onu_auto_cfg, gpon_onu, rei, BCMOS_FALSE);
1241 rc = bcmolt_auto_cfg_set(device_id, &gpon_onu_auto_cfg.hdr);
1242 if (rc != BCM_ERR_OK)
1243 {
1244 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1245 "bcmolt_auto_cfg_set for gpon_onu.rei Failed (%s), err_text=%s)\n",
1246 bcmos_strerror(rc), gpon_onu_auto_cfg.hdr.hdr.err_text);
1247
1248 /* This is not fatal, so just continue anyway */
1249 }
1250
1251 /*
1252 * Set the new onu state for the ADD operation
1253 */
1254 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1255 "Setting ONU state to active\n");
1256
1257 new_onu_state = BCMOLT_ONU_OPERATION_ACTIVE;
1258 }
1259 else if (BAL_UTIL_OPER_SUB_TERM_REMOVE == op_type)
1260 {
1261 /* If the ONU is not present, then it will never respond to the deactivate command
1262 * with an indication, so just allow the FSM to continue as if it did.
1263 */
1264 if(BCMBAL_STATUS_NOT_PRESENT != p_sub_term_inst->current_sub_term_info.data.oper_status)
1265 {
1266 /*
1267 * Set the new onu state for the REMOVE operation
1268 */
1269 BCM_LOG(DEBUG, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1270 "Setting ONU state to IN-active\n");
1271
1272 new_onu_state = BCMOLT_ONU_OPERATION_INACTIVE;
1273 }
1274 }
1275 else /* This should never happen */
1276 {
1277 BCM_LOG(ERROR, log_id_mac_util, "Bad request from core\n");
1278 rc = BCM_ERR_INTERNAL;
1279 break;
1280 }
1281
1282 /* Do oper_submit to set the ONU state */
1283 BCMOLT_OPER_PROP_SET(&oper, gpon_onu, set_onu_state, onu_state, new_onu_state);
1284 rc = bcmolt_oper_submit(device_id, &oper.hdr);
1285 if (BCM_ERR_OK != rc)
1286 {
1287 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1288 "bcmolt_oper_submit Failed for onu state Failed (%s), err_text=%s\n",
1289 bcmos_strerror(rc), &(oper.hdr.hdr.err_text[0]));
1290 }
1291
1292
1293 /* If the ONU is not present, then it will never respond to the deactivate command
1294 * with an indication, so just allow the FSM to continue as if it did.
1295 */
1296 if((BCMOLT_ONU_OPERATION_INACTIVE == new_onu_state) &&
1297 (BCMBAL_STATUS_NOT_PRESENT == p_sub_term_inst->current_sub_term_info.data.oper_status))
1298 {
1299 mac_util_report_sub_term_event(p_sub_term_req->key.intf_id,
1300 p_sub_term_req->key.sub_term_id,
1301 (bcmolt_serial_number *)NULL,
1302 BAL_UTIL_OPER_SUB_TERM_REMOVE,
1303 rc, rc,
1304 MAC_UTIL_DEACTIVATION_FAIL_REASON_NONE, BCMBAL_INVALID_TUNNEL_ID);
1305 }
1306
1307 } while (0);
1308
1309
1310
1311 if (rc == BCM_ERR_STATE)
1312 {
1313 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1314 "%s failed to set state, possibly because interface is not configured yet, pon fiber disconnect, or onu disconnect: rc = %s (%d)\n",
1315 __FUNCTION__,
1316 bcmos_strerror(rc), rc);
1317 }
1318 else if (BCM_ERR_OK != rc)
1319 {
1320 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_sub_term_req->key.intf_id),
1321 "%s Failed: rc = %s (%d)\n",
1322 __FUNCTION__,
1323 bcmos_strerror(rc), rc);
1324 }
1325
1326 return rc;
1327}
1328
1329
1330/**
1331 * @brief validate_flow_info for gpon
1332 *
1333 * This routine is used to validate all input attributes required for a flow
1334 * setting received from core for GPON
1335 *
1336 * @param p_flow_req A pointer to a flow object
1337 *
1338 * @return bcmos_errno
1339 */
1340bcmos_errno mac_util_validate_flow_info_for_gpon (const bcmbal_flow_cfg *p_flow_req)
1341{
1342 bcmos_errno rc = BCM_ERR_OK;
1343 mac_util_topo_pon_context *topo_context;
1344
1345 topo_context = bcm_topo_pon_get_context(p_flow_req->data.access_int_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
1346 if ((BCM_ERR_OK == rc) && (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode))
1347 {
1348 if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, o_vid))
1349 {
1350 /* if the flow has an action to remove the outer tag from a double tagged OLT downstream packets,
1351 the outer tag will be removed by the SWITCH in front of the MAC, the MAC should take the inner
1352 tag vid for GEM decision. Sep-28-2015 IL
1353 */
1354 if (BCMOS_TRUE == mac_util_check_flow_is_double_tag_remove_o_tag (p_flow_req))
1355 {
1356 if (BCMOS_TRUE != BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, i_vid))
1357 {
1358 BCM_LOG(INFO, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1359 "classifier i_vid id is a mandatory downstream parameter for double tagged action, "
1360 "and it is not set\n");
1361 rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
1362 }
1363 }
1364 }
1365 else
1366 {
1367 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1368 "o_vid id is a mandatory parameter for a flow classifier, and it is not set\n");
1369 rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
1370 }
1371 }
1372
1373 if (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
1374 {
1375 if (!BCMBAL_CFG_PROP_IS_SET(p_flow_req, flow, agg_port_id))
1376 {
1377 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1378 "agg port id is a mandatory parameter for an US flow, and it is not set\n");
1379 rc = BCM_ERR_MANDATORY_PARM_IS_MISSING;
1380 }
1381
1382 }
1383
1384 return rc;
1385}
1386
1387
1388/**
1389 * @brief flow set for GPON
1390 *
1391 * @param p_flow_req pointer to flow request structure from core
1392 * @param op_type ADD, REMOVE or CLEAR
1393 * @param p_flow_core local DB flow context passed as a cookie
1394 *
1395 * @return errno error
1396 */
1397bcmos_errno mac_util_flow_set_for_gpon (bcmbal_flow_cfg *p_flow_req, bal_util_oper_flow op_type, flow_inst *p_flow_core)
1398{
1399 bcmos_errno rc = BCM_ERR_OK;
1400
1401 bcmos_bool is_pbit_enabled = BCMOS_FALSE;
1402 uint16_t per_flow_mode_vlan_id = 0; /* hold the value of the vlan tag to use in per-flow mode */
1403 uint8_t pbits_val = 0;
1404 mac_util_topo_pon_context *topo_context;
1405 flow_list_entry *p_mac_util_flow_entry = NULL;
1406
1407 topo_context = bcm_topo_pon_get_context(p_flow_req->data.access_int_id, BCM_TOPO_PON_CONTEXT_ID_MAC_UTIL);
1408 if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
1409 {
1410 per_flow_mode_vlan_id = 0; /* set to default */
1411
1412 if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, o_vid))
1413 {
1414 /* if the flow has an action to remove the outer tag from a double tagged OLT downstream packets,
1415 the outer tag will be removed by the SWITCH in front of the MAC, the MAC should take the inner
1416 tag vid for GEM decision. Sep-28-2015 IL
1417 */
1418 if (BCMOS_TRUE == mac_util_check_flow_is_double_tag_remove_o_tag (p_flow_req))
1419 {
1420 if (BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&(p_flow_req->data.classifier), classifier, i_vid))
1421 {
1422 per_flow_mode_vlan_id = p_flow_req->data.classifier.i_vid;
1423 }
1424 //else should not happen here really, since this was validated in a previous step
1425 }
1426 else
1427 {
1428 per_flow_mode_vlan_id = p_flow_req->data.classifier.o_vid;
1429 }
1430 }
1431 //else should not happen here really, since this was validated in a previous step
1432 }
1433
1434
1435 /* Check the operation id */
1436 if ((BAL_UTIL_OPER_FLOW_ADD != op_type) &&
1437 (BAL_UTIL_OPER_FLOW_REMOVE != op_type) &&
1438 (BAL_UTIL_OPER_FLOW_CLEAR != op_type))
1439 {
1440 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1441 "Unexpected mac_util flow operation %d \n", op_type);
1442 return BCM_ERR_PARM;
1443 }
1444
1445 /* flow Add or Modify */
1446 if (BAL_UTIL_OPER_FLOW_ADD == op_type)
1447 {
1448 switch (p_flow_req->key.flow_type)
1449 {
1450 /* unicast flows */
1451 case BCMBAL_FLOW_TYPE_UPSTREAM:
1452 case BCMBAL_FLOW_TYPE_DOWNSTREAM:
1453 {
1454 if (p_flow_req->data.classifier.o_pbits)
1455 {
1456 /* o_pbits can only take one p-bit value */
1457 pbits_val = p_flow_req->data.classifier.o_pbits;
1458 is_pbit_enabled = BCMOS_TRUE;
1459 }
1460 else
1461 {
1462 pbits_val = 0;
1463 is_pbit_enabled = BCMOS_FALSE;
1464 }
1465
1466 /* create a gem port id and relevant flow for a single pbit, or with no pbit */
1467 /* pass on the op type also to specify if it is FLOW_ADD OR FLOW_MODIFY */
1468 rc = maple_mac_unicast_flow_add(p_flow_req, pbits_val, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
1469 if ((BCM_ERR_OK != rc) || (NULL == p_mac_util_flow_entry))
1470 {
1471 break;
1472 }
1473
1474
1475 /* configure iwf flows in case of per flow interworking mode */
1476 if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
1477 {
1478 if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type)
1479 {
1480 rc = maple_mac_ds_iwf_cfg(p_flow_req, per_flow_mode_vlan_id, is_pbit_enabled);
1481 }
1482 else
1483 /* FLOW_TYPE_UPSTREAM */
1484 {
1485 rc = maple_mac_us_iwf_cfg(p_flow_req, pbits_val);
1486 }
1487 if (BCM_ERR_OK != rc)
1488 {
1489 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1490 "Failed to add iwf flows in per flow mode (%s))\n",
1491 bcmos_strerror(rc));
1492 break;
1493 }
1494 }
1495
1496 /* mark flow configuration to device completed */
1497 mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
1498 }
1499 break;
1500
1501 case BCMBAL_FLOW_TYPE_BROADCAST:
1502 {
1503 rc = maple_mac_broadcast_flow_add(p_flow_req, per_flow_mode_vlan_id, op_type, &p_mac_util_flow_entry);
1504 if ((BCM_ERR_OK != rc) || (NULL == p_mac_util_flow_entry))
1505 {
1506 break;
1507 }
1508
1509 }
1510 break;
1511
1512 default:
1513 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1514 "Unknown flow type %d\n",
1515 p_flow_req->key.flow_type);
1516 rc = BCM_ERR_PARM;
1517 break;
1518 }
1519 }
1520 else if ((BAL_UTIL_OPER_FLOW_REMOVE == op_type) ||
1521 (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
1522 {
1523 /* find the flow */
1524 p_mac_util_flow_entry = _mac_util_db_flow_get_w_flow_key(p_flow_req->data.access_int_id, &(p_flow_req->key));
1525 if (NULL == p_mac_util_flow_entry)
1526 {
1527 rc = BCM_ERR_NOENT;
1528 if (BAL_UTIL_OPER_FLOW_CLEAR != op_type)
1529 {
1530 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1531 "%s: NULL mac util flow entry to remove: flow id: %d, flow_type: %s\n",
1532 __FUNCTION__,
1533 p_flow_req->key.flow_id,
1534 (p_flow_req->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ? "up":"down"));
1535 }
1536
1537 goto exit;
1538 }
1539
1540 switch (p_flow_req->key.flow_type)
1541 {
1542 /* unicast flows */
1543 case BCMBAL_FLOW_TYPE_UPSTREAM:
1544 case BCMBAL_FLOW_TYPE_DOWNSTREAM:
1545 {
1546 /* First De-configure IWF flows in case of per flow interworking mode */
1547 if (BCMOLT_IWF_MODE_PER_FLOW_MODE == topo_context->iwf_mode)
1548 {
1549 if (BCMBAL_FLOW_TYPE_DOWNSTREAM == p_flow_req->key.flow_type)
1550 {
1551 rc = maple_mac_ds_iwf_cfg_remove(p_flow_req, per_flow_mode_vlan_id);
1552 }
1553 else
1554 {
1555 rc = maple_mac_us_iwf_cfg_remove(p_flow_req);
1556 }
1557 if (BCM_ERR_OK != rc)
1558 {
1559 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1560 "Failed to remove iwf flows in per flow mode (%s))\n",
1561 bcmos_strerror(rc));
1562 break;
1563 }
1564 }
1565
1566
1567 /** Then remove unicast GEM/Alloc Id from Maple and flow entry from local database */
1568 rc = maple_mac_unicast_flow_remove(p_flow_req, op_type, p_mac_util_flow_entry);
1569 if (BCM_ERR_OK != rc)
1570 {
1571 break;
1572 }
1573
1574 /* mark flow De-configuration to device completed */
1575 mac_util_mark_flow_config_complete(p_mac_util_flow_entry);
1576 }
1577 break;
1578
1579 case BCMBAL_FLOW_TYPE_BROADCAST:
1580 {
1581 rc = maple_mac_broadcast_flow_remove(p_flow_req, per_flow_mode_vlan_id, op_type, p_mac_util_flow_entry);
1582 }
1583 break;
1584
1585 default:
1586 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1587 "Unknown flow type %d\n",
1588 p_flow_req->key.flow_type);
1589 rc = BCM_ERR_PARM;
1590 break;
1591 }
1592
1593 }
1594 else
1595 {
1596 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(p_flow_req->data.access_int_id),
1597 "Unknown flow op type %d for flow id/type = %d/%d\n",
1598 op_type, p_flow_req->key.flow_id, p_flow_req->key.flow_type);
1599 rc = BCM_ERR_PARM;
1600 }
1601
1602exit:
1603 if (BCM_ERR_OK == rc)
1604 {
1605 /*
1606 * Check flow entry flags to see if an indication to Core should be triggered immediately:
1607 * (Special handling for flow configuration, for the case no device configuration is needed,
1608 * and/or no indication from device is expected - could be the case of a single/multiple
1609 * gem ports used for us and ds, and us was already configured.
1610 * - send the flow ind immediately
1611 */
1612 check_send_flow_bal_ind_msg(p_mac_util_flow_entry, BCM_ERR_OK, BCMOLT_RESULT_SUCCESS);
1613 }
1614 else
1615 {
1616 if ((BCM_ERR_NOENT == rc) && (BAL_UTIL_OPER_FLOW_CLEAR == op_type))
1617 {
1618 /*
1619 * For flow CLEAR, and if no flow entry is found, then fake an indication success to Core,
1620 * for it to execute the flow state machine.
1621 * The reasons for flow entry not found could be because the flow was already admin-ed Down.
1622 * Admin-down of a flow causes mac util to clear flow config and flow instance from itself
1623 * and the maple HW. However, Core FSM still keeps it's flow instance during admin down state.
1624 */
1625 mac_util_report_flow_remove_success (p_flow_req->key, p_flow_req->data.access_int_id, op_type);
1626 rc = BCM_ERR_OK;
1627 }
1628 }
1629 //else if there was an error during config, just return a failure; no need to send back indication for that.
1630
1631
1632 return rc;
1633}
1634
1635bcmos_errno maple_gpon_mac_check_gem_port_id(uint32_t if_id, uint32_t onu_id, uint16_t svc_port_id,
1636 bcmos_bool *is_configured, bcmos_bool *is_activated)
1637{
1638 bcmos_errno rc = BCM_ERR_OK;
1639 bcmolt_gpon_gem_port_key gem_key = {};
1640 bcmolt_gpon_gem_port_cfg gem_cfg = {};
1641 bcmolt_devid device_id;
1642 uint32_t physical_if_id;
1643
1644 GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
1645
1646 /* set the gem port object key */
1647 gem_key.pon_ni = physical_if_id;
1648 gem_key.gem_port_id = svc_port_id;
1649 BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
1650 BCMOLT_CFG_PROP_GET(&gem_cfg, gpon_gem_port, all_properties);
1651
1652 rc = bcmolt_cfg_get(device_id, &gem_cfg.hdr);
1653 if(BCM_ERR_OK != rc)
1654 {
1655 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
1656 "%s FAILED in bcmolt_cfg_get: svc_port_id = %d if_id = %d onu_id = %d\n",
1657 __FUNCTION__,
1658 svc_port_id, if_id, onu_id);
1659
1660 return rc;
1661 }
1662
1663
1664 /* may be configured; does gem belong to same onu ? */
1665 if (BCMOLT_GPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state && onu_id != gem_cfg.data.onu_id)
1666 {
1667 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
1668 "%s FAILED, onu id mismatch: svc_port_id = %d if_id = %d is already assigned to onu_id = %d (not to onu id %d) \n",
1669 __FUNCTION__,
1670 svc_port_id, if_id, gem_cfg.data.onu_id, onu_id);
1671
1672 return BCM_ERR_PARM;
1673 }
1674 *is_configured = BCMOLT_GPON_GEM_PORT_STATE_NOT_CONFIGURED != gem_cfg.data.gem_port_state;
1675 *is_activated = BCMOLT_GPON_GEM_PORT_STATE_ACTIVE == gem_cfg.data.gem_port_state;
1676
1677 return rc;
1678}
1679
1680
1681bcmos_errno maple_gpon_gem_port_id_add(uint32_t if_id, uint16_t svc_port_id, uint32_t onu_id, bcmolt_gem_port_configuration *configuration)
1682{
1683 bcmos_errno rc = BCM_ERR_OK;
1684 bcmolt_gpon_gem_port_key gem_key = {};
1685 bcmolt_gpon_gem_port_cfg gem_cfg = {};
1686 bcmolt_devid device_id;
1687 uint32_t physical_if_id;
1688
1689 GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
1690
1691 /* set the gem port object key */
1692 gem_key.pon_ni = physical_if_id;
1693 gem_key.gem_port_id = svc_port_id;
1694 BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
1695
1696 /* set the gem port configuration */
1697 if (onu_id < MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM)
1698 {
1699 BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, onu_id, onu_id);
1700 BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, upstream_destination_queue,
1701 BCMOLT_US_GEM_PORT_DESTINATION_DATA);
1702 }
1703 BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, downstream_encryption_mode,
1704 BCMOLT_CONTROL_STATE_DISABLE);
1705 BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, configuration, *configuration);
1706 BCMOLT_CFG_PROP_SET(&gem_cfg, gpon_gem_port, control, BCMOLT_CONTROL_STATE_ENABLE);
1707
1708 rc = bcmolt_cfg_set(device_id, &gem_cfg.hdr);
1709 if(BCM_ERR_OK != rc)
1710 {
1711 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
1712 "%s FAILED: rc=%s (%d), svc_port_id = %d dev_id = %d if_id = %d onu_id = %d, err_text=%s\n",
1713 __FUNCTION__,
1714 bcmos_strerror(rc), rc, svc_port_id, device_id, if_id, onu_id, gem_cfg.hdr.hdr.err_text);
1715 }
1716
1717 return rc;
1718}
1719
1720
1721bcmos_errno maple_gpon_gem_port_id_remove(uint32_t if_id, uint16_t svc_port_id)
1722{
1723 bcmos_errno rc = BCM_ERR_OK;
1724 bcmolt_gpon_gem_port_key gem_key = {};
1725 bcmolt_gpon_gem_port_cfg gem_cfg = {};
1726 bcmolt_devid device_id;
1727 uint32_t physical_if_id;
1728
1729 GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
1730
1731 gem_key.pon_ni = physical_if_id;
1732 gem_key.gem_port_id = svc_port_id;
1733 BCMOLT_CFG_INIT(&gem_cfg, gpon_gem_port, gem_key);
1734 rc = bcmolt_cfg_clear(device_id, &gem_cfg.hdr);
1735 if (BCM_ERR_OK != rc)
1736 {
1737 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s id=%d, gem=%d, failed with error %s\n",__FUNCTION__, if_id, svc_port_id, bcmos_strerror(rc));
1738 }
1739
1740
1741 return rc;
1742}
1743
1744
1745bcmos_errno maple_gpon_mac_get_alloc_id_config (uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_alloc_state *alloc_id_state)
1746{
1747 bcmos_errno rc = BCM_ERR_OK;
1748 bcmolt_gpon_alloc_key alloc_key = {};
1749 bcmolt_gpon_alloc_cfg alloc_cfg = {};
1750 bcmolt_devid device_id;
1751 uint32_t physical_if_id;
1752
1753 GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
1754
1755 /* set the alloc-id key */
1756 alloc_key.pon_ni = physical_if_id;
1757 alloc_key.alloc_id = agg_id;
1758 BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
1759 BCMOLT_CFG_PROP_GET(&alloc_cfg, gpon_alloc, all_properties);
1760
1761 rc = bcmolt_cfg_get(device_id, &alloc_cfg.hdr);
1762 if(BCM_ERR_OK != rc)
1763 {
1764 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
1765 "%s: FAILED in bcmolt_cfg_get rc = %s, agg_id = %d if_id = %d\n",
1766 __FUNCTION__,
1767 bcmos_strerror(rc), agg_id, if_id);
1768
1769 return rc;
1770 }
1771
1772 /* may be configured; does alloc id belong to the expected onu ? */
1773 if (alloc_cfg.data.state != BCMOLT_ALLOC_STATE_NOT_CONFIGURED
1774 && alloc_cfg.data.onu_id != onu_id)
1775 {
1776 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
1777 "%s FAILED, onu id mismatch: agg_id = %d if_id = %d is set to onu %d NOT to onu_id = %d\n",
1778 __FUNCTION__,
1779 agg_id, if_id, alloc_cfg.data.onu_id, onu_id);
1780
1781 return BCM_ERR_PARM;
1782 }
1783
1784 *alloc_id_state = alloc_cfg.data.state;
1785
1786 return BCM_ERR_OK;
1787}
1788
1789
1790bcmos_errno maple_gpon_us_alloc_id_add(uint32_t if_id, uint32_t onu_id, uint16_t agg_id, bcmolt_pon_alloc_sla agg_sla)
1791{
1792 bcmos_errno rc = BCM_ERR_OK;
1793 bcmolt_gpon_alloc_key alloc_key = {};
1794 bcmolt_gpon_alloc_cfg alloc_cfg = {};
1795 bcmolt_devid device_id;
1796 uint32_t physical_if_id;
1797
1798 GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
1799
1800 /* set the alloc-id key */
1801 alloc_key.pon_ni = physical_if_id;
1802 alloc_key.alloc_id = agg_id;
1803 BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
1804 BCMOLT_CFG_PROP_SET(&alloc_cfg, gpon_alloc, sla, agg_sla);
1805 /* set the alloc-id - onu assignment */
1806 BCMOLT_CFG_PROP_SET(&alloc_cfg, gpon_alloc, onu_id, onu_id);
1807
1808 rc = bcmolt_cfg_set(device_id, &alloc_cfg.hdr);
1809 if(BCM_ERR_OK != rc)
1810 {
1811 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id),
1812 "%s: rc = %s, agg_id = %d if_id = %d, err_text = %s \n",
1813 __FUNCTION__,
1814 bcmos_strerror(rc), agg_id, if_id, alloc_cfg.hdr.hdr.err_text);
1815 }
1816 return rc;
1817
1818}
1819
1820
1821bcmos_errno maple_gpon_us_alloc_id_remove(uint32_t if_id, uint16_t agg_id)
1822{
1823 bcmos_errno rc = BCM_ERR_OK;
1824 bcmolt_gpon_alloc_key alloc_key = {};
1825 bcmolt_gpon_alloc_cfg alloc_cfg = {};
1826 bcmolt_devid device_id;
1827 uint32_t physical_if_id;
1828
1829 GET_DEVICE_ID_AND_PHYSICAL_ID_FROM_IF_ID(if_id, device_id, physical_if_id);
1830
1831 /* set the alloc-id key */
1832 alloc_key.pon_ni = physical_if_id;
1833 alloc_key.alloc_id = agg_id;
1834 BCMOLT_CFG_INIT(&alloc_cfg, gpon_alloc, alloc_key);
1835
1836 rc = bcmolt_cfg_clear(device_id, &alloc_cfg.hdr);
1837 if (BCM_ERR_OK != rc)
1838 {
1839 BCM_LOG(ERROR, MAC_UTIL_GET_LOG_ID_FOR_PON_IF(if_id), "%s failed with error %s\n",__FUNCTION__, bcmos_strerror(rc));
1840 }
1841
1842 return rc;
1843}
1844
1845/**
1846 * @brief group set for gpon
1847 * @param p_group_req pointer to group request structure from core
1848 * @param op_type ADD, REMOVE or SET
1849 * @param p_group_inst pointer to the Core Group Object instance
1850 *
1851 * @return errno error
1852 *
1853 * @todo shift this out to mac specific files
1854 */
1855bcmos_errno mac_util_group_set_for_gpon (bcmbal_group_cfg *p_group_req, bal_util_oper_group op_type, group_inst *p_group_inst)
1856{
1857 bcmos_errno rc = BCM_ERR_OK;
1858 uint16_t svc_port_id;
1859 uint32_t if_id, i, ref_count;
1860 bcmolt_gem_port_configuration configuration = {0};
1861
1862 /* Check the operation id */
1863 if ((BAL_UTIL_OPER_GROUP_ADD != op_type) &&
1864 (BAL_UTIL_OPER_GROUP_REMOVE != op_type) &&
1865 (BAL_UTIL_OPER_GROUP_SET != op_type))
1866 {
1867 BCM_LOG(ERROR, log_id_mac_util,
1868 "Unexpected mac_util gpon group operation %d \n", op_type);
1869 return BCM_ERR_PARM;
1870 }
1871
1872 configuration.direction = BCMOLT_GEM_PORT_DIRECTION_DOWNSTREAM;
1873 configuration.type = BCMOLT_GEM_PORT_TYPE_MULTICAST;
1874
1875 /* for group SET operation, first remove the old multicast GEM */
1876 if (BAL_UTIL_OPER_GROUP_SET == op_type)
1877 {
1878 bcmbal_group_cfg *p_group_rem_req;
1879 /* use the Core DB for existing members - store in current_flow_info */
1880 p_group_rem_req = &p_group_inst->current_group_info;
1881 for(i=0; i< p_group_rem_req->data.members.len; i++)
1882 {
1883 if_id = p_group_rem_req->data.members.val[i].intf_id;
1884 svc_port_id = p_group_rem_req->data.members.val[i].svc_port_id;
1885 /* svc_port_id can be 0 (not assigned) when group had no owner, no need to remove */
1886 if(svc_port_id)
1887 {
1888 rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
1889 if(BCM_ERR_OK != rc)
1890 {
1891 BCM_LOG(ERROR, log_id_mac_util,
1892 "mac_util gpon group get reference count on interface %d (gem %d) failed \n", if_id, svc_port_id);
1893 return rc;
1894 }
1895 /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
1896 The core will ask Resource Manger to decrease the counter if everything is good */
1897 if ( ref_count == 1)
1898 {
1899 rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
1900
1901 if(BCM_ERR_OK != rc)
1902 {
1903 BCM_LOG(ERROR, log_id_mac_util,
1904 "mac_util gpon group set operation SET on remove interface %d (gem %d) failed \n", if_id, svc_port_id);
1905 return rc;
1906 }
1907 }
1908 else if ( ref_count == 0)
1909 {
1910 BCM_LOG(WARNING, log_id_mac_util,
1911 "mac_util gpon group set operation SET on interface %d (gem %d) remove with 0 reference counter \n", if_id, svc_port_id);
1912 }
1913 }
1914 }
1915 }
1916
1917 /* walk through every member interface */
1918 for(i=0; i< p_group_req->data.members.len; i++)
1919 {
1920 if_id = p_group_req->data.members.val[i].intf_id;
1921 svc_port_id = p_group_req->data.members.val[i].svc_port_id;
1922 /* group Add */
1923 if (BAL_UTIL_OPER_GROUP_ADD == op_type || BAL_UTIL_OPER_GROUP_SET == op_type)
1924 {
1925 rc = maple_gpon_gem_port_id_add(if_id, svc_port_id, MAC_UTIL_DUMMY_ONU_ID_FOR_MULTICAST_GEM, &configuration);
1926 }
1927 else if (BAL_UTIL_OPER_GROUP_REMOVE == op_type)
1928 {
1929 rc = rsc_mgr_gem_get_ref_count(if_id, svc_port_id, &ref_count);
1930 if(BCM_ERR_OK != rc)
1931 {
1932 BCM_LOG(ERROR, log_id_mac_util,
1933 "mac_util gpon group operation REM on interface %d (gem %d) failed \n", if_id, svc_port_id);
1934 break;
1935 }
1936 /* if other group is referencing the same GEM (ref_count > 1), do not call Mac API to remove it.
1937 The core will ask Resource Manger to decrease the counter if everything is good */
1938 if ( ref_count == 1)
1939 {
1940 rc = maple_gpon_gem_port_id_remove(if_id, svc_port_id);
1941 }
1942 else if ( ref_count == 0)
1943 {
1944 BCM_LOG(WARNING, log_id_mac_util,
1945 "mac_util gpon group operation REM on interface %d (gem %d) with 0 reference count \n", if_id, svc_port_id);
1946 }
1947 }
1948
1949 if(BCM_ERR_OK != rc)
1950 {
1951 BCM_LOG(ERROR, log_id_mac_util,
1952 "mac_util gpon group set of operation %d on interface %d (gem %d) failed \n", op_type, if_id, svc_port_id);
1953 break;
1954 }
1955 }
1956
1957
1958 return rc;
1959}
1960
1961/*@}*/