blob: 8d3b97bccf5ccf466ddb252e486ffdba87cb1533 [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/*
2<:copyright-BRCM:2016:DUAL/GPL:standard
3
4 Broadcom Proprietary and Confidential.(c) 2016 Broadcom
5 All Rights Reserved
6
7Unless you and Broadcom execute a separate written software license
8agreement governing use of this software, this software is licensed
9to you under the terms of the GNU General Public License version 2
10(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
11with 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
22Not withstanding the above, under no circumstances may you combine
23this software in any way with any other Broadcom software provided
24under a license other than the GPL, without Broadcom's express prior
25written consent.
26
27:>
28*/
29
30#include <bcmolt_host_api.h>
31#include "bcmolt_user_appl_onu_tuning.h"
32
33#define ONU_TUNING_TASK_MSG_Q_SIZE 256
34
35typedef struct
36{
37 bcmos_msg os_msg;
38 bcmolt_auto *ind;
39 bcmolt_devid device_id;
40} ot_task_msg;
41
42static bcmolt_onu_tuning_context ot_context[BCMTR_MAX_OLTS];
43
44
45static bcmos_errno onu_tuning_init_task(bcmolt_devid device_id)
46{
47 bcmos_errno rc;
48 bcmos_task_parm task_params = {};
49 snprintf(ot_context[device_id].task.name, sizeof(ot_context[device_id].task.name), "user_appl_onu_tuning%u", device_id);
50 task_params.name = ot_context[device_id].task.name;
51 task_params.priority = TASK_PRIORITY_USER_APPL_ONU_TUNING;
52 task_params.core = BCMOS_CPU_CORE_ANY; /* No CPU affinity */
53 task_params.init_handler = NULL;
54 task_params.data = (long)device_id;
55 rc = bcmos_task_create(&ot_context[device_id].task, &task_params);
56 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcmos_task_create()\n");
57
58 return rc;
59}
60
61static bcmos_errno onu_tuning_init_module(bcmolt_devid device_id)
62{
63 /* This value is used inside bcmolt_onu_tuning_module_init for timer owner */
64 ot_context[device_id].device = device_id;
65 bcmos_module_parm module_params =
66 {
67 .qparm = { .name = "user_appl_onu_tuning",
68 .size = ONU_TUNING_TASK_MSG_Q_SIZE },
69 };
70
71 return bcmos_module_create(BCMOS_MODULE_ID_USER_APPL_ONU_TUNING_DEV0 + device_id, &ot_context[device_id].task, &module_params);
72}
73
74void bcmolt_onu_tuning_appl_init(bcmolt_devid device_id)
75{
76 bcmos_errno err;
77
78#ifdef ENABLE_LOG
79 char log_name[MAX_DEV_LOG_ID_NAME] = {};
80 snprintf(log_name, sizeof(log_name) - 1, "user_appl_onu_tuning%u", device_id);
81 ot_context[device_id].log_id = bcm_dev_log_id_register(log_name, DEV_LOG_LEVEL_DEBUG, DEV_LOG_ID_TYPE_BOTH);
82#endif
83
84 err = bcmos_mutex_create(&ot_context[device_id].mutex, 0, NULL);
85 BUG_ON(err != BCM_ERR_OK);
86
87 err = onu_tuning_init_task(device_id);
88 BUG_ON(err != BCM_ERR_OK);
89
90 err = onu_tuning_init_module(device_id);
91 BUG_ON(err != BCM_ERR_OK);
92
93}
94
95bcmos_errno bcmolt_onu_tuning_appl_start(bcmolt_devid device_id)
96{
97 bcmos_errno ret = BCM_ERR_OK;
98
99 bcmos_mutex_lock(&ot_context[device_id].mutex);
100
101 if (ot_context[device_id].is_running)
102 {
103 BCM_LOG(ERROR, ot_context[device_id].log_id, "ONU tuning application already running on device=%u\n", device_id);
104 ret = BCM_ERR_STATE;
105 goto exit;
106 }
107
108 ot_context[device_id].is_running = BCMOS_TRUE;
109 ot_context[device_id].device = device_id;
110
111 BCM_LOG(INFO, ot_context[device_id].log_id, "ONU tuning application started on device=%u\n", device_id);
112 ret = BCM_ERR_OK;
113
114exit:
115 bcmos_mutex_unlock(&ot_context[device_id].mutex);
116 return ret;
117}
118
119bcmos_errno bcmolt_onu_tuning_appl_stop(bcmolt_devid device_id)
120{
121 bcmos_errno ret;
122
123 bcmos_mutex_lock(&ot_context[device_id].mutex);
124
125 if (!ot_context[device_id].is_running)
126 {
127 ret = BCM_ERR_STATE;
128 goto exit;
129 }
130
131 ot_context[device_id].is_running = BCMOS_FALSE;
132 bcmos_timer_stop(&ot_context[device_id].timer);
133 BCM_LOG(INFO, ot_context[device_id].log_id, "ONU tuning application stopped on device=%u\n", device_id);
134 ret = BCM_ERR_OK;
135
136exit:
137 bcmos_mutex_unlock(&ot_context[device_id].mutex);
138 return ret;
139}
140
141bcmos_bool bcmolt_onu_tuning_appl_is_running(bcmolt_devid device_id)
142{
143 bcmos_bool ret;
144
145 bcmos_mutex_lock(&ot_context[device_id].mutex);
146 ret = ot_context[device_id].is_running;
147 bcmos_mutex_unlock(&ot_context[device_id].mutex);
148
149 return ret;
150}
151
152static bcmos_bool bcmolt_onu_tuning_is_interested(bcmolt_auto *ind)
153{
154 switch (ind->hdr.obj_type)
155 {
156 case BCMOLT_OBJ_ID_XGPON_ONU:
157 switch (ind->hdr.subgroup)
158 {
159 case BCMOLT_XGPON_ONU_AUTO_ID_TUNING_RESPONSE:
160 return BCMOS_TRUE;
161 case BCMOLT_XGPON_ONU_AUTO_ID_ONU_TUNING_IN_COMPLETED:
162 return BCMOS_TRUE;
163 default:
164 break;
165 }
166 break;
167 default:
168 break;
169 }
170
171 return BCMOS_FALSE;
172}
173
174static void bcmolt_onu_tuning_ind_cb(bcmos_module_id module_id, bcmos_msg *os_msg)
175{
176 ot_task_msg *msg = (ot_task_msg *)os_msg;
177 bcmolt_pon_ni pon_ni;
178 bcmolt_pon_onu_id onu_id;
179 bcmolt_auto *ind = msg->ind;
180 bcmos_errno rc;
181
182 switch (msg->ind->hdr.obj_type)
183 {
184 case BCMOLT_OBJ_ID_XGPON_ONU:
185 switch (msg->ind->hdr.subgroup)
186 {
187 case BCMOLT_XGPON_ONU_AUTO_ID_TUNING_RESPONSE:
188 {
189 bcmolt_xgpon_onu_tuning_response *onu_tuning_response = (bcmolt_xgpon_onu_tuning_response *)ind;
190 onu_id = onu_tuning_response->key.onu_id;
191 pon_ni = onu_tuning_response->key.pon_ni;
192
193 if (onu_tuning_response->data.ack == BCMOS_TRUE && onu_tuning_response->data.result == BCMOLT_RESULT_SUCCESS)
194 {
195 BCM_LOG(INFO, ot_context[msg->device_id].log_id, "Indication BCMOLT_XGPON_ONU_AUTO_ID_TUNING_RESPONSE handled: PON:%u ONU:%u target_pon_ni=%u\n", pon_ni, onu_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_ni);
196
197 /* start tuning in onu on target pon id */
198 bcmolt_xgpon_onu_key key = { .pon_ni = ot_context[msg->device_id].onu_db[onu_id].target_pon_ni, .onu_id = onu_id };
199 bcmolt_xgpon_onu_onu_tuning_in onu_tuning_in;
200
201 BCMOLT_OPER_INIT(&onu_tuning_in, xgpon_onu, onu_tuning_in, key);
202 rc = bcmolt_oper_submit(msg->device_id, &onu_tuning_in.hdr);
203 if (rc != BCM_ERR_OK)
204 BCM_LOG(ERROR, ot_context[msg->device_id].log_id, "ONU=%u tuning in to PON=%u failed\n", onu_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_ni);
205 }
206
207 break;
208 }
209 case BCMOLT_XGPON_ONU_AUTO_ID_ONU_TUNING_IN_COMPLETED:
210 {
211 bcmolt_xgpon_onu_onu_tuning_in_completed *onu_tuning_in_completed = (bcmolt_xgpon_onu_onu_tuning_in_completed *)ind;
212 onu_id = onu_tuning_in_completed->key.onu_id;
213 pon_ni = onu_tuning_in_completed->key.pon_ni;
214 if (onu_tuning_in_completed->data.result == BCMOLT_RESULT_SUCCESS)
215 {
216 BCM_LOG(INFO, ot_context[msg->device_id].log_id, "Indication BCMOLT_XGPON_ONU_AUTO_ID_ONU_TUNING_IN_COMPLETED handled: PON:%u ONU:%u\n", pon_ni, onu_id);
217
218 /* start tuning out onu on source pon id */
219 bcmolt_xgpon_onu_key key = { .pon_ni = ot_context[msg->device_id].onu_db[onu_id].source_pon_ni, .onu_id = onu_id };
220 bcmolt_xgpon_onu_onu_tuning_out onu_tuning_out;
221
222 BCMOLT_OPER_INIT(&onu_tuning_out, xgpon_onu, onu_tuning_out, key);
223 BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, target_ds_pon_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_id);
224 BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, target_us_pon_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_id);
225 BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, time_to_switch, 1000);
226 BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, rollback, BCMOS_FALSE);
227 BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, status, BCMOLT_STATUS_OFF);
228 rc = bcmolt_oper_submit(msg->device_id, &onu_tuning_out.hdr);
229 if (rc != BCM_ERR_OK)
230 BCM_LOG(ERROR, ot_context[msg->device_id].log_id, "ONU=%u tuning out from PON=%u failed\n", onu_id, ot_context[msg->device_id].onu_db[onu_id].source_pon_ni);
231 }
232 break;
233 }
234 default:
235 break;
236 }
237 break;
238 default:
239 break;
240 }
241
242 /* free the cloned indication since we're done processing it */
243 bcmolt_msg_free(&msg->ind->hdr);
244 /* free the internal OS message handle */
245 bcmos_free(os_msg);
246}
247
248bcmos_errno bcmolt_onu_tuning_process_ind(bcmolt_devid device_id, bcmolt_auto *ind)
249{
250 bcmos_errno err;
251 bcmolt_msg *ind_clone = NULL;
252
253 /* if the application isn't running, don't listen to any indications */
254 if (!bcmolt_onu_tuning_appl_is_running(device_id))
255 return BCM_ERR_OK;
256
257 /* check to see if we have a handler for this type of indication */
258 if (!bcmolt_onu_tuning_is_interested(ind))
259 return BCM_ERR_OK;
260
261 /* clone the indication into newly-allocated memory so we can handle it after the original message has been freed */
262 err = bcmolt_msg_clone(&ind_clone, &ind->hdr);
263 if (err != BCM_ERR_OK)
264 {
265 BCM_LOG(ERROR, ot_context[device_id].log_id, "Indication clone failed: %s\n", bcmos_strerror(err));
266 return err;
267 }
268
269 /* send the clone to the internal task's message queue */
270 ot_task_msg *msg = bcmos_calloc(sizeof(*msg));
271 if (msg == NULL)
272 {
273 BCM_LOG(ERROR, ot_context[device_id].log_id, "Message calloc failed: %s\n", bcmos_strerror(err));
274 bcmolt_msg_free(ind_clone);
275 return BCM_ERR_NOMEM;
276 }
277 msg->os_msg.handler = bcmolt_onu_tuning_ind_cb;
278 msg->os_msg.release = bcmolt_os_msg_release_cb;
279 msg->device_id = device_id;
280 msg->ind = (bcmolt_auto *)ind_clone;
281
282 err = bcmos_msg_send_to_module(TASK_PRIORITY_USER_APPL_ONU_TUNING + device_id, &msg->os_msg, 0);
283 if (err != BCM_ERR_OK)
284 {
285 BCM_LOG(ERROR, ot_context[device_id].log_id, "Message send failed: %s\n", bcmos_strerror(err));
286 bcmolt_msg_free(ind_clone);
287 return err;
288 }
289
290 return BCM_ERR_OK;
291}
292
293bcmos_errno onu_tuning_update_onu_db (bcmolt_devid device_id, bcmolt_xgpon_onu_id onu_id, bcmolt_pon_ni source_pon_ni, bcmolt_pon_ni target_pon_ni, bcmolt_pon_id target_pon_id, bcmos_bool rollback)
294{
295 bcmos_errno ret;
296 bcmos_mutex_lock(&ot_context[device_id].mutex);
297
298 if (!ot_context[device_id].is_running)
299 {
300 ret = BCM_ERR_STATE;
301 goto exit;
302 }
303 ot_context[device_id].onu_db[onu_id].target_pon_ni = target_pon_ni;
304 ot_context[device_id].onu_db[onu_id].source_pon_ni = source_pon_ni;
305 ot_context[device_id].onu_db[onu_id].target_pon_id = target_pon_id;
306 ot_context[device_id].onu_db[onu_id].rollback = rollback;
307 ret = BCM_ERR_OK;
308
309exit:
310 bcmos_mutex_unlock(&ot_context[device_id].mutex);
311 return ret;
312}