Shad Ansari | 2f7f9be | 2017-06-07 13:34:53 -0700 | [diff] [blame^] | 1 | /* |
| 2 | <:copyright-BRCM:2016:DUAL/GPL:standard |
| 3 | |
| 4 | Broadcom Proprietary and Confidential.(c) 2016 Broadcom |
| 5 | All Rights Reserved |
| 6 | |
| 7 | Unless you and Broadcom execute a separate written software license |
| 8 | agreement governing use of this software, this software is licensed |
| 9 | to you under the terms of the GNU General Public License version 2 |
| 10 | (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| 11 | with the following added to such license: |
| 12 | |
| 13 | As a special exception, the copyright holders of this software give |
| 14 | you permission to link this software with independent modules, and |
| 15 | to copy and distribute the resulting executable under terms of your |
| 16 | choice, provided that you also meet, for each linked independent |
| 17 | module, the terms and conditions of the license of that module. |
| 18 | An independent module is a module which is not derived from this |
| 19 | software. The special exception does not apply to any modifications |
| 20 | of the software. |
| 21 | |
| 22 | Not withstanding the above, under no circumstances may you combine |
| 23 | this software in any way with any other Broadcom software provided |
| 24 | under a license other than the GPL, without Broadcom's express prior |
| 25 | written consent. |
| 26 | |
| 27 | :> |
| 28 | */ |
| 29 | |
| 30 | #include <bcmtr_interface.h> |
| 31 | #include "bcmolt_api.h" |
| 32 | #include "bcmolt_msg_pack.h" |
| 33 | |
| 34 | system_mode_change_cb sm_change_cb; |
| 35 | |
| 36 | /** Set configuration |
| 37 | * |
| 38 | * \param[in] dev Device id |
| 39 | * \param[in] cfg Configuration |
| 40 | * \returns error code |
| 41 | */ |
| 42 | bcmos_errno bcmolt_cfg_set(bcmolt_devid dev, bcmolt_cfg *cfg) |
| 43 | { |
| 44 | bcmos_errno err; |
| 45 | bcmolt_presence_mask ro_mask; |
| 46 | |
| 47 | cfg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| 48 | /* Make sure that no attemp is made to set read-only property */ |
| 49 | err = bcmolt_get_prop_readonly_mask(cfg->hdr.obj_type, &ro_mask); |
| 50 | if (err) |
| 51 | { |
| 52 | return err; |
| 53 | } |
| 54 | if ((ro_mask & cfg->hdr.presence_mask)) |
| 55 | { |
| 56 | cfg->hdr.dir = BCMOLT_MSG_DIR_RESPONSE; |
| 57 | cfg->hdr.err = BCM_ERR_READ_ONLY; |
| 58 | strncpy(cfg->hdr.err_text, "Read-only fields cannot be set", BCMOLT_MAX_ERR_TEXT_LENGTH); |
| 59 | return cfg->hdr.err; |
| 60 | } |
| 61 | err = bcmtr_call(dev, &cfg->hdr); |
| 62 | if ((cfg->hdr.err == BCM_ERR_OK) && |
| 63 | (cfg->hdr.obj_type == BCMOLT_OBJ_ID_DEVICE) && |
| 64 | (BCMOLT_CFG_PROP_IS_SET((bcmolt_device_cfg*)cfg, device, system_mode))) |
| 65 | { |
| 66 | bcmolt_system_mode_set(dev, ((bcmolt_device_cfg*)cfg)->data.system_mode); |
| 67 | if (NULL != sm_change_cb) |
| 68 | { |
| 69 | sm_change_cb(dev); |
| 70 | } |
| 71 | } |
| 72 | return err; |
| 73 | } |
| 74 | |
| 75 | /** Get configuration |
| 76 | * |
| 77 | * \param[in] dev Device id |
| 78 | * \param[in] cfg Configuration |
| 79 | * \returns error code |
| 80 | * The error code can indicate local or remote failure |
| 81 | */ |
| 82 | bcmos_errno bcmolt_cfg_get(bcmolt_devid dev, bcmolt_cfg *cfg) |
| 83 | { |
| 84 | cfg->hdr.type = BCMOLT_MSG_TYPE_GET; |
| 85 | return bcmtr_call(dev, &cfg->hdr); |
| 86 | } |
| 87 | |
| 88 | /** Clear configuration |
| 89 | * |
| 90 | * \param[in] dev Device id |
| 91 | * \param[in] cfg Configuration |
| 92 | * \returns error code |
| 93 | * The error code can indicate local or remote failure |
| 94 | */ |
| 95 | bcmos_errno bcmolt_cfg_clear(bcmolt_devid dev, bcmolt_cfg *cfg) |
| 96 | { |
| 97 | cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; /* clear is always object-wide */ |
| 98 | cfg->hdr.type = BCMOLT_MSG_TYPE_CLEAR; |
| 99 | return bcmtr_call(dev, &cfg->hdr); |
| 100 | } |
| 101 | |
| 102 | /** Get statistics |
| 103 | * |
| 104 | * \param[in] dev Device id |
| 105 | * \param[in] stat Configuration |
| 106 | * \param[in] flags Flags |
| 107 | * \returns error code |
| 108 | * The error code can indicate local or remote failure |
| 109 | */ |
| 110 | bcmos_errno bcmolt_stat_get(bcmolt_devid dev, bcmolt_stat *stat, bcmolt_stat_flags flags) |
| 111 | { |
| 112 | stat->hdr.type = BCMOLT_MSG_TYPE_GET; |
| 113 | if ((flags & BCMOLT_STAT_FLAGS_CLEAR_ON_READ)) |
| 114 | { |
| 115 | stat->hdr.type |= BCMOLT_MSG_TYPE_CLEAR; |
| 116 | } |
| 117 | return bcmtr_call(dev, &stat->hdr); |
| 118 | } |
| 119 | |
| 120 | /** Get statistics configuration |
| 121 | * |
| 122 | * \param[in] dev Device id |
| 123 | * \param[in] cfg Configuration |
| 124 | * \returns error code |
| 125 | * The error code can indicate local or remote failure |
| 126 | */ |
| 127 | bcmos_errno bcmolt_stat_cfg_get(bcmolt_devid dev, bcmolt_stat_cfg *cfg) |
| 128 | { |
| 129 | cfg->hdr.type = BCMOLT_MSG_TYPE_GET; |
| 130 | cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; |
| 131 | return bcmtr_call(dev, &cfg->hdr); |
| 132 | } |
| 133 | |
| 134 | /** Set statistics configuration |
| 135 | * |
| 136 | * \param[in] dev Device id |
| 137 | * \param[in] cfg Configuration |
| 138 | * \returns error code |
| 139 | * The error code can indicate local or remote failure |
| 140 | */ |
| 141 | bcmos_errno bcmolt_stat_cfg_set(bcmolt_devid dev, bcmolt_stat_cfg *cfg) |
| 142 | { |
| 143 | cfg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| 144 | cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; |
| 145 | return bcmtr_call(dev, &cfg->hdr); |
| 146 | } |
| 147 | |
| 148 | /** Get indication configuration |
| 149 | * |
| 150 | * \param[in] dev Device id |
| 151 | * \param[in] cfg Configuration |
| 152 | * \returns error code |
| 153 | * The error code can indicate local or remote failure |
| 154 | */ |
| 155 | bcmos_errno bcmolt_auto_cfg_get(bcmolt_devid dev, bcmolt_auto_cfg *cfg) |
| 156 | { |
| 157 | cfg->hdr.type = BCMOLT_MSG_TYPE_GET; |
| 158 | if (cfg->hdr.presence_mask == 0) |
| 159 | { |
| 160 | cfg->hdr.presence_mask = BCMOLT_PRESENCE_MASK_ALL; |
| 161 | } |
| 162 | return bcmtr_call(dev, &cfg->hdr); |
| 163 | } |
| 164 | |
| 165 | /** Set indication configuration |
| 166 | * |
| 167 | * \param[in] dev Device id |
| 168 | * \param[in] cfg Configuration |
| 169 | * \returns error code |
| 170 | * The error code can indicate local or remote failure |
| 171 | */ |
| 172 | bcmos_errno bcmolt_auto_cfg_set(bcmolt_devid dev, bcmolt_auto_cfg *cfg) |
| 173 | { |
| 174 | cfg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| 175 | return bcmtr_call(dev, &cfg->hdr); |
| 176 | } |
| 177 | |
| 178 | /** Invoke operation |
| 179 | * |
| 180 | * \param[in] dev Device id |
| 181 | * \param[in] oper Operation |
| 182 | * \returns error code |
| 183 | */ |
| 184 | bcmos_errno bcmolt_oper_submit(bcmolt_devid dev, bcmolt_oper *oper) |
| 185 | { |
| 186 | oper->hdr.type = BCMOLT_MSG_TYPE_SET; |
| 187 | return bcmtr_call(dev, &oper->hdr); |
| 188 | } |
| 189 | |
| 190 | /** Send message to ONU |
| 191 | * |
| 192 | * \param[in] dev Device id |
| 193 | * \param[in] msg Message to be sent |
| 194 | * \returns error code |
| 195 | */ |
| 196 | bcmos_errno bcmolt_proxy_send(bcmolt_devid dev, bcmolt_proxy *msg) |
| 197 | { |
| 198 | msg->hdr.type = BCMOLT_MSG_TYPE_SET; |
| 199 | return bcmtr_call(dev, &msg->hdr); |
| 200 | } |
| 201 | |
| 202 | |
| 203 | /* (Un)Register auto/proxy message */ |
| 204 | static bcmos_errno bcmolt_rx_cb_set(bcmolt_devid device, bcmolt_mgt_group group, bcmolt_rx_cfg *rx_cfg) |
| 205 | { |
| 206 | bcmtr_handler_parm tparm = { |
| 207 | .group = group, |
| 208 | .subgroup = BCMOLT_SUBGROUP_ANY, |
| 209 | }; |
| 210 | bcmos_errno rc = BCM_ERR_OK; |
| 211 | int i; |
| 212 | |
| 213 | if (!rx_cfg) |
| 214 | return BCM_ERR_PARM; |
| 215 | |
| 216 | tparm.object = rx_cfg->obj_type; |
| 217 | tparm.app_cb = rx_cfg->rx_cb; |
| 218 | tparm.flags = rx_cfg->flags; |
| 219 | if (rx_cfg->flags == BCMOLT_AUTO_FLAGS_DISPATCH) |
| 220 | tparm.module = rx_cfg->module; |
| 221 | |
| 222 | for (i = 0; i < BCMTR_MAX_INSTANCES && !rc; i++) |
| 223 | { |
| 224 | /* Skip interfaces that are not present in the default mask */ |
| 225 | if (rx_cfg->pon_ni_mask && 0 == (rx_cfg->pon_ni_mask & (1 << i))) |
| 226 | continue; |
| 227 | |
| 228 | tparm.instance = i; |
| 229 | if (rx_cfg->rx_cb) |
| 230 | { |
| 231 | /* If registration of specific object - unregister the old handler first */ |
| 232 | if (rx_cfg->obj_type != BCMOLT_OBJECT_ANY) |
| 233 | bcmtr_msg_handler_unregister(device, &tparm); |
| 234 | rc = bcmtr_msg_handler_register(device, &tparm); |
| 235 | } |
| 236 | else |
| 237 | { |
| 238 | rc = bcmtr_msg_handler_unregister(device, &tparm); |
| 239 | } |
| 240 | } |
| 241 | return rc; |
| 242 | } |
| 243 | |
| 244 | /* (Un)Register autonomous indication message handler |
| 245 | * |
| 246 | * \param[in] dev Device id |
| 247 | * \param[in] rx_cfg Receive handler configuration |
| 248 | * \returns error code |
| 249 | */ |
| 250 | bcmos_errno bcmolt_auto_rx_cb_set(bcmolt_devid device, bcmolt_rx_cfg *rx_cfg) |
| 251 | { |
| 252 | return bcmolt_rx_cb_set(device, BCMOLT_MGT_GROUP_AUTO, rx_cfg); |
| 253 | } |
| 254 | |
| 255 | /* (Un)Register proxy message handler |
| 256 | * |
| 257 | * \param[in] dev Device id |
| 258 | * \param[in] rx_cfg Receive handler configuration |
| 259 | * \returns error code |
| 260 | */ |
| 261 | bcmos_errno bcmolt_proxy_rx_cb_set(bcmolt_devid device, bcmolt_rx_cfg *rx_cfg) |
| 262 | { |
| 263 | return bcmolt_rx_cb_set(device, BCMOLT_MGT_GROUP_PROXY_RX, rx_cfg); |
| 264 | } |
| 265 | |
| 266 | /* Get configuration of multiple objects */ |
| 267 | bcmos_errno bcmolt_cfg_get_multi(bcmolt_devid dev, bcmolt_cfg *filter, |
| 268 | bcmolt_filter_flags filter_flags, bcmolt_msg_set *msg_set) |
| 269 | { |
| 270 | int i; |
| 271 | |
| 272 | /* If message set already includes messages received on previous iteration - release them */ |
| 273 | for (i=0; i < msg_set->num_instances; i++) |
| 274 | { |
| 275 | if (msg_set->msg[i]) |
| 276 | { |
| 277 | bcmolt_msg_free(msg_set->msg[i]); |
| 278 | msg_set->msg[i] = NULL; |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | msg_set->filter_flags = filter_flags; |
| 283 | msg_set->num_instances = 0; |
| 284 | msg_set->more = BCMOS_FALSE; |
| 285 | |
| 286 | /* Set msg_set in filter message and submit request*/ |
| 287 | filter->hdr.msg_set = msg_set; |
| 288 | filter->hdr.type = BCMOLT_MSG_TYPE_GET_MULTI; |
| 289 | |
| 290 | return bcmtr_call(dev, &filter->hdr); |
| 291 | } |