blob: f43e7fb0dcc5ea55f044cf3c06d8451f4393b726 [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_ps.h"
32#include "bcmolt_user_appl_ps_internal.h"
33
34static bcmos_errno ps_handle_ni_los(
35 const bcmolt_ps_global_cfg *global_cfg,
36 const bcmolt_ps_pon *pon,
37 const bcmolt_gpon_ni_los *ind)
38{
39 if (ind->data.status == BCMOLT_STATUS_OFF)
40 {
41 PS_INFO("<%d:%d> LoS alarm cleared\n", pon->device_id, pon->pon_id);
42 return BCM_ERR_OK;
43 }
44
45 PS_INFO("<%d:%d> LoS alarm raised\n", pon->device_id, pon->pon_id);
46
47 if (global_cfg->switch_condition == BCMOLT_PS_SWITCH_CONDITION_MANUAL)
48 {
49 /* don't react to the switch if we're in manual switch mode */
50 return BCM_ERR_OK;
51 }
52 else
53 {
54 return bcmolt_ps_switch_perform(pon);
55 }
56}
57
58static bcmos_errno ps_handle_ni_state_changed(
59 const bcmolt_ps_pon *partner,
60 const bcmolt_gpon_ni_state_change_completed *ind)
61{
62 bcmolt_gpon_ni_key key = { partner->pon_id };
63 bcmolt_gpon_ni_set_pon_state oper;
64
65 BCMOLT_OPER_INIT(&oper, gpon_ni, set_pon_state, key);
66
67 if (ind->data.previous_state == BCMOLT_PON_STATE_INACTIVE &&
68 ind->data.new_state == BCMOLT_PON_STATE_ACTIVE_WORKING)
69 {
70 PS_INFO("%s: activating PON <%d:%d>\n", __FUNCTION__, partner->device_id, key.pon_ni);
71 BCMOLT_OPER_PROP_SET(&oper, gpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_STANDBY);
72 }
73 else if (ind->data.previous_state == BCMOLT_PON_STATE_ACTIVE_WORKING &&
74 ind->data.new_state == BCMOLT_PON_STATE_INACTIVE)
75 {
76 PS_INFO("%s: deactivating PON <%d:%d>\n", __FUNCTION__, partner->device_id, key.pon_ni);
77 BCMOLT_OPER_PROP_SET(&oper, gpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_INACTIVE);
78 }
79 else
80 {
81 /* only change the standby PON's state if we're pre-provisioning the working PON
82 (the switchover is handled separately) */
83 return BCM_ERR_OK;
84 }
85
86 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
87}
88
89static bcmos_errno ps_handle_ni_traffic_resume(
90 const bcmolt_ps_pon *pon,
91 const bcmolt_gpon_ni_protection_switching_traffic_resume *ind)
92{
93 uint32_t after_us = bcmos_timestamp();
94 uint32_t before_us = ps_get_last_switch_start_time_us();
95 uint32_t time_taken_us = (after_us > before_us) ? after_us - before_us : before_us - after_us;
96 const char *traffic_resume_result_str = NULL;
97
98 switch (ind->data.result)
99 {
100 case BCMOLT_TRAFFIC_RESUME_RESULT_SUCCESS:
101 traffic_resume_result_str = "success";
102 break;
103 case BCMOLT_TRAFFIC_RESUME_RESULT_FAILURE:
104 traffic_resume_result_str = "failure";
105 break;
106 case BCMOLT_TRAFFIC_RESUME_RESULT_SUSPECTED_LOS:
107 traffic_resume_result_str = "suspected_los";
108 break;
109 default:
110 break;
111 }
112
113 PS_INFO(
114 "<%d:%d> Traffic resume %s. Time since start of switch: %d ms.\n",
115 pon->device_id,
116 pon->pon_id,
117 traffic_resume_result_str,
118 time_taken_us / 1000);
119
120 return BCM_ERR_OK;
121}
122
123static bcmos_errno ps_handle_ni_onus_ranged(
124 const bcmolt_ps_pon *partner,
125 const bcmolt_gpon_ni_protection_switching_onus_ranged *ind)
126{
127 uint32_t i;
128 bcmos_errno last_err = BCM_ERR_OK;
129
130 /* apply all of the new ONU EQDs to the standby PON */
131 for (i = 0; i < ind->data.onus.len; i++)
132 {
133 bcmolt_gpon_onu_key key = { partner->pon_id, ind->data.onus.val[i].onu_id };
134 bcmolt_gpon_onu_cfg cfg;
135 bcmos_errno err;
136
137 PS_INFO(
138 "%s: updating EQD <%d:%d> ONU %d -> %d\n",
139 __FUNCTION__,
140 partner->device_id,
141 key.pon_ni,
142 key.onu_id,
143 ind->data.onus.val[i].eqd);
144
145 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
146 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, ranging_time, ind->data.onus.val[i].eqd);
147 err = bcmolt_cfg_set(partner->device_id, &cfg.hdr);
148 if (err != BCM_ERR_OK)
149 {
150 PS_ERR("EQD update failed: %s\n", bcmos_strerror(err));
151 last_err = err;
152 }
153 }
154
155 return last_err;
156}
157
158static bcmos_errno ps_handle_onu_ranging_completed(
159 const bcmolt_ps_pon *partner,
160 const bcmolt_gpon_onu_ranging_completed *ind)
161{
162 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
163 bcmolt_gpon_onu_cfg cfg;
164
165 /* only react to success indications */
166 if (ind->data.status != BCMOLT_RESULT_SUCCESS)
167 {
168 return BCM_ERR_OK;
169 }
170
171 PS_INFO(
172 "%s: updating EQD <%d:%d> ONU %d -> %d\n",
173 __FUNCTION__,
174 partner->device_id,
175 key.pon_ni,
176 key.onu_id,
177 ind->data.eqd);
178
179 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
180 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, ranging_time, ind->data.eqd);
181 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
182}
183
184static bcmos_errno ps_handle_onu_key_exchange_completed(
185 const bcmolt_ps_pon *partner,
186 const bcmolt_gpon_onu_key_exchange_completed *ind)
187{
188 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
189 bcmolt_gpon_onu_cfg cfg;
190
191 PS_INFO("%s: updating AES key <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
192
193 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
194 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, aes_encryption_key, ind->data.new_key);
195 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
196}
197
198static bcmos_errno ps_handle_onu_password_authentication_completed(
199 const bcmolt_ps_pon *partner,
200 const bcmolt_gpon_onu_password_authentication_completed *ind)
201{
202 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
203 bcmolt_gpon_onu_cfg cfg;
204
205 /* only react to success indications */
206 if (ind->data.status != BCMOLT_RESULT_SUCCESS)
207 {
208 return BCM_ERR_OK;
209 }
210
211 PS_INFO("%s: updating password <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
212
213 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
214 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, password, ind->data.password);
215 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
216}
217
218static bcmos_errno ps_handle_onu_activation_completed(
219 const bcmolt_ps_pon *partner,
220 const bcmolt_gpon_onu_onu_activation_completed *ind)
221{
222 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
223 bcmolt_gpon_onu_set_onu_state oper;
224
225 /* only react to success indications */
226 if (ind->data.status != BCMOLT_RESULT_SUCCESS)
227 {
228 return BCM_ERR_OK;
229 }
230
231 PS_INFO("%s: activating <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
232
233 BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
234 BCMOLT_OPER_PROP_SET(&oper, gpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
235 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
236}
237
238static bcmos_errno ps_handle_onu_deactivation_completed(
239 const bcmolt_ps_pon *partner,
240 const bcmolt_gpon_onu_onu_deactivation_completed *ind)
241{
242 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
243 bcmolt_gpon_onu_set_onu_state oper;
244
245 /* Note: we react to this indication whether or not the deactivation was successful. Failure indicates that the
246 * ONU didn't respond to the deactivation, but we still remove the ONU from OLT hardware so it must be mirrored. */
247
248 PS_INFO("%s: deactivating <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
249
250 BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
251 BCMOLT_OPER_PROP_SET(&oper, gpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
252 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
253}
254
255static bcmos_errno ps_handle_onu_enable_completed(
256 const bcmolt_ps_pon *partner,
257 const bcmolt_gpon_onu_onu_enable_completed *ind)
258{
259 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
260 bcmolt_gpon_onu_set_onu_state oper;
261
262 /* don't try to mirror broadcast enable/disable */
263 if (key.onu_id == BCMOLT_GPON_ONU_ID_INVALID)
264 {
265 return BCM_ERR_OK;
266 }
267
268 PS_INFO("%s: enabling <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
269
270 BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
271 BCMOLT_OPER_PROP_SET(&oper, gpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_ENABLE);
272 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
273}
274
275static bcmos_errno ps_handle_onu_disable_completed(
276 const bcmolt_ps_pon *partner,
277 const bcmolt_gpon_onu_onu_disable_completed *ind)
278{
279 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
280 bcmolt_gpon_onu_set_onu_state oper;
281
282 /* don't try to mirror broadcast enable/disable */
283 if (key.onu_id == BCMOLT_GPON_ONU_ID_INVALID)
284 {
285 return BCM_ERR_OK;
286 }
287
288 PS_INFO("%s: disabling <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);
289
290 BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
291 BCMOLT_OPER_PROP_SET(&oper, gpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_DISABLE);
292 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
293}
294
295static void ps_alarm_state_init(bcmolt_gpon_onu_alarm_state *alarm_state)
296{
297 alarm_state->losi = BCMOLT_STATUS_NO_CHANGE;
298 alarm_state->lofi = BCMOLT_STATUS_NO_CHANGE;
299 alarm_state->loami = BCMOLT_STATUS_NO_CHANGE;
300 alarm_state->dgi = BCMOLT_STATUS_NO_CHANGE;
301 alarm_state->tiwi = BCMOLT_STATUS_NO_CHANGE;
302 alarm_state->dowi = BCMOLT_STATUS_NO_CHANGE;
303 alarm_state->sufi = BCMOLT_STATUS_NO_CHANGE;
304 alarm_state->sfi = BCMOLT_STATUS_NO_CHANGE;
305 alarm_state->sdi = BCMOLT_STATUS_NO_CHANGE;
306 alarm_state->dfi = BCMOLT_STATUS_NO_CHANGE;
307 alarm_state->loai = BCMOLT_STATUS_NO_CHANGE;
308 alarm_state->loki = BCMOLT_STATUS_NO_CHANGE;
309}
310
311static bcmos_errno ps_handle_onu_alarm(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_onu_alarm *ind)
312{
313 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
314 bcmolt_gpon_onu_cfg cfg;
315 bcmolt_gpon_onu_alarm_state alarm_state;
316
317 ps_alarm_state_init(&alarm_state);
318 alarm_state.losi = ind->data.onu_alarm.losi;
319 alarm_state.lofi = ind->data.onu_alarm.lofi;
320 alarm_state.loami = ind->data.onu_alarm.loami;
321
322 PS_INFO(
323 "%s: updating ONU alarms <%d:%d> ONU %d -> %d/%d/%d\n",
324 __FUNCTION__,
325 partner->device_id,
326 key.pon_ni,
327 key.onu_id,
328 alarm_state.losi,
329 alarm_state.lofi,
330 alarm_state.loami);
331
332 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
333 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
334 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
335}
336
337static bcmos_errno ps_handle_onu_dowi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_dowi *ind)
338{
339 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
340 bcmolt_gpon_onu_cfg cfg;
341 bcmolt_gpon_onu_alarm_state alarm_state;
342
343 PS_INFO(
344 "%s: updating DOWi <%d:%d> ONU %d -> %d (EQD %d)\n",
345 __FUNCTION__,
346 partner->device_id,
347 key.pon_ni,
348 key.onu_id,
349 ind->data.alarm_status,
350 ind->data.new_eqd);
351
352 ps_alarm_state_init(&alarm_state);
353 alarm_state.dowi = ind->data.alarm_status;
354
355 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
356 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
357
358 if (ind->data.alarm_status == BCMOLT_STATUS_ON)
359 {
360 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, ranging_time, ind->data.new_eqd);
361 }
362
363 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
364}
365
366static bcmos_errno ps_handle_onu_sfi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_sfi *ind)
367{
368 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
369 bcmolt_gpon_onu_cfg cfg;
370 bcmolt_gpon_onu_alarm_state alarm_state;
371
372 PS_INFO(
373 "%s: updating SFI <%d:%d> ONU %d -> %d\n",
374 __FUNCTION__,
375 partner->device_id,
376 key.pon_ni,
377 key.onu_id,
378 ind->data.alarm_status);
379
380 ps_alarm_state_init(&alarm_state);
381 alarm_state.sfi = ind->data.alarm_status;
382
383 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
384 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
385 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
386}
387
388static bcmos_errno ps_handle_onu_sdi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_sdi *ind)
389{
390 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
391 bcmolt_gpon_onu_cfg cfg;
392 bcmolt_gpon_onu_alarm_state alarm_state;
393
394 PS_INFO(
395 "%s: updating SDi <%d:%d> ONU %d -> %d\n",
396 __FUNCTION__,
397 partner->device_id,
398 key.pon_ni,
399 key.onu_id,
400 ind->data.alarm_status);
401
402 ps_alarm_state_init(&alarm_state);
403 alarm_state.sdi = ind->data.alarm_status;
404
405 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
406 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
407 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
408}
409
410static bcmos_errno ps_handle_onu_dfi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_dfi *ind)
411{
412 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
413 bcmolt_gpon_onu_cfg cfg;
414 bcmolt_gpon_onu_alarm_state alarm_state;
415
416 PS_INFO(
417 "%s: updating DFi <%d:%d> ONU %d -> %d\n",
418 __FUNCTION__,
419 partner->device_id,
420 key.pon_ni,
421 key.onu_id,
422 ind->data.alarm_status);
423
424 ps_alarm_state_init(&alarm_state);
425 alarm_state.dfi = ind->data.alarm_status;
426
427 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
428 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
429 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
430}
431
432static bcmos_errno ps_handle_onu_sufi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_sufi *ind)
433{
434 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
435 bcmolt_gpon_onu_cfg cfg;
436 bcmolt_gpon_onu_alarm_state alarm_state;
437
438 PS_INFO(
439 "%s: updating SUFi <%d:%d> ONU %d -> %d\n",
440 __FUNCTION__,
441 partner->device_id,
442 key.pon_ni,
443 key.onu_id,
444 ind->data.alarm_status);
445
446 ps_alarm_state_init(&alarm_state);
447 alarm_state.sufi = ind->data.alarm_status;
448
449 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
450 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
451 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
452}
453
454static bcmos_errno ps_handle_onu_loai(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_loai *ind)
455{
456 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
457 bcmolt_gpon_onu_cfg cfg;
458 bcmolt_gpon_onu_alarm_state alarm_state;
459
460 PS_INFO(
461 "%s: updating LOAi <%d:%d> ONU %d -> %d\n",
462 __FUNCTION__,
463 partner->device_id,
464 key.pon_ni,
465 key.onu_id,
466 ind->data.alarm_status);
467
468 ps_alarm_state_init(&alarm_state);
469 alarm_state.loai = ind->data.alarm_status;
470
471 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
472 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
473 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
474}
475
476static bcmos_errno ps_handle_onu_dgi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_dgi *ind)
477{
478 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
479 bcmolt_gpon_onu_cfg cfg;
480 bcmolt_gpon_onu_alarm_state alarm_state;
481
482 PS_INFO(
483 "%s: updating DGi <%d:%d> ONU %d -> %d\n",
484 __FUNCTION__,
485 partner->device_id,
486 key.pon_ni,
487 key.onu_id,
488 ind->data.alarm_status);
489
490 ps_alarm_state_init(&alarm_state);
491 alarm_state.dgi = ind->data.alarm_status;
492
493 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
494 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
495 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
496}
497
498static bcmos_errno ps_handle_onu_tiwi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_tiwi *ind)
499{
500 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
501 bcmolt_gpon_onu_cfg cfg;
502 bcmolt_gpon_onu_alarm_state alarm_state;
503
504 PS_INFO(
505 "%s: updating TIWi <%d:%d> ONU %d -> %d\n",
506 __FUNCTION__,
507 partner->device_id,
508 key.pon_ni,
509 key.onu_id,
510 ind->data.alarm_status);
511
512 ps_alarm_state_init(&alarm_state);
513 alarm_state.tiwi = ind->data.alarm_status;
514
515 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
516 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
517 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
518}
519
520static bcmos_errno ps_handle_onu_loki(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_loki *ind)
521{
522 bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
523 bcmolt_gpon_onu_cfg cfg;
524 bcmolt_gpon_onu_alarm_state alarm_state;
525
526 PS_INFO(
527 "%s: updating LOKi <%d:%d> ONU %d -> %d\n",
528 __FUNCTION__,
529 partner->device_id,
530 key.pon_ni,
531 key.onu_id,
532 ind->data.alarm_status);
533
534 ps_alarm_state_init(&alarm_state);
535 alarm_state.loki = ind->data.alarm_status;
536
537 BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
538 BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
539 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
540}
541
542static bcmos_errno ps_handle_onu_omci_port_configuration_completed(
543 const bcmolt_ps_pon *partner,
544 const bcmolt_gpon_onu_omci_port_id_configuration_completed *ind)
545{
546 bcmolt_gpon_gem_port_key key = { partner->pon_id, ind->data.gem_port };
547 bcmolt_gpon_gem_port_set_state oper;
548
549 BCMOLT_OPER_INIT(&oper, gpon_gem_port, set_state, key);
550
551 if (ind->data.operation == BCMOLT_OMCI_PORT_ID_OPERATION_CONFIGURE)
552 {
553 /* don't react to unsuccessful activations */
554 if (ind->data.status != BCMOLT_RESULT_SUCCESS)
555 {
556 return BCM_ERR_OK;
557 }
558
559 PS_INFO("%s: activating <%d:%d> GEM port ID %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.gem_port_id);
560 BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_ACTIVATE);
561 }
562 else
563 {
564 PS_INFO(
565 "%s: deactivating <%d:%d> GEM port ID %d\n",
566 __FUNCTION__,
567 partner->device_id,
568 key.pon_ni,
569 key.gem_port_id);
570 BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_DEACTIVATE);
571 }
572
573 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
574}
575
576static bcmos_errno ps_handle_mac_table_new_mac(
577 const bcmolt_ps_global_cfg *global_cfg,
578 const bcmolt_ps_pon *partner,
579 const bcmolt_gpon_iwf_mac_table_new_mac *ind)
580{
581 bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
582 bcmolt_gpon_iwf_mac_table_cfg cfg;
583
584 if (!global_cfg->mirror_mac_entries)
585 {
586 return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
587 }
588
589 BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
590 BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, flow_id, ind->data.flow_id);
591
592 if (global_cfg->static_mac_entries)
593 {
594 BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, stat, BCMOS_TRUE);
595 }
596 else
597 {
598 BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, stat, BCMOS_FALSE);
599 }
600
601 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
602}
603
604static bcmos_errno ps_handle_mac_table_mac_aged(
605 const bcmolt_ps_global_cfg *global_cfg,
606 const bcmolt_ps_pon *partner,
607 const bcmolt_gpon_iwf_mac_table_mac_aged *ind)
608{
609 bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
610 bcmolt_gpon_iwf_mac_table_cfg cfg;
611
612 if (!global_cfg->mirror_mac_entries)
613 {
614 return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
615 }
616
617 BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
618 return bcmolt_cfg_clear(partner->device_id, &cfg.hdr);
619}
620
621static bcmos_errno ps_handle_mac_table_mac_move(
622 const bcmolt_ps_global_cfg *global_cfg,
623 const bcmolt_ps_pon *partner,
624 const bcmolt_gpon_iwf_mac_table_mac_move *ind)
625{
626 bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
627 bcmolt_gpon_iwf_mac_table_cfg cfg;
628
629 if (!global_cfg->mirror_mac_entries)
630 {
631 return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
632 }
633
634 BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
635 BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, flow_id, ind->data.new_flow_id);
636 return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
637}
638
639static bcmos_errno ps_handle_alloc_id_configuration_completed(
640 const bcmolt_ps_pon *partner,
641 const bcmolt_gpon_alloc_configuration_completed *ind)
642{
643 bcmolt_gpon_alloc_key key = { partner->pon_id, ind->key.alloc_id };
644 bcmolt_gpon_alloc_set_state oper;
645
646 BCMOLT_OPER_INIT(&oper, gpon_alloc, set_state, key);
647
648 if (ind->data.new_state == BCMOLT_ALLOC_STATE_ACTIVE)
649 {
650 /* don't react to unsuccessful activations */
651 if (ind->data.status != BCMOLT_RESULT_SUCCESS)
652 {
653 return BCM_ERR_OK;
654 }
655
656 PS_INFO("%s: activating <%d:%d> alloc %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.alloc_id);
657 BCMOLT_OPER_PROP_SET(&oper, gpon_alloc, set_state, state, BCMOLT_ALLOC_OPERATION_ACTIVATE);
658 }
659 else if (ind->data.new_state == BCMOLT_ALLOC_STATE_INACTIVE)
660 {
661 PS_INFO("%s: deactivating <%d:%d> alloc %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.alloc_id);
662 BCMOLT_OPER_PROP_SET(&oper, gpon_alloc, set_state, state, BCMOLT_ALLOC_OPERATION_DEACTIVATE);
663 }
664 else /* ind->data.new_state is something else (e.g. unprovisioned, if the alloc was cleared) */
665 {
666 return BCM_ERR_OK;
667 }
668
669 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
670}
671
672static bcmos_errno ps_handle_gem_port_configuration_completed(
673 const bcmolt_ps_pon *partner,
674 const bcmolt_gpon_gem_port_configuration_completed *ind)
675{
676 bcmolt_gpon_gem_port_key key = { partner->pon_id, ind->key.gem_port_id };
677 bcmolt_gpon_gem_port_set_state oper;
678
679 BCMOLT_OPER_INIT(&oper, gpon_gem_port, set_state, key);
680
681 if (ind->data.new_state == BCMOLT_GPON_GEM_PORT_STATE_ACTIVE)
682 {
683 /* don't react to unsuccessful activations */
684 if (ind->data.status != BCMOLT_RESULT_SUCCESS)
685 {
686 return BCM_ERR_OK;
687 }
688
689 PS_INFO("%s: activating <%d:%d> GEM port ID %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.gem_port_id);
690 BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_ACTIVATE);
691 }
692 else if (ind->data.new_state == BCMOLT_GPON_GEM_PORT_STATE_INACTIVE)
693 {
694 PS_INFO(
695 "%s: deactivating <%d:%d> GEM port ID %d\n",
696 __FUNCTION__,
697 partner->device_id,
698 key.pon_ni,
699 key.gem_port_id);
700 BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_DEACTIVATE);
701 }
702 else /* ind->data.new_state is something else (e.g. unprovisioned, if the GEM port was cleared) */
703 {
704 return BCM_ERR_OK;
705 }
706
707 return bcmolt_oper_submit(partner->device_id, &oper.hdr);
708}
709
710bcmos_errno ps_process_ind_gpon(const bcmolt_ps_pon *pon, const bcmolt_auto *ind)
711{
712 bcmos_errno err;
713 bcmolt_ps_pon_state state;
714 bcmolt_ps_pon partner;
715 bcmolt_ps_global_cfg global_cfg;
716
717 err = bcmolt_ps_global_cfg_get(&global_cfg);
718 if (err != BCM_ERR_OK)
719 {
720 return err;
721 }
722
723 if (global_cfg.mirror_mode != BCMOLT_PS_MIRROR_MODE_AUTO &&
724 ind->hdr.subgroup != BCMOLT_GPON_NI_AUTO_ID_LOS)
725 {
726 /* only handle most indications while in mirror mode 'auto', but perform a switchover on LoS in any case */
727 return BCM_ERR_OK;
728 }
729
730 err = bcmolt_ps_pon_state_get(pon, &state, &partner);
731 if (err != BCM_ERR_OK)
732 {
733 return err;
734 }
735
736 if (state != BCMOLT_PS_PON_STATE_WORKING)
737 {
738 return BCM_ERR_OK; /* ignore indications from PONs that aren't protected working */
739 }
740
741 switch (ind->hdr.obj_type)
742 {
743 case BCMOLT_OBJ_ID_GPON_NI:
744 switch (ind->hdr.subgroup)
745 {
746 case BCMOLT_GPON_NI_AUTO_ID_LOS:
747 return ps_handle_ni_los(&global_cfg, pon, ((const bcmolt_gpon_ni_los *)ind));
748 case BCMOLT_GPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED:
749 return ps_handle_ni_state_changed(&partner, ((const bcmolt_gpon_ni_state_change_completed *)ind));
750 case BCMOLT_GPON_NI_AUTO_ID_PROTECTION_SWITCHING_TRAFFIC_RESUME:
751 return ps_handle_ni_traffic_resume(pon, ((const bcmolt_gpon_ni_protection_switching_traffic_resume *)ind));
752 case BCMOLT_GPON_NI_AUTO_ID_PROTECTION_SWITCHING_ONUS_RANGED:
753 return ps_handle_ni_onus_ranged(&partner, ((const bcmolt_gpon_ni_protection_switching_onus_ranged *)ind));
754 default:
755 return BCM_ERR_OK; /* silently ignore all other NI indications */
756 }
757
758 case BCMOLT_OBJ_ID_GPON_ONU:
759 switch (ind->hdr.subgroup)
760 {
761 case BCMOLT_GPON_ONU_AUTO_ID_RANGING_COMPLETED:
762 return ps_handle_onu_ranging_completed(&partner, ((const bcmolt_gpon_onu_ranging_completed *)ind));
763 case BCMOLT_GPON_ONU_AUTO_ID_KEY_EXCHANGE_COMPLETED:
764 return ps_handle_onu_key_exchange_completed(
765 &partner,
766 ((const bcmolt_gpon_onu_key_exchange_completed *)ind));
767 case BCMOLT_GPON_ONU_AUTO_ID_PASSWORD_AUTHENTICATION_COMPLETED:
768 return ps_handle_onu_password_authentication_completed(
769 &partner,
770 ((const bcmolt_gpon_onu_password_authentication_completed *)ind));
771 case BCMOLT_GPON_ONU_AUTO_ID_ONU_ACTIVATION_COMPLETED:
772 return ps_handle_onu_activation_completed(
773 &partner,
774 ((const bcmolt_gpon_onu_onu_activation_completed *)ind));
775 case BCMOLT_GPON_ONU_AUTO_ID_ONU_DEACTIVATION_COMPLETED:
776 return ps_handle_onu_deactivation_completed(
777 &partner,
778 ((const bcmolt_gpon_onu_onu_deactivation_completed *)ind));
779 case BCMOLT_GPON_ONU_AUTO_ID_ONU_ENABLE_COMPLETED:
780 return ps_handle_onu_enable_completed(&partner, ((const bcmolt_gpon_onu_onu_enable_completed *)ind));
781 case BCMOLT_GPON_ONU_AUTO_ID_ONU_DISABLE_COMPLETED:
782 return ps_handle_onu_disable_completed(&partner, ((const bcmolt_gpon_onu_onu_disable_completed *)ind));
783 case BCMOLT_GPON_ONU_AUTO_ID_ONU_ALARM:
784 return ps_handle_onu_alarm(&partner, ((const bcmolt_gpon_onu_onu_alarm *)ind));
785 case BCMOLT_GPON_ONU_AUTO_ID_DOWI:
786 return ps_handle_onu_dowi(&partner, ((const bcmolt_gpon_onu_dowi *)ind));
787 case BCMOLT_GPON_ONU_AUTO_ID_SFI:
788 return ps_handle_onu_sfi(&partner, ((const bcmolt_gpon_onu_sfi *)ind));
789 case BCMOLT_GPON_ONU_AUTO_ID_SDI:
790 return ps_handle_onu_sdi(&partner, ((const bcmolt_gpon_onu_sdi *)ind));
791 case BCMOLT_GPON_ONU_AUTO_ID_DFI:
792 return ps_handle_onu_dfi(&partner, ((const bcmolt_gpon_onu_dfi *)ind));
793 case BCMOLT_GPON_ONU_AUTO_ID_SUFI:
794 return ps_handle_onu_sufi(&partner, ((const bcmolt_gpon_onu_sufi *)ind));
795 case BCMOLT_GPON_ONU_AUTO_ID_LOAI:
796 return ps_handle_onu_loai(&partner, ((const bcmolt_gpon_onu_loai *)ind));
797 case BCMOLT_GPON_ONU_AUTO_ID_DGI:
798 return ps_handle_onu_dgi(&partner, ((const bcmolt_gpon_onu_dgi *)ind));
799 case BCMOLT_GPON_ONU_AUTO_ID_TIWI:
800 return ps_handle_onu_tiwi(&partner, ((const bcmolt_gpon_onu_tiwi *)ind));
801 case BCMOLT_GPON_ONU_AUTO_ID_LOKI:
802 return ps_handle_onu_loki(&partner, ((const bcmolt_gpon_onu_loki *)ind));
803 case BCMOLT_GPON_ONU_AUTO_ID_OMCI_PORT_ID_CONFIGURATION_COMPLETED:
804 return ps_handle_onu_omci_port_configuration_completed(
805 &partner,
806 ((const bcmolt_gpon_onu_omci_port_id_configuration_completed *)ind));
807 default:
808 return BCM_ERR_OK; /* silently ignore all other ONU indications */
809 }
810
811 case BCMOLT_OBJ_ID_GPON_ALLOC:
812 switch (ind->hdr.subgroup)
813 {
814 case BCMOLT_GPON_ALLOC_AUTO_ID_CONFIGURATION_COMPLETED:
815 return ps_handle_alloc_id_configuration_completed(
816 &partner,
817 ((const bcmolt_gpon_alloc_configuration_completed *)ind));
818 default:
819 return BCM_ERR_OK; /* silently ignore all other alloc indications */
820 }
821
822 case BCMOLT_OBJ_ID_GPON_GEM_PORT:
823 switch (ind->hdr.subgroup)
824 {
825 case BCMOLT_GPON_GEM_PORT_AUTO_ID_CONFIGURATION_COMPLETED:
826 return ps_handle_gem_port_configuration_completed(
827 &partner,
828 ((const bcmolt_gpon_gem_port_configuration_completed *)ind));
829 default:
830 return BCM_ERR_OK; /* silently ignore all other GEM port indications */
831 }
832
833 case BCMOLT_OBJ_ID_GPON_IWF_MAC_TABLE:
834 switch (ind->hdr.subgroup)
835 {
836 case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_NEW_MAC:
837 return ps_handle_mac_table_new_mac(
838 &global_cfg,
839 &partner,
840 (const bcmolt_gpon_iwf_mac_table_new_mac *)ind);
841 case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_MAC_AGED:
842 return ps_handle_mac_table_mac_aged(
843 &global_cfg,
844 &partner,
845 (const bcmolt_gpon_iwf_mac_table_mac_aged *)ind);
846 case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_MAC_MOVE:
847 return ps_handle_mac_table_mac_move(
848 &global_cfg,
849 &partner,
850 (const bcmolt_gpon_iwf_mac_table_mac_move *)ind);
851 default:
852 return BCM_ERR_OK; /* silently ignore all other mac table indications */
853 }
854
855 default:
856 return BCM_ERR_NOT_SUPPORTED; /* someone else needs to handle this indication */
857 }
858}
859
860bcmos_errno ps_move_to_standby_gpon(const bcmolt_ps_pon *pon)
861{
862 bcmolt_gpon_ni_set_pon_state set_pon_state;
863 bcmolt_gpon_ni_key key = { (bcmolt_gpon_ni)pon->pon_id };
864
865 BCMOLT_OPER_INIT(&set_pon_state, gpon_ni, set_pon_state, key);
866 BCMOLT_OPER_PROP_SET(&set_pon_state, gpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_STANDBY);
867 return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr);
868}
869
870bcmos_errno ps_move_to_working_gpon(const bcmolt_ps_pon *pon)
871{
872 bcmolt_gpon_ni_set_pon_state set_pon_state;
873 bcmolt_gpon_ni_key key = { (bcmolt_gpon_ni)pon->pon_id };
874
875 BCMOLT_OPER_INIT(&set_pon_state, gpon_ni, set_pon_state, key);
876 BCMOLT_OPER_PROP_SET(&set_pon_state, gpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_WORKING);
877 return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr);
878}