| /* |
| <:copyright-BRCM:2016:DUAL/GPL:standard |
| |
| Broadcom Proprietary and Confidential.(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. |
| |
| :> |
| */ |
| |
| #include <bcmtr_interface.h> |
| #include "bcmolt_api.h" |
| #include "bcmolt_msg_pack.h" |
| |
| system_mode_change_cb sm_change_cb; |
| |
| /** Set configuration |
| * |
| * \param[in] dev Device id |
| * \param[in] cfg Configuration |
| * \returns error code |
| */ |
| bcmos_errno bcmolt_cfg_set(bcmolt_devid dev, bcmolt_cfg *cfg) |
| { |
| bcmos_errno err; |
| bcmolt_presence_mask ro_mask; |
| |
| cfg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| /* Make sure that no attemp is made to set read-only property */ |
| err = bcmolt_get_prop_readonly_mask(cfg->hdr.obj_type, &ro_mask); |
| if (err) |
| { |
| return err; |
| } |
| if ((ro_mask & cfg->hdr.presence_mask)) |
| { |
| cfg->hdr.dir = BCMOLT_MSG_DIR_RESPONSE; |
| cfg->hdr.err = BCM_ERR_READ_ONLY; |
| strncpy(cfg->hdr.err_text, "Read-only fields cannot be set", BCMOLT_MAX_ERR_TEXT_LENGTH); |
| return cfg->hdr.err; |
| } |
| err = bcmtr_call(dev, &cfg->hdr); |
| if ((cfg->hdr.err == BCM_ERR_OK) && |
| (cfg->hdr.obj_type == BCMOLT_OBJ_ID_DEVICE) && |
| (BCMOLT_CFG_PROP_IS_SET((bcmolt_device_cfg*)cfg, device, system_mode))) |
| { |
| bcmolt_system_mode_set(dev, ((bcmolt_device_cfg*)cfg)->data.system_mode); |
| if (NULL != sm_change_cb) |
| { |
| sm_change_cb(dev); |
| } |
| } |
| return err; |
| } |
| |
| /** Get configuration |
| * |
| * \param[in] dev Device id |
| * \param[in] cfg Configuration |
| * \returns error code |
| * The error code can indicate local or remote failure |
| */ |
| bcmos_errno bcmolt_cfg_get(bcmolt_devid dev, bcmolt_cfg *cfg) |
| { |
| cfg->hdr.type = BCMOLT_MSG_TYPE_GET; |
| return bcmtr_call(dev, &cfg->hdr); |
| } |
| |
| /** Clear configuration |
| * |
| * \param[in] dev Device id |
| * \param[in] cfg Configuration |
| * \returns error code |
| * The error code can indicate local or remote failure |
| */ |
| bcmos_errno bcmolt_cfg_clear(bcmolt_devid dev, bcmolt_cfg *cfg) |
| { |
| cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; /* clear is always object-wide */ |
| cfg->hdr.type = BCMOLT_MSG_TYPE_CLEAR; |
| return bcmtr_call(dev, &cfg->hdr); |
| } |
| |
| /** Get statistics |
| * |
| * \param[in] dev Device id |
| * \param[in] stat Configuration |
| * \param[in] flags Flags |
| * \returns error code |
| * The error code can indicate local or remote failure |
| */ |
| bcmos_errno bcmolt_stat_get(bcmolt_devid dev, bcmolt_stat *stat, bcmolt_stat_flags flags) |
| { |
| stat->hdr.type = BCMOLT_MSG_TYPE_GET; |
| if ((flags & BCMOLT_STAT_FLAGS_CLEAR_ON_READ)) |
| { |
| stat->hdr.type |= BCMOLT_MSG_TYPE_CLEAR; |
| } |
| return bcmtr_call(dev, &stat->hdr); |
| } |
| |
| /** Get statistics configuration |
| * |
| * \param[in] dev Device id |
| * \param[in] cfg Configuration |
| * \returns error code |
| * The error code can indicate local or remote failure |
| */ |
| bcmos_errno bcmolt_stat_cfg_get(bcmolt_devid dev, bcmolt_stat_cfg *cfg) |
| { |
| cfg->hdr.type = BCMOLT_MSG_TYPE_GET; |
| cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; |
| return bcmtr_call(dev, &cfg->hdr); |
| } |
| |
| /** Set statistics configuration |
| * |
| * \param[in] dev Device id |
| * \param[in] cfg Configuration |
| * \returns error code |
| * The error code can indicate local or remote failure |
| */ |
| bcmos_errno bcmolt_stat_cfg_set(bcmolt_devid dev, bcmolt_stat_cfg *cfg) |
| { |
| cfg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; |
| return bcmtr_call(dev, &cfg->hdr); |
| } |
| |
| /** Get indication configuration |
| * |
| * \param[in] dev Device id |
| * \param[in] cfg Configuration |
| * \returns error code |
| * The error code can indicate local or remote failure |
| */ |
| bcmos_errno bcmolt_auto_cfg_get(bcmolt_devid dev, bcmolt_auto_cfg *cfg) |
| { |
| cfg->hdr.type = BCMOLT_MSG_TYPE_GET; |
| if (cfg->hdr.presence_mask == 0) |
| { |
| cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; |
| } |
| return bcmtr_call(dev, &cfg->hdr); |
| } |
| |
| /** Set indication configuration |
| * |
| * \param[in] dev Device id |
| * \param[in] cfg Configuration |
| * \returns error code |
| * The error code can indicate local or remote failure |
| */ |
| bcmos_errno bcmolt_auto_cfg_set(bcmolt_devid dev, bcmolt_auto_cfg *cfg) |
| { |
| cfg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| return bcmtr_call(dev, &cfg->hdr); |
| } |
| |
| /** Invoke operation |
| * |
| * \param[in] dev Device id |
| * \param[in] oper Operation |
| * \returns error code |
| */ |
| bcmos_errno bcmolt_oper_submit(bcmolt_devid dev, bcmolt_oper *oper) |
| { |
| oper->hdr.type = BCMOLT_MSG_TYPE_SET; |
| return bcmtr_call(dev, &oper->hdr); |
| } |
| |
| /** Send message to ONU |
| * |
| * \param[in] dev Device id |
| * \param[in] msg Message to be sent |
| * \returns error code |
| */ |
| bcmos_errno bcmolt_proxy_send(bcmolt_devid dev, bcmolt_proxy *msg) |
| { |
| msg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| return bcmtr_call(dev, &msg->hdr); |
| } |
| |
| |
| /* (Un)Register auto/proxy message */ |
| static bcmos_errno bcmolt_rx_cb_set(bcmolt_devid device, bcmolt_mgt_group group, bcmolt_rx_cfg *rx_cfg) |
| { |
| bcmtr_handler_parm tparm = { |
| .group = group, |
| .subgroup = BCMOLT_SUBGROUP_ANY, |
| }; |
| bcmos_errno rc = BCM_ERR_OK; |
| int i; |
| |
| if (!rx_cfg) |
| return BCM_ERR_PARM; |
| |
| tparm.object = rx_cfg->obj_type; |
| tparm.app_cb = rx_cfg->rx_cb; |
| tparm.flags = rx_cfg->flags; |
| if (rx_cfg->flags == BCMOLT_AUTO_FLAGS_DISPATCH) |
| tparm.module = rx_cfg->module; |
| |
| for (i = 0; i < BCMTR_MAX_INSTANCES && !rc; i++) |
| { |
| /* Skip interfaces that are not present in the default mask */ |
| if (rx_cfg->pon_ni_mask && 0 == (rx_cfg->pon_ni_mask & (1 << i))) |
| continue; |
| |
| tparm.instance = i; |
| if (rx_cfg->rx_cb) |
| { |
| /* If registration of specific object - unregister the old handler first */ |
| if (rx_cfg->obj_type != BCMOLT_OBJECT_ANY) |
| bcmtr_msg_handler_unregister(device, &tparm); |
| rc = bcmtr_msg_handler_register(device, &tparm); |
| } |
| else |
| { |
| rc = bcmtr_msg_handler_unregister(device, &tparm); |
| } |
| } |
| return rc; |
| } |
| |
| /* (Un)Register autonomous indication message handler |
| * |
| * \param[in] dev Device id |
| * \param[in] rx_cfg Receive handler configuration |
| * \returns error code |
| */ |
| bcmos_errno bcmolt_auto_rx_cb_set(bcmolt_devid device, bcmolt_rx_cfg *rx_cfg) |
| { |
| return bcmolt_rx_cb_set(device, BCMOLT_MGT_GROUP_AUTO, rx_cfg); |
| } |
| |
| /* (Un)Register proxy message handler |
| * |
| * \param[in] dev Device id |
| * \param[in] rx_cfg Receive handler configuration |
| * \returns error code |
| */ |
| bcmos_errno bcmolt_proxy_rx_cb_set(bcmolt_devid device, bcmolt_rx_cfg *rx_cfg) |
| { |
| return bcmolt_rx_cb_set(device, BCMOLT_MGT_GROUP_PROXY_RX, rx_cfg); |
| } |
| |
| /* Get configuration of multiple objects */ |
| bcmos_errno bcmolt_cfg_get_multi(bcmolt_devid dev, bcmolt_cfg *filter, |
| bcmolt_filter_flags filter_flags, bcmolt_msg_set *msg_set) |
| { |
| int i; |
| |
| /* If message set already includes messages received on previous iteration - release them */ |
| for (i=0; i < msg_set->num_instances; i++) |
| { |
| if (msg_set->msg[i]) |
| { |
| bcmolt_msg_free(msg_set->msg[i]); |
| msg_set->msg[i] = NULL; |
| } |
| } |
| |
| msg_set->filter_flags = filter_flags; |
| msg_set->num_instances = 0; |
| msg_set->more = BCMOS_FALSE; |
| |
| /* Set msg_set in filter message and submit request*/ |
| filter->hdr.msg_set = msg_set; |
| filter->hdr.type = BCMOLT_MSG_TYPE_GET_MULTI; |
| |
| return bcmtr_call(dev, &filter->hdr); |
| } |