| /****************************************************************************** |
| * |
| * <:copyright-BRCM:2016:DUAL/GPL:standard |
| * |
| * Copyright (c) 2016 Broadcom |
| * All Rights Reserved |
| * |
| * Unless you and Broadcom execute a separate written software license |
| * agreement governing use of this software, this software is licensed |
| * to you under the terms of the GNU General Public License version 2 |
| * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| * with the following added to such license: |
| * |
| * As a special exception, the copyright holders of this software give |
| * you permission to link this software with independent modules, and |
| * to copy and distribute the resulting executable under terms of your |
| * choice, provided that you also meet, for each linked independent |
| * module, the terms and conditions of the license of that module. |
| * An independent module is a module which is not derived from this |
| * software. The special exception does not apply to any modifications |
| * of the software. |
| * |
| * Not withstanding the above, under no circumstances may you combine |
| * this software in any way with any other Broadcom software provided |
| * under a license other than the GPL, without Broadcom's express prior |
| * written consent. |
| * |
| * :> |
| * |
| *****************************************************************************/ |
| |
| /** |
| * @file fsm_common.c |
| * @brief Common code to support the BAL access terminal FSMs |
| * |
| * @addtogroup core |
| */ |
| |
| /*@{*/ |
| |
| /*--- project includes ---*/ |
| #include <bcmos_system.h> |
| #include <acc_term_fsm.h> |
| #include <bal_msg.h> |
| #include <bal_api.h> |
| #include "bal_worker.h" |
| #include "bal_mac_util.h" |
| #include "bal_switch_util.h" |
| #include <bal_osmsg.h> |
| #include <fsm_common.h> |
| |
| #ifdef ENABLE_LOG |
| #include <bcm_dev_log.h> |
| #endif |
| |
| |
| /*****************************************************************************/ |
| /** |
| * @brief Send a management message response |
| * |
| * A Worker module function that sends the specified message to the |
| * BAL Public API. |
| * |
| * @param cmd_status The results of the command associated with the message |
| * |
| * @param msg_payload A pointer to the message to be sent |
| * |
| * @param oper_type The operation type of the object in this response |
| * |
| * @param log_id The log id of the calling component |
| * |
| * @returns bcmos_errno |
| * |
| *****************************************************************************/ |
| bcmos_errno mgmt_msg_send_balapi_rsp(bcmos_errno cmd_status, |
| void *msg_payload, |
| bcmbal_obj_msg_type oper_type, |
| dev_log_id log_id) |
| { |
| |
| bcmos_errno ret = BCM_ERR_OK; |
| |
| /* Parameter checks */ |
| BUG_ON(NULL == msg_payload); |
| |
| BCM_LOG(DEBUG, log_id, "sending rsp message to the public api (payload at %p)\n", |
| msg_payload); |
| |
| /* |
| * Send the response back to the BAL Public API backend |
| */ |
| bcmbal_msg_hdr_set(msg_payload, |
| bcmbal_type_major_get(msg_payload), |
| BAL_MSG_TYPE_RSP, |
| BAL_SUBSYSTEM_CORE, |
| bcmbal_msg_id_obj_get(msg_payload), |
| bcmbal_msg_id_oper_get(msg_payload), |
| bcmbal_ex_id_get(msg_payload)); |
| |
| /* Return the command status to the Public API backend */ |
| ((bcmbal_obj *)(msg_payload))->status = cmd_status; |
| |
| ((bcmbal_obj *)(msg_payload))->dir = BCMBAL_OBJ_MSG_DIR_RESPONSE; |
| |
| ((bcmbal_obj *)(msg_payload))->type = oper_type; |
| |
| if(BCM_ERR_OK != cmd_status) |
| { |
| ((bcmbal_obj *)(msg_payload))->presence_mask = 0; |
| } |
| |
| /* Send message, but don't free it. It is still being used by FSM */ |
| if(BCM_ERR_OK != (ret = bcmbal_msg_send(p_bal_core_to_api_queue, msg_payload, BCMOS_MSG_SEND_NO_FREE_ON_ERROR))) |
| { |
| BCM_LOG(ERROR, log_id, "msg_send failed to send rsp to core (error:%s)\n", |
| bcmos_strerror(ret)); |
| } |
| else |
| { |
| BCM_LOG(DEBUG, log_id, "RSP message sent to the public api with status=%s\n", |
| bcmos_strerror(cmd_status)); |
| } |
| |
| return ret; |
| |
| } |
| |
| |
| /*****************************************************************************/ |
| /** |
| * @brief Send a management message indication |
| * |
| * A Worker module function that sends the specified message to the |
| * BAL Public API. |
| * |
| * @param cmd_status The results of the command associated with the message |
| * |
| * @param is_auto_ind Set to BCMOS_TRUE if the indication to be sent is an AUTO IND |
| * |
| * @param msg_payload A pointer to the message to be sent (a BAL object!) (may be NULL) |
| * |
| * @param log_id The log id of the calling component |
| * |
| * @returns bcmos_errno |
| * |
| *****************************************************************************/ |
| static bcmos_errno _mgmt_msg_send_balapi_ind(bcmos_errno cmd_status, |
| bcmos_bool is_auto_ind, |
| void *msg_payload, /* If this is NULL, there is no message body */ |
| dev_log_id log_id) |
| { |
| |
| bcmos_errno ret = BCM_ERR_OK; |
| uint16_t payload_size; |
| void *p_ind_msg; |
| bcmbal_obj_id obj_type; |
| |
| if(NULL == msg_payload) |
| { |
| obj_type = BCMBAL_OBJ_ID_ANY; |
| payload_size = sizeof(bcmbal_obj); |
| } |
| else |
| { |
| switch(((bcmbal_obj *)msg_payload)->obj_type) |
| { |
| case (BCMBAL_OBJ_ID_FLOW): |
| { |
| payload_size = sizeof(bcmbal_flow_cfg); |
| break; |
| } |
| |
| case (BCMBAL_OBJ_ID_ACCESS_TERMINAL): |
| { |
| payload_size = sizeof(bcmbal_access_terminal_cfg); |
| break; |
| } |
| |
| case (BCMBAL_OBJ_ID_INTERFACE): |
| { |
| payload_size = sizeof(bcmbal_interface_cfg); |
| break; |
| } |
| |
| case (BCMBAL_OBJ_ID_SUBSCRIBER_TERMINAL): |
| { |
| payload_size = sizeof(bcmbal_subscriber_terminal_cfg); |
| break; |
| } |
| |
| case (BCMBAL_OBJ_ID_GROUP): |
| { |
| payload_size = sizeof(bcmbal_group_cfg); |
| break; |
| } |
| |
| case (BCMBAL_OBJ_ID_TM_SCHED): |
| { |
| payload_size = sizeof(bcmbal_tm_sched_cfg); |
| break; |
| } |
| |
| case (BCMBAL_OBJ_ID_TM_QUEUE): |
| { |
| payload_size = sizeof(bcmbal_tm_queue_cfg); |
| break; |
| } |
| |
| default: |
| { |
| BCM_LOG(ERROR, log_id, "indication for object (%d) not supported\n", |
| ((bcmbal_obj *)msg_payload)->obj_type); |
| ret = BCM_ERR_PARM; |
| goto out; |
| } |
| } |
| |
| } |
| |
| p_ind_msg = bcmbal_msg_calloc(payload_size); |
| |
| if(NULL == msg_payload) |
| { |
| ((bcmbal_obj *)p_ind_msg)->obj_type = obj_type; |
| } |
| else |
| { |
| memcpy(p_ind_msg, msg_payload, payload_size); |
| } |
| |
| /* |
| * Send the indication back to the BAL Public API backend |
| */ |
| bcmbal_msg_hdr_set(p_ind_msg, |
| BCMBAL_MGMT_API_IND_MSG, |
| (BCMOS_TRUE == is_auto_ind) ? BAL_MSG_TYPE_AUTO_IND : BAL_MSG_TYPE_IND, |
| BAL_SUBSYSTEM_CORE, |
| ((bcmbal_obj *)p_ind_msg)->obj_type, |
| 0, |
| 0); |
| |
| /* Return the command status to the Public API backend */ |
| ((bcmbal_obj *)(p_ind_msg))->status = cmd_status; |
| |
| ((bcmbal_obj *)(p_ind_msg))->type = BCMBAL_OBJ_MSG_TYPE_GET; |
| ((bcmbal_obj *)(p_ind_msg))->dir = BCMBAL_OBJ_MSG_DIR_RESPONSE; |
| |
| BCM_LOG(DEBUG, log_id, "sending IND message to the public api (payload at %p)\n", p_ind_msg); |
| |
| if(BCM_ERR_OK != (ret = bcmbal_msg_send(p_bal_core_to_api_ind_queue, p_ind_msg, BCMOS_MSG_SEND_AUTO_FREE))) |
| { |
| BCM_LOG(ERROR, log_id, "msg_send failed to send IND to public API (%s)\n", bcmos_strerror(ret)); |
| } |
| else |
| { |
| BCM_LOG(DEBUG, log_id, "IND message sent to the public api with status=%s\n", |
| bcmos_strerror(cmd_status)); |
| } |
| |
| out: |
| return ret; |
| |
| } |
| |
| bcmos_errno mgmt_msg_send_balapi_ind(bcmos_errno cmd_status, |
| void *msg_payload, /* If this is NULL, there is no message body */ |
| dev_log_id log_id) |
| { |
| |
| return _mgmt_msg_send_balapi_ind(cmd_status, |
| BCMOS_FALSE, |
| msg_payload, |
| log_id); |
| } |
| |
| bcmos_errno mgmt_msg_send_balapi_auto_ind(bcmos_errno cmd_status, |
| void *msg_payload, /* If this is NULL, there is no message body */ |
| dev_log_id log_id) |
| { |
| |
| return _mgmt_msg_send_balapi_ind(cmd_status, |
| BCMOS_TRUE, |
| msg_payload, |
| log_id); |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * @brief Create and Start the FSM timer |
| * |
| * @param p_timer_inst A pointer to an instance of a timer data structure |
| * |
| * @param p_inst An opaque pointer to an FSM instance to be passed to the timer |
| * expiry handler |
| * |
| * @param p_timer_expiry_handler A timer expiry handler function |
| * |
| * @param delay The delay interval (in mS) for this timer to run before the |
| * expiry handler is called |
| * |
| * @param log_id The log_id to use when logging errors encountered in this |
| * function |
| * |
| * @returns bcmos_errno |
| */ |
| bcmos_errno fsm_timer_start(bcmos_timer *p_timer_inst, |
| void *p_inst, |
| F_bcmos_timer_handler p_timer_expiry_handler, |
| uint32_t delay, /* delay is in mS */ |
| dev_log_id log_id) |
| { |
| |
| bcmos_errno ret = BCM_ERR_OK; |
| bcmos_timer_parm timer_spec; |
| |
| /* Parameter checks */ |
| BUG_ON(p_inst == NULL); |
| BUG_ON(p_timer_expiry_handler == NULL); |
| BUG_ON(p_timer_inst == NULL); |
| |
| |
| /* Create bcm_os timer */ |
| timer_spec.owner = BCMOS_MODULE_ID_WORKER_MGMT; |
| timer_spec.handler = p_timer_expiry_handler; |
| timer_spec.data = (long) p_inst; |
| timer_spec.periodic = BCMOS_FALSE; |
| |
| if (BCM_ERR_OK != bcmos_timer_create(p_timer_inst, &timer_spec)) |
| { |
| BCM_LOG(ERROR, log_id, "Can't create timer for FSM\n"); |
| ret = BCM_ERR_NORES; |
| } |
| else |
| { |
| /* Start the timer. Timer resolution is in uS*/ |
| bcmos_timer_start(p_timer_inst, delay*1000); |
| } |
| |
| return ret; |
| |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * @brief Stop and delete the specified FSM timer |
| * |
| * @param p_timer_inst A pointer to an instance of a timer data structure |
| * |
| */ |
| void fsm_timer_stop(bcmos_timer *p_timer_inst) |
| { |
| /* Parameter checks */ |
| BUG_ON(p_timer_inst == NULL); |
| |
| bcmos_timer_destroy(p_timer_inst); |
| } |
| |
| /*@}*/ |