blob: c4635b95b44a02ca9732743bb40f9cb9cfc779b4 [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 acc_term_fsm.c
34 * @brief Code to support the BAL access terminal FSM
35 *
36 * @addtogroup access_terminal
37 */
38
39/*@{*/
40
41#define BAL_DBG_PRINT
42
43/*--- project includes ---*/
44#include <bcmos_system.h>
45#include <acc_term_fsm.h>
46#include <bal_msg.h>
47#include <bal_api.h>
48#include "bal_worker.h"
49#include "bal_mac_util.h"
50#include "bal_switch_util.h"
51#include <bal_osmsg.h>
52#include <fsm_common.h>
53#include <rsc_mgr.h>
54#include <bal_core.h>
55
56#ifdef ENABLE_LOG
57#include <bcm_dev_log.h>
58
59/*
60 * @brief The logging device ids for the access-terminal and interface
61 */
62static dev_log_id log_id_access_terminal;
63static dev_log_id log_id_interface;
64#endif
65
66
67/*--- local function declarations ---*/
68static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
69 void *msg,
70 acc_term_fsm_event *p_event);
71
72static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
73 void *msg,
74 acc_term_fsm_event *p_event);
75
76static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
77 void *msg,
78 acc_term_fsm_event *p_event);
79
80static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
81 void *msg,
82 acc_term_fsm_event *p_event);
83
84static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
85 void *msg,
86 acc_term_fsm_event *p_event);
87
88static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
89 void *msg,
90 acc_term_fsm_event *p_event);
91
92static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
93 void *msg,
94 acc_term_fsm_event *p_event);
95
96static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
97 void *msg,
98 acc_term_fsm_event *p_event);
99
100static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
101 void *msg,
102 acc_term_fsm_event *p_event);
103
104static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
105 void *msg,
106 acc_term_fsm_event *p_event);
107
108static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
109 void *msg,
110 acc_term_fsm_event *p_event);
111
112static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
113 void *msg,
114 acc_term_fsm_event *p_event);
115
116static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface,
117 void *msg);
118
119static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface,
120 void *msg);
121
122static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser);
123
124static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst, acc_term_fsm_event *p_event);
125
126
127/**
128 * access-terminal FSM helper functions
129 */
130static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
131 void *msg,
132 acc_term_fsm_event *p_event);
133
134static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst);
135
136static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
137 bcmbal_sub_id_list_u16 *sub_term_id_list);
138
139
140static acc_term_inst *access_terminal_get(void);
141static char *interface_type_str_get(bcmbal_intf_type intf_type);
142
143static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info);
144static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key);
145
146#define ACC_TERM_FSM_STATE_ADDING_TIMEOUT (45) /* Seconds */
147
148/*
149 * @brief The definition of an access terminal FSM state processing function
150 */
151typedef bcmos_errno (* acc_term_fsm_state_processor)(acc_term_inst *, void *, acc_term_fsm_event *);
152
153extern bcmbal_config_params bal_config_params;
154
155
156/**
157 * @brief API to get oper status from admin state of an interface
158 */
159bcmbal_status bcmbal_get_intf_oper_status_from_admin_state (bcmbal_state intf_admin_state)
160{
161 switch (intf_admin_state)
162 {
163 case BCMBAL_STATE_UP:
164 return BCMBAL_STATUS_UP;
165 break;
166
167 case BCMBAL_STATE_DOWN:
168 return BCMBAL_STATUS_DOWN;
169 break;
170
171 case BCMBAL_STATE_TESTING:
172 return BCMBAL_STATUS_TESTING;
173 break;
174
175 default:
176 return BCMBAL_STATUS_UP; /* default keep oper status as UP */
177 break;
178 }
179
180 return BCMBAL_STATUS_UP; /* default keep oper status as UP */
181}
182
183
184/**
185 * @brief API to convert port type and id from CLI/Mgmt interface to the internal
186 * index of interface array database.
187 */
188uint32_t bcmbal_port_type_and_id_to_interface_index (bcmbal_intf_type intf_type, bcmbal_intf_id intf_id)
189{
190 switch (intf_type)
191 {
192 case BCMBAL_INTF_TYPE_PON:
193 if (intf_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
194 {
195 return intf_id; /* zero offset for the PON ports */
196 }
197 break;
198
199 case BCMBAL_INTF_TYPE_NNI:
200 if (intf_id < bal_config_params.num_nni_ports)
201 {
202 return (NUM_SUPPORTED_SUBSCRIBER_INTERFACES + intf_id); /* offset-ed for the NNI ports */
203 }
204 break;
205
206 default:
207 break;
208 }
209
210 return INVALID_INTERFACE_INDEX;
211
212}
213
214
215/*
216 * @brief The Access terminal FSM state processing array
217 */
218static acc_term_fsm_state_processor access_term_states[ACC_TERM_FSM_STATE__NUM_OF][ACC_TERM_FSM_EVENT_TYPE__NUM_OF] =
219{
220
221 [ACC_TERM_FSM_STATE_NULL] =
222 {
223 /*
224 * Next state: ADDING
225 */
226 [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_start,
227
228 /*
229 * Next state: NULL
230 */
231 [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_ok,
232
233 /*
234 * Next state: NULL
235 */
236 [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_ignore_msg,
237
238 /*
239 * Next state: NULL
240 */
241 [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
242 },
243
244 [ACC_TERM_FSM_STATE_ADDING] =
245 {
246 /*
247 * Next state: ADDING
248 */
249 [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_pending,
250
251 /*
252 * Next state: ADDING | ADDED
253 */
254 [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_adding_process_util_msg,
255
256 /*
257 * Next state: ADDING
258 */
259 [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
260
261 /*
262 * Next state: NULL
263 */
264 [ACC_TERM_FSM_EVENT_TYPE_TIMEOUT] = acc_term_fsm_process_adding_timeout,
265
266 },
267
268 [ACC_TERM_FSM_STATE_ADDED] =
269 {
270 /*
271 * Next state: ADDED
272 */
273 [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP] = acc_term_fsm_acc_term_admin_up_ok,
274
275 /*
276 * Next state: REMOVING
277 */
278 [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_start,
279
280 /*
281 * Next state: ADDING | ADDED
282 */
283 [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_ignore_msg,
284
285 /*
286 * Next state: ADDED
287 */
288 [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
289
290 },
291
292 [ACC_TERM_FSM_STATE_REMOVING] =
293 {
294 /*
295 * Next state: REMOVING
296 */
297 [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN] = acc_term_fsm_acc_term_admin_dn_pending,
298
299 /*
300 * Next state: REMOVING | NULL
301 */
302 [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG] = acc_term_fsm_removing_process_util_msg,
303
304 /*
305 * Next state: REMOVING
306 */
307 [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG] = acc_term_fsm_process_util_auto_msg,
308
309 /*
310 * Next state: NULL
311 */
312 [ACC_TERM_FSM_EVENT_TYPE_TIMEOUT] = acc_term_fsm_process_removing_timeout,
313 },
314
315};
316
317static char *state_name_str[] =
318{
319 "ACC_TERM_NULL",
320 "ACC_TERM_ADDING",
321 "ACC_TERM_ADDED",
322 "ACC_TERM_REMOVING",
323};
324
325/* Ensure that the name array size matches the associated enum */
326BAL_STATIC_ASSERT (ACC_TERM_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), acc_term_fsm_state);
327
328static char *acc_term_state_name_get(acc_term_fsm_state state)
329{
330 if(state < ACC_TERM_FSM_STATE__LAST)
331 {
332 return state_name_str[state];
333 }
334 else
335 {
336 return "ACC_TERM_UNKNOWN";
337 }
338}
339
340static char *event_name_str[] =
341{
342 "ACC_TERM_FSM_ACC_TERM_ADMIN_UP_EVENT",
343 "ACC_TERM_FSM_ACC_TERM_ADMIN_DN_EVENT",
344 "ACC_TERM_FSM_INT_ADMIN_UP_EVENT",
345 "ACC_TERM_FSM_INT_ADMIN_DN_EVENT",
346 "ACC_TERM_FSM_UTIL_MSG_EVENT",
347 "ACC_TERM_FSM_UTIL_AUTO_MSG_EVENT",
348 "ACC_TERM_FSM_TIMEOUT_EVENT"
349};
350
351/* Ensure that the name array size matches the associated enum */
352BAL_STATIC_ASSERT (ACC_TERM_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), acc_term_fsm_event_type);
353
354static char *acc_term_event_name_get(acc_term_fsm_event_type event)
355{
356 if(event < ACC_TERM_FSM_EVENT_TYPE__LAST)
357 {
358 return event_name_str[event];
359 }
360 else
361 {
362 return "ACC_TERM_EVT_UNKNOWN";
363 }
364}
365
366static acc_term_inst single_access_terminal_instance;
367
368/*****************************************************************************/
369/**
370 * @brief A function called to initialize the access-terminal FSM
371 * infrastructure.
372 *
373 * NOTE: This is called once on startup and NOT for each FSM instance.
374 *
375 * @returns void
376 *****************************************************************************/
377void access_terminal_fsm_init(void)
378{
379
380#ifdef ENABLE_LOG
381 /* Register the log ids for this FSM */
382 log_id_access_terminal = bcm_dev_log_id_register("ACC_TERM", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
383 BUG_ON(log_id_access_terminal == DEV_LOG_INVALID_ID);
384
385 log_id_interface = bcm_dev_log_id_register("INTF", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
386 BUG_ON(log_id_interface == DEV_LOG_INVALID_ID);
387#endif
388
389 /*
390 * Initialize the access terminal instance structures
391 */
392 initialize_access_terminal_instance_config(&single_access_terminal_instance);
393}
394
395/*****************************************************************************/
396/**
397 * @brief The Access terminal FSM state processing executive function
398 *
399 * @param p_acc_term_inst Pointer to an access terminal instance
400 * @param p_event Pointer to an access terminal event structure
401 *
402 * @returns bcmos_errno
403 *****************************************************************************/
404static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst,
405 acc_term_fsm_event *p_event)
406{
407
408 bcmos_errno ret = BCM_ERR_OK;
409 acc_term_fsm_state pre_state;
410 acc_term_fsm_state_processor acc_term_state_processor;
411
412 /* Parameter checks */
413 BUG_ON(NULL == p_acc_term_inst);
414 BUG_ON(NULL == p_event);
415
416 /* Record the present state before transitioning
417 */
418 pre_state = p_acc_term_inst->fsm_state;
419
420 /*
421 * Get the state processing function
422 */
423 acc_term_state_processor = access_term_states[p_acc_term_inst->fsm_state][p_event->event_type];
424
425 /*
426 * If there's a state processing function for this event and state, execute it.
427 * Otherwise, process a generic error.
428 */
429 if (acc_term_state_processor)
430 {
431 ret = acc_term_state_processor(p_acc_term_inst, p_event->msg, p_event);
432 } else
433 {
434 acc_term_fsm_state_err(p_acc_term_inst, p_event->msg, p_event);
435 }
436
437 BCM_LOG(DEBUG, log_id_access_terminal, "*** FSM exec: Event %s, State: %s --> %s\n",
438 acc_term_event_name_get(p_event->event_type),
439 acc_term_state_name_get(pre_state),
440 acc_term_state_name_get(p_acc_term_inst->fsm_state));
441
442 return ret;
443}
444
445bcmos_errno process_access_terminal_util_msg(void *msg_payload)
446{
447 acc_term_inst *p_access_terminal_inst;
448
449 BCM_LOG(INFO, log_id_access_terminal, "ACCESS_TERMINAL indication received from util\n");
450
451 /* Find the specified access terminal instance */
452 p_access_terminal_inst = access_terminal_get();
453
454 if (NULL != p_access_terminal_inst)
455 {
456 acc_term_fsm_event event;
457
458 event.event_type = ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG;
459 event.msg = msg_payload;
460
461 access_terminal_fsm_exec(p_access_terminal_inst, &event);
462 }
463 else
464 {
465 BCM_LOG(ERROR, log_id_interface, "Could not find the ACTIVE access-terminal\n");
466 }
467
468 return BCM_ERR_OK;
469}
470
471/*****************************************************************************/
472/**
473 * @brief The Access terminal FSM state processing for an access-terminal
474 * admin-up command received from the BAL Public API when the specified
475 * access-terminal instance is in the admin-down state (i.e. when
476 * the access-terminal instance FSM is in the NULL state).
477 *
478 * @param p_acc_term_inst Pointer to an access terminal instance
479 * @param msg Pointer to a BAL message received from the BAL Public API
480 * @param p_event Pointer to an access terminal event structure
481 *
482 * @returns bcmos_errno
483 *****************************************************************************/
484static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
485 void *msg,
486 acc_term_fsm_event *p_event)
487{
488 bcmos_errno ret = BCM_ERR_OK;
489 acc_term_fsm_state old_state = p_acc_term_inst->fsm_state;
490
491 BCM_LOG(INFO, log_id_access_terminal,
492 "Received an admin UP request from BAL API - bringing access terminal up\n");
493
494 do
495 {
496 /* change access terminal state to ADDING */
497 p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDING;
498
499 /* start the timeout timer for the ADDING state */
500 fsm_timer_start(&p_acc_term_inst->timer_info,
501 p_acc_term_inst,
502 acc_term_fsm_timer_expiry,
503 TIMER_DURATION_IN_SEC(ACC_TERM_FSM_STATE_ADDING_TIMEOUT),
504 log_id_access_terminal);
505
506 /* Validate that the OLT SW version that the Bal was compiled against matches
507 * the SW version of the actual OLT that the Bal works with. We assume that
508 * Device Id 0 has the same version as all other OLT devices */
509 if (!bcmbal_is_mac_in_loopback() &&
510 (BCM_ERR_OK != (ret = mac_util_access_terminal_sw_version_validate((bcmolt_devid) 0))))
511 {
512 BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_sw_version_validate(() failed. rc=%s\n", bcmos_strerror(ret));
513 break;
514 }
515
516 /* Core calls Mac Utils to set the access-terminal parameters using the applicable SDK calls */
517 if(BCM_ERR_OK != (ret = mac_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT)))
518 {
519 BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
520 break;
521 }
522
523 }while(0);
524
525 if(BCM_ERR_OK == ret)
526 {
527 /*
528 * The access-terminal object command has succeeded. The current object info
529 * becomes the commanded object info, except for the oper_status. This should
530 * be done atomically
531 */
532 memcpy(&p_acc_term_inst->current_acc_term_obj_info,
533 &p_acc_term_inst->api_req_acc_term_obj_info,
534 sizeof(p_acc_term_inst->api_req_acc_term_obj_info));
535
536 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_TRUE);
537
538 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
539 access_terminal,
540 oper_status,
541 BCMBAL_STATUS_DOWN);
542 }
543 else
544 {
545 fsm_timer_stop(&p_acc_term_inst->timer_info);
546 p_acc_term_inst->fsm_state = old_state;
547 mgmt_msg_send_balapi_ind(ret, msg, log_id_access_terminal);
548 }
549
550 return ret;
551}
552
553/*****************************************************************************/
554/**
555 * @brief The Access terminal FSM state processing for an access-terminal
556 * admin-up command from the BAL Public API when the specified
557 * access-terminal is already admin-up (i.e. when the specified
558 * access-terminal instance FSM is in the ADDED state).
559 *
560 * @param p_acc_term_inst Pointer to an access terminal instance
561 * @param msg Pointer to a BAL message received from the BAL Public API
562 * @param p_event Pointer to an access terminal event structure
563 *
564 * @returns bcmos_errno
565 *****************************************************************************/
566static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
567 void *msg,
568 acc_term_fsm_event *p_event)
569{
570 bcmos_errno ret = BCM_ERR_OK;
571
572 BCM_LOG(DEBUG, log_id_access_terminal,
573 "Received an admin UP request from BAL API - returning OK to the API"
574 " - no further function\n");
575
576 return ret;
577}
578
579/*****************************************************************************/
580/**
581 * @brief The Access terminal FSM state processing for an access-terminal
582 * admin-down command received from the BAL Public API when the specified
583 * access-terminal is admin-up (i.e when the specified access-terminal
584 * instance FSM is in the ADDED state).
585 *
586 * @param p_acc_term_inst Pointer to an access terminal instance
587 * @param msg Pointer to a BAL message received from the BAL Public API
588 * @param p_event Pointer to an access terminal event structure
589 *
590 * @returns bcmos_errno
591 *****************************************************************************/
592static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
593 void *msg,
594 acc_term_fsm_event *p_event)
595{
596 bcmos_errno ret = BCM_ERR_OK;
597
598 BCM_LOG(DEBUG, log_id_access_terminal,
599 "Received an admin DOWN request from BAL API - removing the access terminal\n");
600
601 /*
602 * @todo - complete the DOWN implementation - until then, return an error
603 */
604 ret = BCM_ERR_NOT_SUPPORTED;
605
606 return ret;
607}
608
609/*****************************************************************************/
610/**
611 * @brief The Access terminal FSM state processing for access-terminal
612 * admin-down command from the BAL Public API when the specified
613 * access-terminal is already admin-down.
614 *
615 * @param p_acc_term_inst Pointer to an access terminal instance
616 * @param msg Pointer to a BAL message received from the BAL Public API
617 * @param p_event Pointer to an access terminal event structure
618 *
619 * @returns bcmos_errno
620 *****************************************************************************/
621static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
622 void *msg,
623 acc_term_fsm_event *p_event)
624{
625 bcmos_errno ret = BCM_ERR_OK;
626
627 BCM_LOG(DEBUG, log_id_access_terminal,
628 "Received an admin DOWN request from BAL API - returning OK to the API"
629 " - no further function\n");
630
631 return ret;
632}
633
634/*****************************************************************************/
635/**
636 * @brief The Access terminal FSM state processing function to ignore a
637 * received message.
638 *
639 * @param p_acc_term_inst Pointer to an access terminal instance
640 * @param msg Pointer to a BAL message received from the BAL Public API
641 * @param p_event Pointer to an access terminal event structure
642 *
643 * @returns bcmos_errno
644 *****************************************************************************/
645static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
646 void *msg,
647 acc_term_fsm_event *p_event)
648{
649 bcmos_errno ret = BCM_ERR_OK;
650
651 BCM_LOG(DEBUG, log_id_access_terminal, "Ignoring message from BAL API \n");
652 return ret;
653}
654
655/*****************************************************************************/
656/**
657 * @brief The Access terminal FSM state processing function to process an
658 * access-terminal admin-up command from the BAL Public API when the
659 * specified access-terminal is in the REMOVING state.
660 *
661 * @param p_acc_term_inst Pointer to an access terminal instance
662 * @param msg Pointer to a BAL message received from the BAL Public API
663 * @param p_event Pointer to an access terminal event structure
664 *
665 * @returns bcmos_errno
666 *****************************************************************************/
667static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
668 void *msg,
669 acc_term_fsm_event *p_event)
670{
671 bcmos_errno ret = BCM_ERR_OK;
672
673 BCM_LOG(DEBUG, log_id_access_terminal,
674 " Received an admin UP request from BAL API - returning UP_PENDING to the API"
675 " - no further function\n");
676
677 return ret;
678}
679
680/*****************************************************************************/
681/**
682 * @brief The Access terminal FSM state processing function to process an
683 * access-terminal admin-down command from the BAL Public API when the
684 * specified access-terminal FSM is in the REMOVING state.
685 *
686 * @param p_acc_term_inst Pointer to an access terminal instance
687 * @param msg Pointer to a BAL message received from the BAL Public API
688 * @param p_event Pointer to an access terminal event structure
689 *
690 * @returns bcmos_errno
691 *****************************************************************************/
692static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
693 void *msg,
694 acc_term_fsm_event *p_event)
695{
696 bcmos_errno ret = BCM_ERR_IN_PROGRESS;
697
698 BCM_LOG(DEBUG, log_id_access_terminal,
699 " Received an admin DOWN request from BAL API"
700 " - returning IN_PROGRESS to the API - no further function\n");
701
702 return ret;
703}
704
705/*****************************************************************************/
706/**
707 * @brief The Access terminal FSM state processing function to process a
708 * message from one of the BAL apps when the specified access-terminal
709 * instance FSM is in the ADDING state.
710 *
711 * @param p_acc_term_inst Pointer to an access terminal instance
712 * @param msg Pointer to a BAL message received from one of
713 * the BAL apps.
714 * @param p_event Pointer to an access terminal event structure
715 *
716 * @returns bcmos_errno
717 *****************************************************************************/
718static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
719 void *msg,
720 acc_term_fsm_event *p_event)
721{
722 flow_fsm_state next_state = ACC_TERM_FSM_STATE_NULL;
723 bcmos_errno ret;
724 bal_util_msg_ind *ind_msg;
725
726 /* Parameter checks */
727 BUG_ON(NULL == p_acc_term_inst);
728 BUG_ON(NULL == msg);
729 BUG_ON(NULL == p_event);
730
731 ind_msg = (bal_util_msg_ind *)msg;
732
733 ret = ind_msg->status;
734
735 /*
736 * NOTE: AUTO_IND messages are not processed in this function,
737 * so there is no need to consider them in this logic.
738 */
739 if(BCM_ERR_OK != ret)
740 {
741 BCM_LOG(ERROR, log_id_access_terminal,
742 "Received an IND message from BAL UTIL (%s) during ADDING state with status %s\n",
743 subsystem_str[bcmbal_sender_get(msg)],
744 bcmos_strerror(ret)
745 );
746 }
747
748 /*
749 * Stop the indication timer
750 */
751 fsm_timer_stop(&p_acc_term_inst->timer_info);
752
753 if(BCM_ERR_OK == ret)
754 {
755 /* Core calls Switch Utils to set the access-terminal parameters using the applicable SDK calls */
756 ret = sw_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT);
757 if (ret)
758 {
759 BCM_LOG(INFO, log_id_access_terminal,
760 "sw_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
761 }
762
763 if(BCM_ERR_OK == ret)
764 {
765 uint32_t logical_pon;
766
767 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
768 access_terminal,
769 oper_status,
770 BCMBAL_STATUS_UP);
771
772 /*
773 * Initialize the resource manager only if at least of the PONs on the device is a GPON/XGPON/XGS/NGPON2 PON
774 */
775 BCM_TOPO_DEV_FOR_EACH_PON(0, logical_pon)
776 {
777 bcm_topo_pon_family pon_family = bcm_topo_pon_get_pon_family(logical_pon);
778
779 if (pon_family == BCM_TOPO_PON_FAMILY_GPON)
780 {
781 rsc_mgr_mac_init();
782 break;
783 }
784 }
785
786 /*
787 * Go to the ADDED state upon success
788 */
789 next_state = ACC_TERM_FSM_STATE_ADDED;
790
791
792 }
793 else
794 {
795 /* Error */
796 BCM_LOG(ERROR, log_id_access_terminal,
797 " Failed in state %s;%s\n",
798 acc_term_state_name_get(p_acc_term_inst->fsm_state),
799 bcmos_strerror(ret));
800
801 /*
802 * Automatically return to the NULL state if an error occurs
803 */
804 }
805
806 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
807
808 /*
809 * Send the indication back to the BAL public API here
810 */
811 mgmt_msg_send_balapi_ind(ret,
812 (void *)&p_acc_term_inst->current_acc_term_obj_info.hdr,
813 log_id_access_terminal);
814
815
816
817 }
818
819 p_acc_term_inst->fsm_state = next_state;
820
821 return ret;
822}
823
824/*****************************************************************************/
825/**
826 * @brief The Access terminal FSM state processing function to process a
827 * message from one of the BAL apps received when the specified
828 * access-terminal instance FSM is in the REMOVING state.
829 *
830 * @param p_acc_term_inst Pointer to an access terminal instance
831 * @param msg Pointer to a BAL message received from one of
832 * the BAL apps.
833 * @param p_event Pointer to an access terminal event structure
834 *
835 * @returns bcmos_errno
836 *****************************************************************************/
837static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
838 void *msg,
839 acc_term_fsm_event *p_event)
840{
841 bcmos_errno ret;
842 bal_util_msg_ind *ind_msg;
843
844 /* Parameter checks */
845 BUG_ON(NULL == p_acc_term_inst);
846 BUG_ON(NULL == msg);
847 BUG_ON(NULL == p_event);
848
849 ind_msg = (bal_util_msg_ind *)msg;
850
851 ret = ind_msg->status;
852
853 /*
854 * NOTE: AUTO_IND messages are not processed in this function,
855 * so there is no need to consider them in this logic.
856 */
857
858 if(BCM_ERR_OK != ret)
859 {
860 BCM_LOG(ERROR, log_id_access_terminal,
861 " Received an IND message from BAL UTIL (%s) during REMOVING state\n",
862 subsystem_str[bcmbal_sender_get(msg)]);
863 }
864
865 return ret;
866}
867
868/*****************************************************************************/
869/**
870 * @brief The Access terminal FSM state processing function to process an
871 * AUTO IND message from one of the BAL apps.
872 *
873 * @param p_acc_term_inst Pointer to an access terminal instance
874 * @param msg Pointer to a BAL message received from one of
875 * the BAL apps.
876 * @param p_event Pointer to an access terminal event structure
877 *
878 * @returns bcmos_errno
879 *****************************************************************************/
880static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
881 void *msg,
882 acc_term_fsm_event *p_event)
883{
884 bcmos_errno ret = BCM_ERR_OK;
885
886 /* Parameter checks */
887 BUG_ON(NULL == p_acc_term_inst);
888 BUG_ON(NULL == msg);
889 BUG_ON(NULL == p_event);
890
891 BCM_LOG(INFO, log_id_access_terminal,
892 " Received an AUTO IND message from BAL UTIL ()\n");
893
894 return ret;
895}
896
897/*****************************************************************************/
898/**
899 * @brief Interface admin-up command received from the BAL Public API when
900 * the specified interface instance is in the admin-up state.
901 *
902 * @note This handler gets called for both PON and NNI type interfaces
903 *
904 * @param p_interface_inst Pointer to an interface instance
905 * @param msg Pointer to a BAL message received from the BAL Public API
906 *
907 * @returns bcmos_errno
908 *****************************************************************************/
909static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface_inst,
910 void *msg)
911{
912 bcmos_errno ret = BCM_ERR_OK;
913 bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);
914
915 BCM_LOG(INFO, log_id_interface,
916 " Received an INTERFACE admin UP request from BAL API"
917 " - bringing interface (%s%d) UP \n",
918 interface_type_str_get(key->intf_type),
919 key->intf_id);
920
921 do
922 {
923 bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;
924
925 /*
926 * Create a pointer to the interface instance specified by the user
927 */
928
929 /*
930 * If the user has set the min_data_agg_port_id attribute for the interface, then program the resource manager
931 * with this value. It will also be sent to the MAC device for any required programming there.
932 */
933 if ((BCMBAL_INTF_TYPE_PON == key->intf_type) &&
934 (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_interface_inst->api_req_int_obj_info,
935 interface,
936 min_data_agg_port_id)) &&
937 (BCM_ERR_OK != rsc_mgr_access_int_base_alloc_id_set(key->intf_id,
938 p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id)))
939 {
940 BCM_LOG(ERROR, log_id_access_terminal, "Error while setting base agg_port_id (%d) in the resource manager\n",
941 p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id);
942
943 ret = BCM_ERR_INTERNAL;
944 break;
945 }
946
947 /* Change the interface admin state of the "current" interface object to up (this is for reporting) */
948 BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
949 interface,
950 admin_state,
951 BCMBAL_STATE_UP);
952
953 /* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
954 ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_UP);
955
956 if (BCM_ERR_OK != ret)
957 {
958 BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
959 interface,
960 admin_state,
961 old_admin_state);
962
963 BCM_LOG(ERROR, log_id_interface,
964 "Error detected by mac_util_interface_set (%s)\n",
965 bcmos_strerror(ret));
966
967 break;
968 }
969 } while (0);
970
971 if (BCM_ERR_OK != ret)
972 {
973 /* report this error to the API */
974 mgmt_msg_send_balapi_ind(ret,
975 msg,
976 log_id_interface);
977 }
978 else
979 {
980 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
981 }
982
983 return ret;
984 }
985
986/*****************************************************************************/
987/**
988 * @brief Interface admin-up command received from the BAL Public API when
989 * the specified interface instance is in the admin-down state.
990 *
991 * @note This handler gets called for both PON and NNI type interfaces
992 *
993 * @param p_interface_inst Pointer to an interface instance
994 * @param msg Pointer to a BAL message received from the BAL Public API
995 *
996 * @returns bcmos_errno
997 *****************************************************************************/
998static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface_inst,
999 void *msg)
1000{
1001
1002 bcmos_errno ret = BCM_ERR_OK;
1003 bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);
1004
1005 BCM_LOG(INFO, log_id_interface,
1006 " Received an INTERFACE admin DOWN request from BAL API"
1007 " - bringing interface (%s%d) DOWN \n",
1008 interface_type_str_get(key->intf_type),
1009 key->intf_id);
1010
1011 do
1012 {
1013 bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;
1014
1015 /*
1016 * Create a pointer to the interface instance specified by the user
1017 */
1018
1019 /* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
1020 ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_DOWN);
1021
1022 if (BCM_ERR_OK != ret)
1023 {
1024
1025 BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
1026 interface,
1027 admin_state,
1028 old_admin_state);
1029
1030 BCM_LOG(ERROR, log_id_interface,
1031 "Error detected by mac_util_interface_set (%s)\n",
1032 bcmos_strerror(ret));
1033
1034 break;
1035 }
1036
1037 } while (0);
1038
1039 /* Change the interface admin state of the current interface info to down */
1040 BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
1041 interface,
1042 admin_state,
1043 BCMBAL_STATE_DOWN);
1044
1045 /* Check for any error and send an indication immediately in that case */
1046 if (BCM_ERR_OK != ret)
1047 {
1048 /* report this error to the API */
1049 mgmt_msg_send_balapi_ind(ret,
1050 msg,
1051 log_id_interface);
1052
1053 }
1054 else
1055 {
1056 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
1057 }
1058
1059 return ret;
1060
1061}
1062
1063/*****************************************************************************/
1064/**
1065 * @brief The function to process a timer expiry for either the ADDING
1066 * states. This function executes an
1067 * ACC_TERM_FSM_TIMEOUT_EVENT in the FSM state machine.
1068 *
1069 * @param timer - A pointer to the timer instance
1070 * @param pUser - An opaque pointer to an access terminal instance
1071 *
1072 * @returns bcmos_timer_rc == BCMOS_TIMER_OK
1073 */
1074static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser)
1075{
1076 acc_term_fsm_event acc_term_event;
1077
1078 /*
1079 * Stop the indication timer
1080 */
1081 fsm_timer_stop(timer);
1082
1083 BCM_LOG(INFO, log_id_access_terminal,
1084 "timer expiry\n");
1085
1086 /*
1087 * A message pointer is always passed inside the event structure. In this case, it is unused
1088 */
1089 acc_term_event.msg = NULL;
1090 acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_TIMEOUT;
1091
1092 /* Declare this no longer in-progress */
1093 BCMBAL_OBJ_IN_PROGRESS_SET(&(((acc_term_inst *)pUser)->current_acc_term_obj_info), BCMOS_FALSE);
1094
1095 /*
1096 * Run the access terminal FSM to process this event
1097 */
1098 access_terminal_fsm_exec((acc_term_inst *)pUser, &acc_term_event);
1099
1100 return BCMOS_TIMER_OK;
1101
1102}
1103
1104
1105/*****************************************************************************/
1106/**
1107 * @brief The Access terminal FSM state processing a timeout that occurs
1108 * when the FSM is in the ADDING state. In this case, the FSM should
1109 * just go back to the NULL state.
1110 *
1111 * @param p_acc_term_inst Pointer to an access terminal instance
1112 * @param msg Pointer to a BAL message received from the BAL Public API
1113 * @param p_event Pointer to an access terminal event structure
1114 *
1115 * @returns bcmos_errno
1116 *****************************************************************************/
1117static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
1118 void *msg,
1119 acc_term_fsm_event *p_event)
1120{
1121 bcmos_errno ret = BCM_ERR_OK;
1122
1123 BCM_LOG(ERROR, log_id_access_terminal,
1124 "Error: Received a timeout while in the %s state.\n",
1125 acc_term_state_name_get(p_acc_term_inst->fsm_state));
1126
1127
1128 /*
1129 * Send the indication back to the BAL public API here
1130 */
1131 mgmt_msg_send_balapi_ind(BCM_ERR_TIMEOUT,
1132 (void *)&(p_acc_term_inst->current_acc_term_obj_info.hdr.hdr),
1133 log_id_access_terminal);
1134
1135 /*
1136 * Go back to the previous state
1137 */
1138 p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_NULL;
1139 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
1140
1141 return ret;
1142
1143}
1144
1145/*****************************************************************************/
1146/**
1147 * @brief The Access terminal FSM state processing a timeout that occurs
1148 * when the FSM is in the REMOVING state. In this case, the FSM should
1149 * just go back to the ADDED state.
1150 *
1151 * @param p_acc_term_inst Pointer to an access terminal instance
1152 * @param msg Pointer to a BAL message received from the BAL Public API
1153 * @param p_event Pointer to an access terminal event structure
1154 *
1155 * @returns bcmos_errno
1156 *****************************************************************************/
1157static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
1158 void *msg,
1159 acc_term_fsm_event *p_event)
1160{
1161 bcmos_errno ret = BCM_ERR_OK;
1162
1163 BCM_LOG(INFO, log_id_access_terminal,
1164 "Received a timeout while in the %s state. Going back to the ADDED state\n",
1165 acc_term_state_name_get(p_acc_term_inst->fsm_state));
1166
1167 /*
1168 * Go back to the previous state
1169 */
1170 p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDED;
1171
1172 return ret;
1173
1174}
1175
1176/*****************************************************************************/
1177/**
1178 * @brief The function to process a
1179 * message from one of the BAL apps for the specified interface
1180 *
1181 * @param msg Pointer to a BAL message received from one of
1182 * the BAL apps.
1183 *
1184 * @returns bcmos_errno
1185 *****************************************************************************/
1186bcmos_errno process_interface_util_msg(void *msg)
1187{
1188 bcmos_errno ret = BCM_ERR_OK;
1189 uint32_t interface_index = INVALID_INTERFACE_INDEX;
1190 bal_util_msg_ind *ind_msg;
1191 acc_term_interface *p_interface_inst;
1192
1193 /* Parameter checks */
1194 BUG_ON(NULL == msg);
1195
1196 ind_msg = (bal_util_msg_ind *)msg;
1197
1198 /*
1199 * NOTE: AUTO_IND messages are not processed in this function,
1200 * so there is no need to consider them in this logic.
1201 */
1202 BCM_LOG(DEBUG, log_id_access_terminal,
1203 " Received an interface IND message from BAL UTIL (%s)\n",
1204 subsystem_str[bcmbal_sender_get(msg)]);
1205
1206 if (BCM_ERR_OK == ind_msg->status)
1207 {
1208 /* first get the index to the interface array from port id/type */
1209 interface_index = bcmbal_port_type_and_id_to_interface_index(ind_msg->obj_key.if_key.intf_type,
1210 ind_msg->obj_key.if_key.intf_id);
1211
1212 if (interface_index >= INVALID_INTERFACE_INDEX)
1213 {
1214 BCM_LOG(ERROR, log_id_interface,
1215 "INVALID port type/id (%s/%d) to interface index (%d)\n",
1216 interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
1217 ind_msg->obj_key.if_key.intf_id,
1218 interface_index);
1219
1220 ret = BCM_ERR_PARM;
1221 }
1222
1223 p_interface_inst = &(access_terminal_get()->intf_info.interface[interface_index]);
1224
1225 if(BCM_ERR_OK == ret)
1226 {
1227 /* Core calls Switch Utils to set the interface parameters using the applicable SDK call
1228 * If a PON port is being set, then the corresponding direct connect switch port is also
1229 * set along with it
1230 */
1231 ret = sw_util_interface_set(p_interface_inst,
1232 (p_interface_inst->api_req_int_obj_info.data.admin_state == BCMBAL_STATE_DOWN ?
1233 BAL_UTIL_OPER_IF_DOWN : BAL_UTIL_OPER_IF_UP));
1234
1235 if (ret)
1236 {
1237 BCM_LOG(ERROR, log_id_access_terminal,
1238 "sw_util_interface_set(() failed. rc=%s\n", bcmos_strerror(ret));
1239
1240 }
1241 }
1242 else
1243 {
1244 /* Error */
1245 BCM_LOG(ERROR, log_id_interface,
1246 "Bad interface index: interface type/id (%s/%d) (status: %s)\n",
1247 interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
1248 ind_msg->obj_key.if_key.intf_id,
1249 bcmos_strerror(ind_msg->status));
1250 }
1251
1252
1253
1254 if(BCM_ERR_OK == ret)
1255 {
1256 BCM_LOG(DEBUG, log_id_interface,
1257 "Setting interface (%d) to %s\n",
1258 interface_index,
1259 (BCMBAL_STATE_UP == p_interface_inst->api_req_int_obj_info.data.admin_state) ?
1260 "UP" : "DOWN");
1261
1262
1263 /*
1264 * Interface SET function succeeded, so copy the API request into the
1265 * current interface object.
1266 */
1267
1268 bcmbal_interface_object_overlay_w_src_priority(&(p_interface_inst->current_int_obj_info),&(p_interface_inst->api_req_int_obj_info));
1269
1270 /* Set the status of the current interface that we just configured to the requested state (UP or DOWN) */
1271 BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
1272 interface,
1273 oper_status,
1274 bcmbal_get_intf_oper_status_from_admin_state(p_interface_inst->api_req_int_obj_info.data.admin_state));
1275
1276 }
1277 else
1278 {
1279 /* Error */
1280 BCM_LOG(ERROR, log_id_interface,
1281 "Bad response from switch: Interface type/Id: %s/%d (status:%s) \n",
1282 interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
1283 ind_msg->obj_key.if_key.intf_id,
1284 bcmos_strerror(ind_msg->status));
1285
1286 }
1287 }
1288 else
1289 {
1290 /* Error */
1291 BCM_LOG(ERROR, log_id_interface,
1292 "Bad interface indication from MAC (status:%s)\n",
1293 bcmos_strerror(ind_msg->status));
1294 }
1295
1296 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_FALSE);
1297
1298 /*
1299 * Send the indication back to the BAL public API here
1300 */
1301 mgmt_msg_send_balapi_ind(ret,
1302 (void *)&(p_interface_inst->current_int_obj_info.hdr),
1303 log_id_interface);
1304
1305 return ret;
1306
1307}
1308
1309/*****************************************************************************/
1310/**
1311 * @brief The Access terminal FSM function which is executed when an error
1312 * is encountered during FSM processing.
1313 *
1314 * @param p_acc_term_inst Pointer to an access terminal instance
1315 * @param msg Pointer to a BAL message (MAY BE NULL!)
1316 * @param p_event Pointer to an access terminal event structure
1317 *
1318 * @returns bcmos_errno
1319 *****************************************************************************/
1320static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
1321 void *msg,
1322 acc_term_fsm_event *p_event)
1323{
1324 bcmos_errno ret = BCM_ERR_INVALID_OP;
1325
1326 BCM_LOG(ERROR, log_id_access_terminal,
1327 "Error encountered processing FSM - BAD EVENT event:%s, state:%s\n",
1328 acc_term_event_name_get(p_event->event_type),
1329 acc_term_state_name_get(p_acc_term_inst->fsm_state));
1330
1331 return ret;
1332}
1333
1334
1335/*****************************************************************************/
1336/**
1337 * @brief A function called by the core worker thread to process an
1338 * access-terminal object message (SET, GET, CLEAR, STATS) received
1339 * from the BAL Public API.
1340 *
1341 * @param msg_payload Pointer to a BAL message received from the
1342 * BAL Public API.
1343 *
1344 * @returns bcmos_errno
1345 *****************************************************************************/
1346bcmos_errno process_access_terminal_object(void *msg_payload)
1347{
1348
1349 bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;
1350 acc_term_inst *p_access_terminal_inst;
1351 acc_term_fsm_event acc_term_event;
1352 bcmbal_obj_msg_type oper_type;
1353
1354 /* Parameter checks */
1355 BUG_ON(NULL == msg_payload);
1356
1357 BCM_LOG(DEBUG, log_id_access_terminal,
1358 "Processing an access-terminal object\n");
1359
1360 do
1361 {
1362 /*
1363 * Find or create the specified access terminal instance
1364 */
1365 p_access_terminal_inst = access_terminal_get();
1366
1367 oper_type = ((bcmbal_access_terminal_cfg *)msg_payload)->hdr.hdr.type;
1368
1369 /* If the state of the access-terminal is in flux, then reject the SET request */
1370 if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
1371 BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
1372 {
1373 BCM_LOG(ERROR, log_id_access_terminal,
1374 "The access-terminal is in-progress, SETs are not allowed\n");
1375 ret = BCM_ERR_IN_PROGRESS;
1376 break;
1377 }
1378
1379 /* Copy the object in the message into local storage */
1380 memcpy(&p_access_terminal_inst->api_req_acc_term_obj_info,
1381 msg_payload,
1382 sizeof(p_access_terminal_inst->api_req_acc_term_obj_info));
1383
1384 BCM_LOG(DEBUG, log_id_access_terminal,
1385 "access_terminal admin state is: %s\n",
1386 (BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state) ?
1387 "UP" : "DOWN");
1388
1389 /*
1390 * A message pointer is always passed inside the event structure.
1391 */
1392 acc_term_event.msg = msg_payload;
1393
1394 /* SET or GET or ...? */
1395 switch (oper_type)
1396 {
1397 case (BCMBAL_OBJ_MSG_TYPE_SET):
1398 {
1399
1400 BCM_LOG(DEBUG, log_id_access_terminal,
1401 "Processing a access-terminal SET REQ mgmt message\n");
1402
1403 /*
1404 * Check if the mandatory access-terminal attributes have been set
1405 */
1406
1407 do
1408 {
1409
1410 /* The admin state attribute is mandatory */
1411 if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
1412 access_terminal,
1413 admin_state))
1414 {
1415 ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
1416 break;
1417 }
1418
1419 /*set iwf_mode from the global config parameters*/
1420 BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
1421 access_terminal,
1422 iwf_mode,
1423 bcmbal_config_get()->iwf_mode);
1424
1425 /*
1426 * Perform the validation check(s) that the utils require
1427 */
1428 if(BCM_ERR_OK !=
1429 (ret = mac_util_access_terminal_info_validate(&p_access_terminal_inst->api_req_acc_term_obj_info)))
1430 {
1431 break;
1432 }
1433 }
1434 while(0);
1435
1436 /* We respond to the BAL public API backend with a result. We always
1437 * send a complete msg_payload back to the API, but the data portion
1438 * of the object is only relevant when a GET or GET-STATS has been requested.
1439 */
1440 rsp_ret = mgmt_msg_send_balapi_rsp(ret,
1441 msg_payload,
1442 oper_type,
1443 log_id_access_terminal);
1444
1445 if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
1446 {
1447 /* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
1448 ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
1449 break;
1450 }
1451
1452 /* Reflect the admin state of the access-terminal according to the commanded admin state */
1453 BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->current_acc_term_obj_info,
1454 access_terminal,
1455 admin_state,
1456 p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state);
1457
1458 if(BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state)
1459 {
1460
1461 acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP;
1462 }
1463 else
1464 {
1465 acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN;
1466 }
1467
1468 /*
1469 * Run the access terminal FSM to process this event
1470 */
1471 ret = access_terminal_fsm_exec(p_access_terminal_inst, &acc_term_event);
1472 break;
1473
1474 }
1475 case (BCMBAL_OBJ_MSG_TYPE_GET):
1476 {
1477
1478 BCM_LOG(DEBUG, log_id_access_terminal,
1479 "Processing a access-terminal GET REQ mgmt message\n");
1480
1481 p_access_terminal_inst->current_acc_term_obj_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
1482 *((bcmbal_access_terminal_cfg *)msg_payload) = p_access_terminal_inst->current_acc_term_obj_info;
1483
1484 mgmt_msg_send_balapi_rsp(ret,
1485 msg_payload,
1486 oper_type,
1487 log_id_access_terminal);
1488 break;
1489
1490 }
1491 default:
1492 {
1493 BCM_LOG(ERROR, log_id_access_terminal,
1494 "Unsupported operation on access-terminal object (%d)\n",
1495 bcmbal_msg_id_oper_get(msg_payload));
1496
1497 ret = BCM_ERR_NOT_SUPPORTED;
1498
1499 /* We respond to the BAL public API backend with a result. We always
1500 * send a complete msg_payload back to the API, but the data portion
1501 * of the object is only relevant when a GET or GET-STATS has been requested.
1502 */
1503 mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_access_terminal);
1504
1505 break;
1506 }
1507 }
1508 }while(0);
1509
1510 return ret;
1511}
1512
1513/*****************************************************************************/
1514/**
1515 * @brief A function to retrieve an access-terminal instance
1516 *
1517 * @returns acc_term_inst_t* A pointer to the found access-terminal instance,
1518 * or NULL if one is not found.
1519 *****************************************************************************/
1520static acc_term_inst *access_terminal_get(void)
1521{
1522 acc_term_inst *p_acc_term = (acc_term_inst *)NULL;
1523
1524 p_acc_term = &single_access_terminal_instance;
1525
1526 return p_acc_term;
1527}
1528
1529/*****************************************************************************/
1530/**
1531 * @brief A function to retrieve the status of the access-terminal
1532 *
1533 *
1534 * @returns bcmbal_status
1535 *****************************************************************************/
1536bcmbal_status acc_term_status_get(void)
1537{
1538 acc_term_inst *p_acc_term_inst;
1539
1540 p_acc_term_inst = access_terminal_get();
1541
1542 return p_acc_term_inst->current_acc_term_obj_info.data.oper_status;
1543
1544}
1545
1546static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info)
1547{
1548 bcmos_errno ret = BCM_ERR_OK;
1549 tm_sched_inst *p_tm_sched_inst;
1550 bcmbal_tm_sched_key tm_key;
1551 switch(p_interface_info->key.intf_type)
1552 {
1553 case BCMBAL_INTF_TYPE_PON:
1554 {
1555 /*for active pon interface:
1556 ds_tm should be define, - if it is set, validate sched exist and match direction (ds)
1557 if not set - will create auto created tm */
1558 if(BCMBAL_CFG_PROP_IS_SET(p_interface_info,interface,ds_tm))
1559 {
1560 tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
1561 tm_key.id = p_interface_info->data.ds_tm;
1562 p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
1563 if (NULL == p_tm_sched_inst)
1564 {
1565 BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
1566 ret = BCM_ERR_NOENT;
1567 break;
1568 }
1569 ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
1570 if(BCM_ERR_OK != ret)
1571 {
1572 BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
1573 p_interface_info->key.intf_id, tm_key.id);
1574 break;
1575 }
1576 }
1577 else /*auto created sched was removed and no other default sched was set*/
1578 {
1579 BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
1580 ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
1581 break;
1582 }
1583 /* us_tm is optional - if it is set, validate sched exist and match direction (us)*/
1584 if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
1585 {
1586 tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
1587 tm_key.id = p_interface_info->data.us_tm;
1588 p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
1589 if (NULL == p_tm_sched_inst)
1590 {
1591 BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
1592 ret = BCM_ERR_NOENT;
1593 break;
1594 }
1595 ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
1596 if(BCM_ERR_OK != ret)
1597 {
1598 BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
1599 p_interface_info->key.intf_id, tm_key.id);
1600 break;
1601 }
1602 }
1603
1604 }
1605 break;
1606
1607 case BCMBAL_INTF_TYPE_NNI:
1608 {
1609 /*for active nni interface:
1610 us_tm should be define, -
1611 if it is set, validate sched exist and match direction (us)
1612 if not set - will create auto created tm
1613 */
1614 if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
1615 {
1616 tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
1617 tm_key.id = p_interface_info->data.us_tm;
1618 p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
1619 if (NULL == p_tm_sched_inst)
1620 {
1621 BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
1622 ret = BCM_ERR_NOENT;
1623 break;
1624 }
1625
1626 ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
1627 if(BCM_ERR_OK != ret)
1628 {
1629 BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
1630 p_interface_info->key.intf_id, tm_key.id);
1631 break;
1632 }
1633 }
1634 else /*auto created sched was removed and no other default sched was set*/
1635 {
1636 BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
1637 break;
1638 }
1639 /* ds_tm is optional - if it is set, validate sched exist and match direction (ds)*/
1640 if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, ds_tm))
1641 {
1642 tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
1643 tm_key.id = p_interface_info->data.ds_tm;
1644 p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
1645 if (NULL == p_tm_sched_inst)
1646 {
1647 BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
1648 ret = BCM_ERR_NOENT;
1649 break;
1650 }
1651
1652 ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
1653 if(BCM_ERR_OK != ret)
1654 {
1655 BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
1656 p_interface_info->key.intf_id, tm_key.id);
1657 break;
1658 }
1659 }
1660 }
1661 break;
1662
1663 default:
1664 BCM_LOG(ERROR, log_id_interface, "Invalid intf type (%d) in interface key\n",
1665 p_interface_info->key.intf_type);
1666 ret = BCM_ERR_PARM;
1667 }
1668 return ret;
1669}
1670
1671bcmos_errno interface_tm_sched_unset(bcmbal_interface_key intf_key, bcmbal_tm_sched_key sched_key)
1672{
1673 bcmos_errno ret = BCM_ERR_OK;
1674 acc_term_interface *p_acc_term_interface = bcmbal_interface_get(intf_key);
1675 do
1676 {
1677 if(NULL == p_acc_term_interface)
1678 {
1679 BCM_LOG(ERROR, log_id_interface, "no such interface (id = %d dir = %s ) \n",
1680 intf_key.intf_id, interface_type_str_get(intf_key.intf_type));
1681 ret = BCM_ERR_INTERNAL;
1682 break;
1683 }
1684 if (BCMBAL_TM_SCHED_DIR_US == sched_key.dir)
1685 {
1686 BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, us_tm);
1687 }
1688 else
1689 {
1690 BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, ds_tm);
1691 }
1692 }while(0);
1693 return ret;
1694}
1695
1696
1697/*****************************************************************************/
1698/**
1699 * @brief A function to process an interface object message
1700 * (SET, GET, CLEAR, STATS) received from the BAL Public API.
1701 *
1702 * @param msg_payload Pointer to a BAL message received from the
1703 * BAL Public API.
1704 *
1705 * @returns bcmos_errno
1706 *****************************************************************************/
1707bcmos_errno process_interface_object(void *msg_payload)
1708{
1709 bcmos_errno ret = BCM_ERR_OK;
1710
1711 bcmbal_interface_cfg *p_intf_cfg = (bcmbal_interface_cfg *)msg_payload;
1712 bcmbal_interface_key *p_intf_key;
1713 acc_term_inst *p_access_terminal_inst;
1714
1715 bcmbal_interface_cfg *p_api_req_interface_info;
1716 bcmbal_interface_cfg *p_current_interface_info;
1717 uint32_t interface_index = INVALID_INTERFACE_INDEX;
1718 bcmbal_obj_msg_type oper_type;
1719
1720 BCM_LOG(DEBUG, log_id_interface,
1721 "Processing an interface object\n");
1722
1723 do
1724 {
1725 do
1726 {
1727 oper_type = p_intf_cfg->hdr.hdr.type;
1728
1729 /*
1730 * See if the access terminal is active
1731 */
1732 p_access_terminal_inst = access_terminal_get();
1733
1734 if(NULL == p_access_terminal_inst)
1735 {
1736 BCM_LOG(ERROR, log_id_access_terminal,
1737 "the access-terminal is not active\n");
1738
1739 ret = BCM_ERR_NOENT;
1740 break;
1741 }
1742
1743 /* If the state of the access-terminal is in flux, then reject the SET request */
1744 if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
1745 BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
1746 {
1747 BCM_LOG(ERROR, log_id_access_terminal,
1748 "The access-terminal is in-progress, SETs to an interface are not allowed\n");
1749
1750 ret = BCM_ERR_IN_PROGRESS;
1751 break;
1752 }
1753
1754 /*
1755 * Get the interface key from the message
1756 */
1757 p_intf_key = &p_intf_cfg->key;
1758
1759 if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_PON)
1760 {
1761 if(p_intf_key->intf_id > NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
1762 {
1763 BCM_LOG(ERROR, log_id_interface,
1764 "out of range value (%d) detected in interface key for PON\n", p_intf_key->intf_id);
1765
1766 ret = BCM_ERR_RANGE;
1767 break;
1768 }
1769 }
1770 /** @todo check the lower limit also */
1771 else if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_NNI)
1772 {
1773 if( BCMOS_FALSE == bcm_topo_nni_is_valid(p_intf_key->intf_id))
1774 {
1775 BCM_LOG(ERROR, log_id_interface,
1776 "out of range value (%d) detected in interface key for NNI\n", p_intf_key->intf_id);
1777
1778 ret = BCM_ERR_RANGE;
1779 break;
1780 }
1781 }
1782 else
1783 {
1784 BCM_LOG(ERROR, log_id_interface,
1785 "Invalid intf type (%d) in interface key\n", p_intf_key->intf_type);
1786
1787 ret = BCM_ERR_PARM;
1788 break;
1789 }
1790
1791 /*
1792 * Don't accept interface object references when the associated access-terminal is down
1793 *
1794 * Interfaces are not even instantiated internally until the access-terminal object to which
1795 * they belong is instantiated.
1796 */
1797 if(BCMBAL_STATE_DOWN == p_access_terminal_inst->current_acc_term_obj_info.data.admin_state)
1798 {
1799 BCM_LOG(INFO, log_id_interface,
1800 "access terminal admin-state is DOWN\n");
1801
1802 ret = BCM_ERR_INVALID_OP;
1803 break;
1804 }
1805
1806 /* Get the index to the interface array from port id/type */
1807 interface_index = bcmbal_port_type_and_id_to_interface_index (p_intf_key->intf_type, p_intf_key->intf_id);
1808 if (interface_index >= INVALID_INTERFACE_INDEX)
1809 {
1810 BCM_LOG(ERROR, log_id_access_terminal,
1811 "INVALID port type/id (%s/%d) to interface index (%d) for access terminal\n",
1812 interface_type_str_get(p_intf_key->intf_type), p_intf_key->intf_id, interface_index);
1813
1814 ret = BCM_ERR_PARM;
1815 break;
1816 }
1817
1818 /*
1819 * This is a pointer to the "API interface" structure
1820 */
1821 p_api_req_interface_info =
1822 &(p_access_terminal_inst->intf_info.interface[interface_index].api_req_int_obj_info);
1823
1824 /*
1825 * This is a pointer to the "current interface" structure
1826 */
1827 p_current_interface_info =
1828 &(p_access_terminal_inst->intf_info.interface[interface_index].current_int_obj_info);
1829
1830 /* If the state of the interface is in flux, then reject the SET request */
1831 if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
1832 (BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(p_current_interface_info)))
1833 {
1834 BCM_LOG(ERROR, log_id_access_terminal,
1835 "The interface is in-progress, SETs are not allowed\n");
1836 ret = BCM_ERR_IN_PROGRESS;
1837 break;
1838 }
1839
1840 }while(0);
1841
1842 if(BCM_ERR_OK != ret)
1843 {
1844 /* We respond to the BAL public API backend with a result. We always
1845 * send a complete msg_payload back to the API, but the data portion
1846 * of the object is only relevant when a GET or GET-STATS has been requested.
1847 */
1848 mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
1849 break;
1850 }
1851
1852 /*
1853 * Fill in the interface info SET data structure
1854 */
1855 *p_api_req_interface_info = *p_intf_cfg;
1856
1857 BCM_LOG(DEBUG, log_id_interface,
1858 " interface object state from API message is: %d, intf_type: %s intf_id: %d\n",
1859 p_api_req_interface_info->data.admin_state,
1860 interface_type_str_get(p_api_req_interface_info->key.intf_type),
1861 p_api_req_interface_info->key.intf_id);
1862
1863
1864 /* SET or GET or ...? */
1865 switch (oper_type)
1866 {
1867
1868 case (BCMBAL_OBJ_MSG_TYPE_SET):
1869 {
1870 BCM_LOG(DEBUG, log_id_interface,
1871 "Processing an interface SET REQ mgmt message\n");
1872 /*if sched is already set, can not change sched setting using set command, should first delete current sched*/
1873 if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,ds_tm)
1874 && BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,ds_tm))
1875 {
1876 BCM_LOG(ERROR, log_id_interface,
1877 "ds_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
1878 p_current_interface_info->data.ds_tm);
1879 ret = BCM_ERR_ALREADY;
1880 break;
1881 }
1882 if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,us_tm)
1883 && BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,us_tm))
1884 {
1885 BCM_LOG(ERROR, log_id_interface,
1886 "us_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
1887 p_current_interface_info->data.us_tm);
1888 ret = BCM_ERR_ALREADY;
1889 break;
1890 }
1891 /* We respond to the BAL public API backend with a result. We always
1892 * send a complete msg_payload back to the API, but the data portion
1893 * of the object is only relevant when a GET or GET-STATS has been requested.
1894 */
1895 ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
1896
1897 if(BCM_ERR_OK != ret)
1898 {
1899 break;
1900 }
1901
1902 /* If this interface is already up, then just return OK */
1903 if(BCMBAL_STATE_UP == p_api_req_interface_info->data.admin_state)
1904 {
1905 if(BCMBAL_STATUS_UP == p_current_interface_info->data.oper_status)
1906 {
1907 BCM_LOG(DEBUG, log_id_interface,
1908 "=====> Received an interface UP for an already UP interface, returning OK\n");
1909 break;
1910 }
1911
1912 /*validate and set the interface' tm sched*/
1913 bcmbal_interface_object_overlay_w_dst_priority(p_api_req_interface_info,p_current_interface_info);
1914 ret = interface_tm_sched_set(p_api_req_interface_info);
1915 if(BCM_ERR_OK != ret)
1916 {
1917 BCM_LOG(ERROR, log_id_interface,"Could not set the interface tm sched\n");
1918 break;
1919 }
1920 interface_admin_up_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
1921 msg_payload);
1922 }
1923 else
1924 {
1925 if(BCMBAL_STATUS_DOWN == p_current_interface_info->data.oper_status)
1926 {
1927 BCM_LOG(DEBUG, log_id_interface,
1928 "=====> Received an interface DOWN for an already DOWN interface, returning OK\n");
1929
1930 break;
1931 }
1932
1933 interface_admin_dn_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
1934 msg_payload);
1935
1936 }
1937
1938 break;
1939
1940 }
1941 case (BCMBAL_OBJ_MSG_TYPE_GET):
1942 {
1943
1944 BCM_LOG(DEBUG, log_id_interface,
1945 "Processing a interface GET REQ mgmt message\n");
1946
1947 /* We respond to the BAL public API backend with a result. We always
1948 * send a complete msg_payload back to the API, but the data portion
1949 * of the object is only relevant when a GET or GET-STATS has been requested.
1950 */
1951 p_current_interface_info->hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
1952
1953 bcmbal_sub_id_list_u16 sub_term_id_list = {};
1954
1955 BCMBAL_CFG_PROP_CLEAR(p_current_interface_info,
1956 interface,
1957 sub_term_id_list);
1958
1959 /* If the user requested the list of sub_term_ids for this interface,
1960 * and this is a PON interface, then return the list.
1961 */
1962 if(BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,
1963 interface,
1964 sub_term_id_list))
1965 {
1966 if(BCMBAL_INTF_TYPE_PON == p_current_interface_info->key.intf_type)
1967 {
1968
1969 sub_term_id_list_fill(interface_index, &sub_term_id_list);
1970
1971 /* NOTE: The returned list may be empty */
1972 BCMBAL_CFG_PROP_SET(p_current_interface_info,
1973 interface,
1974 sub_term_id_list,
1975 sub_term_id_list);
1976
1977 }
1978 }
1979
1980 *((bcmbal_interface_cfg *)msg_payload) = *p_current_interface_info;
1981
1982 mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
1983
1984 /* Free the temporary list if it was used */
1985 if(sub_term_id_list.val)
1986 {
1987 bcmos_free(sub_term_id_list.val);
1988 }
1989
1990 break;
1991 }
1992 default:
1993 {
1994 BCM_LOG(ERROR, log_id_interface,
1995 "Unsupported operation on interface object (%d)\n",
1996 bcmbal_msg_id_oper_get(msg_payload));
1997
1998 ret = BCM_ERR_NOT_SUPPORTED;
1999
2000 /* We respond to the BAL public API backend with a result. We always
2001 * send a complete msg_payload back to the API, but the data portion
2002 * of the object is only relevant when a GET or GET-STATS has been requested.
2003 */
2004 mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
2005 break;
2006 }
2007
2008 }
2009
2010 }while (0);
2011
2012 return ret;
2013}
2014
2015
2016/*****************************************************************************/
2017/**
2018 * @brief A function called to initialize a single access-terminal instance.
2019 * NOTE: This is called once on startup and NOT for each FSM instance.
2020 *
2021 * @param p_acc_term_inst Pointer to an access terminal instance
2022 *
2023 * @returns void
2024 *****************************************************************************/
2025static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst)
2026{
2027 int ii;
2028 int intf_id;
2029 bcmos_errno ret;
2030
2031 BUG_ON(NULL == p_acc_term_inst);
2032
2033 p_acc_term_inst->current_acc_term_obj_info.key.access_term_id = 0;
2034
2035 BCMBAL_CFG_INIT(&p_acc_term_inst->current_acc_term_obj_info,
2036 access_terminal,
2037 p_acc_term_inst->current_acc_term_obj_info.key);
2038
2039 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
2040 access_terminal,
2041 admin_state,
2042 BCMBAL_STATE_DOWN);
2043
2044 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
2045 access_terminal,
2046 oper_status,
2047 BCMBAL_STATUS_DOWN);
2048
2049 BCMBAL_PROP_SET_PRESENT(&p_acc_term_inst->current_acc_term_obj_info,
2050 access_terminal,
2051 _cfg,
2052 iwf_mode);
2053
2054 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);
2055
2056 {
2057 bcmbal_interface_key key;
2058
2059 intf_id = 0; /* reset the port id to the starting id value for the PON interfaces */
2060
2061 key.intf_type = BCMBAL_INTF_TYPE_PON;
2062
2063 for(ii=0; ii<NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii++)
2064 {
2065
2066 key.intf_id = intf_id;
2067
2068 p_acc_term_inst->intf_info.interface[ii].num_sub_terms_on_int = 0;
2069 TAILQ_INIT(&p_acc_term_inst->intf_info.interface[ii].sub_term_id_list);
2070
2071 BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
2072 interface,
2073 key);
2074
2075 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
2076 interface,
2077 admin_state,
2078 BCMBAL_STATE_DOWN);
2079
2080 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
2081 interface,
2082 oper_status,
2083 BCMBAL_STATUS_DOWN);
2084
2085 ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
2086 if(BCM_ERR_OK != ret)
2087 {
2088 BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for pon if %d", intf_id);
2089 break;
2090 }
2091
2092 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);
2093
2094 intf_id++;
2095 }
2096
2097 intf_id = 0; /* reset the port id to the starting id value for the NNI interfaces */
2098
2099 key.intf_type = BCMBAL_INTF_TYPE_NNI;
2100
2101 for(ii=NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii<(NUM_SUPPORTED_SUBSCRIBER_INTERFACES + bal_config_params.num_nni_ports); ii++)
2102 {
2103
2104 key.intf_id = intf_id;
2105
2106 BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
2107 interface,
2108 key);
2109
2110 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
2111 interface,
2112 admin_state,
2113 BCMBAL_STATE_UP);
2114
2115 BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
2116 interface,
2117 oper_status,
2118 BCMBAL_STATUS_UP);
2119
2120
2121 ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
2122 if(BCM_ERR_OK != ret)
2123 {
2124 BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for nni if %d", intf_id);
2125 break;
2126 }
2127
2128 BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);
2129
2130 intf_id++;
2131 }
2132 }
2133}
2134
2135bcmos_errno bcmbal_interface_sub_term_list_entry_add(bcmbal_subscriber_terminal_key sub_term_key)
2136{
2137 bcmos_errno ret = BCM_ERR_OK;
2138 acc_term_inst *p_access_terminal_inst;
2139 sub_term_id_entry *current_entry;
2140 acc_term_interface *p_interface;
2141
2142 p_access_terminal_inst = access_terminal_get();
2143
2144 do
2145 {
2146 /*
2147 * If the specified access terminal is not active then it's interfaces are down.
2148 */
2149 if(NULL == p_access_terminal_inst)
2150 {
2151 BCM_LOG(ERROR, log_id_access_terminal,
2152 "no such ACTIVE access terminal\n");
2153 ret = BCM_ERR_STATE;
2154 break;
2155 }
2156
2157 p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];
2158
2159 /* Check if the id is already on the list before adding it */
2160 TAILQ_FOREACH(current_entry,
2161 &p_interface->sub_term_id_list,
2162 next)
2163 {
2164 if(current_entry->sub_term_id == sub_term_key.sub_term_id)
2165 {
2166 return BCM_ERR_ALREADY;
2167 }
2168 }
2169
2170 /* Get a new entry and configure it */
2171 current_entry = bcmos_calloc(sizeof(sub_term_id_entry));
2172
2173 if (NULL == current_entry)
2174 {
2175 BCM_LOG(ERROR, log_id_access_terminal,
2176 "No memory available\n");
2177 ret = BCM_ERR_NOMEM;
2178 break;
2179 }
2180
2181 current_entry->sub_term_id = sub_term_key.sub_term_id;
2182
2183 BCM_LOG(INFO, log_id_access_terminal,
2184 "adding sub_term id %u to interface %u\n", sub_term_key.sub_term_id, sub_term_key.intf_id);
2185
2186 /* Save the entry on the list of subscriber-terminal ids on this interface */
2187 TAILQ_INSERT_TAIL(&p_interface->sub_term_id_list,
2188 current_entry, next);
2189
2190 (p_interface->num_sub_terms_on_int)++;
2191
2192 } while (0);
2193
2194 return ret;
2195}
2196
2197bcmos_errno bcmbal_interface_sub_term_list_entry_remove(bcmbal_subscriber_terminal_key sub_term_key)
2198{
2199 bcmos_errno ret = BCM_ERR_NOENT;
2200 acc_term_inst *p_access_terminal_inst;
2201 acc_term_interface *p_interface;
2202 sub_term_id_entry *current_entry, *p_temp_entry;
2203
2204 do
2205 {
2206 p_access_terminal_inst = access_terminal_get();
2207
2208 /*
2209 * If the specified access terminal is not active then it's interfaces are down.
2210 */
2211 if(NULL == p_access_terminal_inst)
2212 {
2213 BCM_LOG(ERROR, log_id_access_terminal,
2214 "no such ACTIVE access terminal\n");
2215 ret = BCM_ERR_STATE;
2216 break;
2217 }
2218
2219 p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];
2220
2221 /* Check if the id is on the list */
2222 TAILQ_FOREACH_SAFE(current_entry,
2223 &p_interface->sub_term_id_list,
2224 next,
2225 p_temp_entry)
2226 {
2227 if(current_entry->sub_term_id == sub_term_key.sub_term_id)
2228 {
2229 /* Remove it from the list of subscriber-terminal ids on this interface */
2230 TAILQ_REMOVE(&p_interface->sub_term_id_list,
2231 current_entry, next);
2232
2233 bcmos_free(current_entry);
2234
2235 (p_interface->num_sub_terms_on_int)--;
2236
2237 ret = BCM_ERR_OK;
2238 break;
2239
2240 }
2241 }
2242 } while (0);
2243
2244 return ret;
2245}
2246
2247static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
2248 bcmbal_sub_id_list_u16 *sub_term_id_list)
2249{
2250 bcmos_errno ret = BCM_ERR_OK;
2251 acc_term_inst *p_acc_term_inst;
2252 sub_term_id_entry *current_entry = NULL;
2253 int ii = 0;
2254
2255 do
2256 {
2257 /*
2258 * See if the access-terminal is active
2259 */
2260 p_acc_term_inst = access_terminal_get();
2261
2262 /*
2263 * If the specified access terminal is not active then it's interfaces are down.
2264 */
2265 if(NULL == p_acc_term_inst)
2266 {
2267 BCM_LOG(ERROR, log_id_access_terminal,
2268 "no such ACTIVE access terminal\n");
2269 ret = BCM_ERR_NOENT;
2270 break;
2271 }
2272
2273 /* Traverse the list of sub_term_ids recorded and fill in the list to be returned */
2274 sub_term_id_list->len = p_acc_term_inst->intf_info.interface[interface_index].num_sub_terms_on_int;
2275 sub_term_id_list->val = bcmos_calloc(sizeof(bcmbal_sub_id) * sub_term_id_list->len);
2276
2277 if (NULL == sub_term_id_list->val)
2278 {
2279 BCM_LOG(ERROR, log_id_access_terminal,
2280 "No memory available\n");
2281 ret = BCM_ERR_NOMEM;
2282 break;
2283 }
2284
2285 TAILQ_FOREACH(current_entry,
2286 &p_acc_term_inst->intf_info.interface[interface_index].sub_term_id_list,
2287 next)
2288 {
2289 BCM_LOG(DEBUG, log_id_access_terminal,
2290 "adding sub_term_id %u to response at array location %u\n",
2291 current_entry->sub_term_id,
2292 ii);
2293 sub_term_id_list->val[ii++] = current_entry->sub_term_id;
2294 }
2295
2296 } while (0);
2297
2298 return ret;
2299}
2300
2301bcmos_errno bcmbal_interface_tm_get(bcmbal_interface_key key, bcmbal_tm_sched_id *id)
2302{
2303 bcmos_errno ret = BCM_ERR_OK;
2304 acc_term_inst *p_acc_term_inst;
2305 uint32_t interface_index = INVALID_INTERFACE_INDEX;
2306
2307 do
2308 {
2309 /* See if the access-terminal is active */
2310 p_acc_term_inst = access_terminal_get();
2311
2312 /* If the specified access terminal is not active then it's interfaces are down. */
2313 if(NULL == p_acc_term_inst)
2314 {
2315 BCM_LOG(ERROR, log_id_access_terminal,"no such ACTIVE access terminal\n");
2316 ret = BCM_ERR_NOT_CONNECTED;
2317 break;
2318 }
2319
2320 /* If the specified access terminal is down, then it's interfaces are down. */
2321 if(BCMBAL_STATE_UP != p_acc_term_inst->current_acc_term_obj_info.data.admin_state)
2322 {
2323 ret = BCM_ERR_NOT_CONNECTED;
2324 break;
2325 }
2326
2327 /* first get the index to the interface array from port id/type */
2328 interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
2329 if (interface_index >= INVALID_INTERFACE_INDEX)
2330 {
2331 BCM_LOG(ERROR, log_id_access_terminal,"INVALID port type/id (%s/%d) to interface index (%d)\n",
2332 interface_type_str_get(key.intf_type), key.intf_id, interface_index);
2333 ret = BCM_ERR_INTERNAL;
2334 break;
2335 }
2336 /* Retrieve the relevany default tm sched of the interface */
2337 if (BCMBAL_INTF_TYPE_NNI == key.intf_type)
2338 {
2339 *id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.us_tm;
2340 }
2341 else /*BCMBAL_INTF_TYPE_PON */
2342 {
2343 *id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.ds_tm;
2344 }
2345 }while(0);
2346
2347 return ret;
2348}
2349
2350
2351/*****************************************************************************/
2352/**
2353 * @brief A function that returns the status of the specified interface object
2354 *
2355 * @param key An interface instance key
2356 *
2357 * @returns bcmbal_state
2358 *****************************************************************************/
2359bcmbal_status bcmbal_interface_status_get(bcmbal_interface_key key)
2360{
2361 bcmbal_state intf_status = BCMBAL_STATUS_DOWN;
2362 acc_term_interface *p_acc_term_interface = bcmbal_interface_get(key);
2363
2364 if(NULL == p_acc_term_interface)
2365 {
2366 BCM_LOG(ERROR, log_id_access_terminal,"no such interface\n");
2367 }
2368 else
2369 {
2370 intf_status = p_acc_term_interface->current_int_obj_info.data.oper_status;
2371 }
2372 return intf_status;
2373}
2374/*****************************************************************************/
2375/**
2376 * @brief A function that returns the interface object
2377 *
2378 * @param key An interface instance key
2379 *
2380 * @returns acc_term_interface *p_acc_term_interface a pointer to the interface object
2381 *****************************************************************************/
2382static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key)
2383{
2384 acc_term_inst *p_acc_term_inst = NULL;
2385 acc_term_interface *p_acc_term_interface = NULL;
2386 uint32_t interface_index = INVALID_INTERFACE_INDEX;
2387
2388 do
2389 {
2390 /*
2391 * See if the access-terminal is active
2392 */
2393 p_acc_term_inst = access_terminal_get();
2394
2395
2396 /*
2397 * If the specified access terminal is not active then it's interfaces are down.
2398 */
2399 if(NULL == p_acc_term_inst)
2400 {
2401 BCM_LOG(ERROR, log_id_access_terminal,
2402 "no such ACTIVE access terminal\n");
2403 break;
2404 }
2405
2406 /*
2407 * Retrieve the interface
2408 */
2409 /* first get the index to the interface array from port id/type */
2410 interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
2411 if (interface_index >= INVALID_INTERFACE_INDEX)
2412 {
2413 BCM_LOG(ERROR, log_id_access_terminal,
2414 "INVALID port type/id (%s/%d) to interface index (%d)\n",
2415 interface_type_str_get(key.intf_type), key.intf_id, interface_index);
2416 break;
2417 }
2418 p_acc_term_interface = &(p_acc_term_inst->intf_info.interface[interface_index]);
2419
2420 }while(0);
2421
2422
2423 return p_acc_term_interface;
2424}
2425
2426static char *interface_type_str_get(bcmbal_intf_type intf_type)
2427{
2428 return intf_type == BCMBAL_INTF_TYPE_NNI ? "NNI" :
2429 intf_type == BCMBAL_INTF_TYPE_PON ? "PON" : "UNKNOWN TYPE";
2430}
2431/*@}*/