blob: ad8d4a7a37b061e4228b5e1b20b53ea6c3b8a417 [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_gpon_utils.h"
32#include <bcmolt_dev_selector.h>
33
34static bcmcli_entry *gpon_utils_cli_dir;
35static bcmcli_entry *gpon_utils_cli_top_dir;
36static bcmos_bool gpon_utils_is_registered;
37
38static bcmos_errno bcmolt_user_appl_gpon_utils_create(bcmcli_entry *top_dir);
39
40#define MAX_GEM_PORTS_FOR_SEND 64
41#define MAX_ONUS_FOR_SEND 64
42#define MAX_PACKET_SIZE 2048
43
44typedef enum
45{
46 GENERATED_PACKET_PATTERN_BYTE_CYCLE,
47 GENERATED_PACKET_PATTERN_WORD_CYCLE,
48 GENERATED_PACKET_PATTERN_CONST
49} generated_packet_pattern;
50
51typedef enum
52{
53 PON_MODE_GPON,
54 PON_MODE_XGPON,
55 PON_MODE_INVALID
56} pon_mode;
57
58static uint8_t saved_packet[MAX_PACKET_SIZE];
59static bcmolt_packet_type saved_packet_type;
60static bcmos_bool saved_packet_calc_crc;
61static uint16_t saved_packet_len = 0;
62
63static void gpon_utils_cli_dir_cli_destroy(void)
64{
65 if (gpon_utils_cli_dir)
66 {
67 bcmcli_token_destroy(gpon_utils_cli_dir);
68 gpon_utils_cli_dir = NULL;
69 }
70}
71
72/* Current device change indication */
73static void bcmolt_user_appl_gpon_utils_device_change_ind(bcmcli_session *session, bcmolt_devid dev)
74{
75 bcmolt_system_mode system_mode;
76 bcmos_errno err = bcmolt_system_mode_get(dev, &system_mode);
77
78 if (err != BCM_ERR_OK)
79 {
80 bcmcli_session_print(session, "Error device Id\n");
81 return;
82 }
83
84 if (system_mode == BCMOLT_SYSTEM_MODE_GPON__16_X ||
85 system_mode == BCMOLT_SYSTEM_MODE_GPON__8_X ||
86 system_mode == BCMOLT_SYSTEM_MODE_GPON__4_X ||
87 system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__8_X ||
88 system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__4_X ||
89 system_mode == BCMOLT_SYSTEM_MODE_XGS__2_X_10_G ||
90 system_mode == BCMOLT_SYSTEM_MODE_NGPON2__2_X_10_G)
91 {
92 bcmcli_session_print(session, "Building gpon_utils CLI for device %d\n", dev);
93
94 err = bcmolt_user_appl_gpon_utils_create(gpon_utils_cli_top_dir);
95 if (err)
96 {
97 bcmcli_session_print(session, "Error building gpon_utils CLI\n");
98 }
99 }
100 else
101 {
102 gpon_utils_cli_dir_cli_destroy();
103 }
104}
105
106static inline pon_mode pon_mode_get(bcmolt_pon_ni pon_id)
107{
108 bcmolt_system_mode system_mode;
109 bcmos_errno err = bcmolt_system_mode_get(current_device, &system_mode);
110 if (err != BCM_ERR_OK)
111 {
112 return PON_MODE_INVALID;
113 }
114
115 if (system_mode == BCMOLT_SYSTEM_MODE_GPON_8_XGPON_4_X_COEXISTENCE)
116 {
117 /* special handling for the 8x GPON / 4x XGPON co-existence mode */
118 return pon_id < 8 ? PON_MODE_XGPON : PON_MODE_GPON;
119 }
120 else if (bcmolt_obj_tag_valid_for_system_mode(system_mode, BCMOLT_OBJ_TAG_GPON))
121 {
122 return PON_MODE_GPON;
123 }
124 else if (bcmolt_obj_tag_valid_for_system_mode(system_mode, BCMOLT_OBJ_TAG_XGPON))
125 {
126 return PON_MODE_XGPON;
127 }
128 else
129 {
130 return PON_MODE_INVALID;
131 }
132}
133
134static bcmos_errno build_packet(bcmcli_session *session, bcmolt_packet_type type)
135{
136 uint16_t i;
137 bcmos_bool calc_crc = (bcmos_bool)bcmcli_find_named_parm(session, "calc_crc")->value.unumber;
138 uint16_t packet_size = (uint16_t)bcmcli_find_named_parm(session, "packet_size")->value.unumber;
139 generated_packet_pattern pattern =
140 (generated_packet_pattern)bcmcli_find_named_parm(session, "pattern")->value.unumber;
141 uint8_t const_value = (uint8_t)bcmcli_find_named_parm(session, "const_value")->value.unumber;
142 uint16_t data_offset;
143
144 /* save packet type / size / CRC flag */
145 saved_packet_type = type;
146 saved_packet_len = packet_size;
147 saved_packet_calc_crc = calc_crc;
148
149 if (type == BCMOLT_PACKET_TYPE_CPU)
150 {
151 bcmos_mac_address eth_da = bcmcli_find_named_parm(session, "eth_da")->value.mac;
152 bcmos_mac_address eth_sa = bcmcli_find_named_parm(session, "eth_sa")->value.mac;
153
154 /* copy destination MAC */
155 memcpy(saved_packet, &eth_da, 6);
156
157 /* copy source MAC */
158 memcpy(&saved_packet[6], &eth_sa, 6);
159
160 /* write EtherType of 0000 */
161 memset(&saved_packet[12], 0, 2);
162
163 /* data starts after EtherType */
164 data_offset = 14;
165 }
166 else
167 {
168 /* fill the entire packet */
169 data_offset = 0;
170 }
171
172 /* fill the rest of the buffer using the specified data pattern */
173 switch (pattern)
174 {
175 case GENERATED_PACKET_PATTERN_BYTE_CYCLE:
176 const_value = 0;
177 for (i = data_offset; i < packet_size; i++)
178 {
179 saved_packet[i] = const_value++;
180 }
181 break;
182 case GENERATED_PACKET_PATTERN_WORD_CYCLE:
183 /* first 4 bytes = 00000000, next 4 = 11111111, next 4 = 22222222, etc */
184 const_value = 0;
185 for (i = data_offset; i < packet_size; i += 4)
186 {
187 uint16_t j;
188 for (j = i; j < i + 4 && j < packet_size; j++)
189 {
190 saved_packet[j] = const_value;
191 }
192 const_value = (const_value == 0xFF) ? 0 : const_value + 0x11;
193 }
194 break;
195 case GENERATED_PACKET_PATTERN_CONST:
196 for (i = data_offset; i < packet_size; i++)
197 {
198 saved_packet[i] = const_value;
199 }
200 break;
201 default:
202 bcmcli_session_print(session, "[Error] Invalid pattern: %u\n", pattern);
203 return BCM_ERR_INTERNAL;
204 }
205
206 return BCM_ERR_OK;
207}
208
209static bcmos_errno build_cpu_packet_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
210{
211 bcmos_errno err = build_packet(session, BCMOLT_PACKET_TYPE_CPU);
212 if (err == BCM_ERR_OK)
213 {
214 bcmcli_session_print(session, "CPU packet buffer saved successfully\n");
215 }
216 else
217 {
218 bcmcli_session_print(session, "[Error] saving CPU packet buffer: %s\n", bcmos_strerror(err));
219 }
220 return err;
221}
222
223static bcmos_errno build_omci_packet_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
224{
225 bcmos_errno err = build_packet(session, BCMOLT_PACKET_TYPE_OMCI);
226 if (err == BCM_ERR_OK)
227 {
228 bcmcli_session_print(session, "OMCI packet buffer saved successfully\n");
229 }
230 else
231 {
232 bcmcli_session_print(session, "[Error] saving OMCI packet buffer: %s\n", bcmos_strerror(err));
233 }
234 return err;
235}
236
237static bcmos_errno send_packet_to_gpon_gem_list(bcmcli_session *session, uint16_t gem_count, bcmolt_gpon_gem_id *gems)
238{
239 uint16_t count = 1;
240 uint16_t i;
241 uint16_t gem_idx;
242 bcmos_errno err;
243 bcmcli_cmd_parm *parm;
244 bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
245 bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
246 bcmolt_gpon_ni_key pon_ni_key = { .pon_ni = pon_ni };
247 bcmolt_gpon_gem_id_list_u8_max_16 gem_port_list;
248 bcmolt_gpon_ni_cpu_packets proxy;
249 bcmolt_u8_list_u32_max_2048 buffer = { .len = saved_packet_len, .val = saved_packet };
250
251 if (saved_packet_len == 0)
252 {
253 bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
254 return BCM_ERR_PARM;
255 }
256
257 parm = bcmcli_find_named_parm(session, "count");
258 if (parm != NULL)
259 {
260 count = (uint16_t)parm->value.unumber;
261 }
262
263 bcmcli_session_print(
264 session,
265 "Sending %u proxy packet%s to %u GEM port%s...\n",
266 count,
267 count == 1 ? "" : "s",
268 gem_count,
269 gem_count == 1 ? "" : "s");
270
271 /* build the proxy API message, except the GEM port list */
272 BCMOLT_PROXY_INIT(&proxy, gpon_ni, cpu_packets, pon_ni_key);
273 BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, packet_type, saved_packet_type);
274 BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, calc_crc, saved_packet_calc_crc);
275 BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, buffer, buffer);
276
277 /* call the proxy API <count> times */
278 for (i = 0; i < count; i++)
279 {
280 /* we may need to split this up into multiple API calls (only 16 GEM ports are allowed per proxy API) */
281 for (gem_idx = 0; gem_idx < gem_count; gem_idx += 16)
282 {
283 gem_port_list.len = MIN(16, gem_count - gem_idx);
284 gem_port_list.val = &gems[gem_idx];
285 BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, gem_port_list, gem_port_list);
286
287 err = bcmolt_proxy_send(device, &proxy.hdr);
288 if (err != BCM_ERR_OK)
289 {
290 bcmcli_session_print(
291 session,
292 "[Error] proxy send: packet index %u GEM index %u: %s\n",
293 i,
294 gem_idx,
295 bcmos_strerror(err));
296 return err;
297 }
298 }
299 }
300
301 bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
302 return BCM_ERR_OK;
303}
304
305static bcmos_errno send_packet_to_xgpon_gem_list(bcmcli_session *session, uint16_t gem_count, bcmolt_xgpon_gem_id *gems)
306{
307 uint16_t count = 1;
308 uint16_t i;
309 uint16_t gem_idx;
310 bcmos_errno err;
311 bcmcli_cmd_parm *parm;
312 bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
313 bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
314 bcmolt_xgpon_ni_key pon_ni_key = { .pon_ni = pon_ni };
315 bcmolt_xgpon_gem_id_list_u8_max_16 gem_port_list;
316 bcmolt_xgpon_ni_cpu_packets proxy;
317 bcmolt_u8_list_u32_max_2048 buffer = { .len = saved_packet_len, .val = saved_packet };
318
319 if (saved_packet_len == 0)
320 {
321 bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
322 return BCM_ERR_PARM;
323 }
324
325 parm = bcmcli_find_named_parm(session, "count");
326 if (parm != NULL)
327 {
328 count = (uint16_t)parm->value.unumber;
329 }
330
331 bcmcli_session_print(
332 session,
333 "Sending %u proxy packet%s to %u GEM port%s...\n",
334 count,
335 count == 1 ? "" : "s",
336 gem_count,
337 gem_count == 1 ? "" : "s");
338
339 /* build the proxy API message, except the GEM port list */
340 BCMOLT_PROXY_INIT(&proxy, xgpon_ni, cpu_packets, pon_ni_key);
341 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, packet_type, saved_packet_type);
342 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, calc_crc, saved_packet_calc_crc);
343 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, buffer, buffer);
344
345 /* call the proxy API <count> times */
346 for (i = 0; i < count; i++)
347 {
348 /* we may need to split this up into multiple API calls (only 16 GEM ports are allowed per proxy API) */
349 for (gem_idx = 0; gem_idx < gem_count; gem_idx += 16)
350 {
351 gem_port_list.len = MIN(16, gem_count - gem_idx);
352 gem_port_list.val = &gems[gem_idx];
353 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, gem_port_list, gem_port_list);
354
355 err = bcmolt_proxy_send(device, &proxy.hdr);
356 if (err != BCM_ERR_OK)
357 {
358 bcmcli_session_print(
359 session,
360 "[Error] proxy send: packet index %u GEM index %u: %s\n",
361 i,
362 gem_idx,
363 bcmos_strerror(err));
364 return err;
365 }
366 }
367 }
368
369 bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
370 return BCM_ERR_OK;
371}
372
373static bcmos_errno send_to_gem_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
374{
375 bcmcli_cmd_parm *gem_parm = bcmcli_find_named_parm(session, "gem");
376 bcmolt_pon_ni pon_id = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
377 uint16_t i;
378 pon_mode mode = pon_mode_get(pon_id);
379
380 if (mode == PON_MODE_GPON)
381 {
382 static bcmolt_gpon_gem_id gem_id_buf[MAX_GEM_PORTS_FOR_SEND];
383 for (i = 0; i < gem_parm->array_size; i++)
384 {
385 gem_id_buf[i] = (bcmolt_gpon_gem_id)gem_parm->values[i].unumber;
386 }
387 return send_packet_to_gpon_gem_list(session, (uint16_t)gem_parm->array_size, gem_id_buf);
388 }
389 else if (mode == PON_MODE_XGPON)
390 {
391 static bcmolt_xgpon_gem_id gem_id_buf[MAX_GEM_PORTS_FOR_SEND];
392 for (i = 0; i < gem_parm->array_size; i++)
393 {
394 gem_id_buf[i] = (bcmolt_xgpon_gem_id)gem_parm->values[i].unumber;
395 }
396 return send_packet_to_xgpon_gem_list(session, (uint16_t)gem_parm->array_size, gem_id_buf);
397 }
398 else
399 {
400 bcmcli_session_print(session, "[Error] Invalid system mode\n");
401 return BCM_ERR_INTERNAL;
402 }
403}
404
405static bcmos_errno send_packet_to_gpon_onu_list(bcmcli_session *session, uint16_t onu_count, bcmolt_gpon_onu_id *onus)
406{
407 uint16_t count = 1;
408 uint16_t i;
409 uint16_t onu_idx;
410 bcmos_errno err;
411 bcmcli_cmd_parm *parm;
412 bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
413 bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
414
415 if (saved_packet_len == 0)
416 {
417 bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
418 return BCM_ERR_PARM;
419 }
420
421 parm = bcmcli_find_named_parm(session, "count");
422 if (parm != NULL)
423 {
424 count = (uint16_t)parm->value.unumber;
425 }
426
427 bcmcli_session_print(
428 session,
429 "Sending %u proxy packet%s to %u ONU%s...\n",
430 count,
431 count == 1 ? "" : "s",
432 onu_count,
433 onu_count == 1 ? "" : "s");
434
435 /* call the proxy API (potentially several times) for each ONU */
436 for (onu_idx = 0; onu_idx < onu_count; onu_idx++)
437 {
438 bcmolt_gpon_onu_key onu_key = { .pon_ni = pon_ni, .onu_id = onus[onu_idx] };
439 bcmolt_u8_list_u32_max_2048 buffer = { .val = saved_packet };
440 bcmolt_gpon_onu_cpu_packets proxy;
441 uint16_t packets_per_proxy;
442
443 /* build the proxy API message, except the buffer/number of packets */
444 BCMOLT_PROXY_INIT(&proxy, gpon_onu, cpu_packets, onu_key);
445 BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, packet_type, saved_packet_type);
446 BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, calc_crc, saved_packet_calc_crc);
447 BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, packet_size, saved_packet_len);
448
449 /* calculate the number of packets we can fit per invocation of the proxy API */
450 packets_per_proxy = MIN(count, 2048 / saved_packet_len);
451 BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, number_of_packets, packets_per_proxy);
452
453 /* prepare the buffer data with several copies of the same packet in a row */
454 for (i = 1; i < packets_per_proxy; i++)
455 {
456 memcpy(&saved_packet[i * saved_packet_len], saved_packet, saved_packet_len);
457 }
458
459 /* call the proxy API enough times to send the requested number of packets */
460 for (i = 0; i < count; i += packets_per_proxy)
461 {
462 uint16_t number_of_packets = MIN(packets_per_proxy, count - i);
463 BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, number_of_packets, number_of_packets);
464
465 buffer.len = number_of_packets * saved_packet_len;
466 BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, buffer, buffer);
467
468 err = bcmolt_proxy_send(device, &proxy.hdr);
469 if (err != BCM_ERR_OK)
470 {
471 bcmcli_session_print(
472 session,
473 "[Error] proxy send: ONU %u packet index %u: %s\n",
474 onus[onu_idx],
475 i,
476 bcmos_strerror(err));
477 return err;
478 }
479 }
480 }
481
482 bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
483 return BCM_ERR_OK;
484}
485
486static bcmos_errno send_packet_to_xgpon_onu_list(bcmcli_session *session, uint16_t onu_count, bcmolt_xgpon_onu_id *onus)
487{
488 uint16_t count = 1;
489 uint16_t i;
490 uint16_t onu_idx;
491 bcmos_errno err;
492 bcmcli_cmd_parm *parm;
493 bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
494 bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
495
496 if (saved_packet_len == 0)
497 {
498 bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
499 return BCM_ERR_PARM;
500 }
501
502 parm = bcmcli_find_named_parm(session, "count");
503 if (parm != NULL)
504 {
505 count = (uint16_t)parm->value.unumber;
506 }
507
508 bcmcli_session_print(
509 session,
510 "Sending %u proxy packet%s to %u ONU%s...\n",
511 count,
512 count == 1 ? "" : "s",
513 onu_count,
514 onu_count == 1 ? "" : "s");
515
516 /* call the proxy API (potentially several times) for each ONU */
517 for (onu_idx = 0; onu_idx < onu_count; onu_idx++)
518 {
519 bcmolt_xgpon_onu_key onu_key = { .pon_ni = pon_ni, .onu_id = onus[onu_idx] };
520 bcmolt_u8_list_u32_max_2048 buffer = { .val = saved_packet };
521 bcmolt_xgpon_onu_cpu_packets proxy;
522 uint16_t packets_per_proxy;
523
524 /* build the proxy API message, except the buffer/number of packets */
525 BCMOLT_PROXY_INIT(&proxy, xgpon_onu, cpu_packets, onu_key);
526 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, packet_type, saved_packet_type);
527 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, calc_crc, saved_packet_calc_crc);
528 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, packet_size, saved_packet_len);
529
530 /* calculate the number of packets we can fit per invocation of the proxy API */
531 packets_per_proxy = MIN(count, 2048 / saved_packet_len);
532 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, number_of_packets, packets_per_proxy);
533
534 /* prepare the buffer data with several copies of the same packet in a row */
535 for (i = 1; i < packets_per_proxy; i++)
536 {
537 memcpy(&saved_packet[i * saved_packet_len], saved_packet, saved_packet_len);
538 }
539
540 /* call the proxy API enough times to send the requested number of packets */
541 for (i = 0; i < count; i += packets_per_proxy)
542 {
543 uint16_t number_of_packets = MIN(packets_per_proxy, count - i);
544 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, number_of_packets, number_of_packets);
545
546 buffer.len = number_of_packets * saved_packet_len;
547 BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, buffer, buffer);
548
549 err = bcmolt_proxy_send(device, &proxy.hdr);
550 if (err != BCM_ERR_OK)
551 {
552 bcmcli_session_print(
553 session,
554 "[Error] proxy send: ONU %u packet index %u: %s\n",
555 onus[onu_idx],
556 i,
557 bcmos_strerror(err));
558 return err;
559 }
560 }
561 }
562
563 bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
564 return BCM_ERR_OK;
565}
566
567static bcmos_errno send_to_onu_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
568{
569 bcmcli_cmd_parm *onu_parm = bcmcli_find_named_parm(session, "onu");
570 bcmolt_pon_ni pon_id = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
571 uint16_t i;
572 pon_mode mode = pon_mode_get(pon_id);
573
574 if (mode == PON_MODE_GPON)
575 {
576 static bcmolt_gpon_onu_id onu_id_buf[MAX_ONUS_FOR_SEND];
577 for (i = 0; i < onu_parm->array_size; i++)
578 {
579 onu_id_buf[i] = (bcmolt_gpon_onu_id)onu_parm->values[i].unumber;
580 }
581 return send_packet_to_gpon_onu_list(session, (uint16_t)onu_parm->array_size, onu_id_buf);
582 }
583 else if (mode == PON_MODE_XGPON)
584 {
585 static bcmolt_xgpon_onu_id onu_id_buf[MAX_ONUS_FOR_SEND];
586 for (i = 0; i < onu_parm->array_size; i++)
587 {
588 onu_id_buf[i] = (bcmolt_xgpon_onu_id)onu_parm->values[i].unumber;
589 }
590 return send_packet_to_xgpon_onu_list(session, (uint16_t)onu_parm->array_size, onu_id_buf);
591 }
592 else
593 {
594 bcmcli_session_print(session, "[Error] Invalid system mode\n");
595 return BCM_ERR_STATE;
596 }
597}
598
599static void dump_saved_mac(bcmcli_session *session, uint16_t offset)
600{
601 uint16_t i;
602 for (i = 0; i < 6; i++)
603 {
604 if (i != 0)
605 {
606 bcmcli_session_print(session, ":");
607 }
608 bcmcli_session_print(session, "%02X", saved_packet[offset + i]);
609 }
610}
611
612static bcmos_errno dump_packet_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
613{
614 uint16_t i;
615 uint16_t data_offset;
616
617 if (saved_packet_len == 0)
618 {
619 bcmcli_session_print(session, "No packet has been built yet\n");
620 return BCM_ERR_OK;
621 }
622
623 bcmcli_session_print(session, "Saved packet parameters:\n");
624 bcmcli_session_print(session, " Type: %s\n", saved_packet_type == BCMOLT_PACKET_TYPE_CPU ? "CPU" : "OMCI");
625 bcmcli_session_print(session, " Length: %u\n", saved_packet_len);
626 bcmcli_session_print(session, " Auto-calculate CRC: %s\n", saved_packet_calc_crc ? "yes" : "no");
627
628 if (saved_packet_type == BCMOLT_PACKET_TYPE_CPU)
629 {
630 bcmcli_session_print(session, " Ethernet DA: ");
631 dump_saved_mac(session, 0);
632 bcmcli_session_print(session, "\n");
633
634 bcmcli_session_print(session, " Ethernet SA: ");
635 dump_saved_mac(session, 6);
636 bcmcli_session_print(session, "\n");
637
638 bcmcli_session_print(session, " EtherType: 0x%02X%02X\n", saved_packet[12], saved_packet[13]);
639 data_offset = 14;
640 }
641 else
642 {
643 data_offset = 0;
644 }
645
646 bcmcli_session_print(session, "Data bytes (starting at offset %u):", data_offset);
647 for (i = data_offset; i < saved_packet_len; i++)
648 {
649 if ((i - data_offset) % 16 == 0)
650 {
651 bcmcli_session_print(session, "\n ");
652 }
653 else
654 {
655 bcmcli_session_print(session, " ");
656 }
657 bcmcli_session_print(session, "%02X", saved_packet[i]);
658 }
659 bcmcli_session_print(session, "\n");
660
661 return BCM_ERR_OK;
662}
663
664bcmos_errno bcmolt_user_appl_gpon_utils_init(bcmcli_entry *top_dir)
665{
666 bcmos_errno err = BCM_ERR_OK;
667
668 if (!gpon_utils_is_registered)
669 {
670 gpon_utils_is_registered = BCMOS_TRUE;
671
672 /* Subscribe for device change indication */
673 err = bcmolt_dev_sel_ind_register(bcmolt_user_appl_gpon_utils_device_change_ind);
674 }
675 return err ? err : bcmolt_user_appl_gpon_utils_create(top_dir);
676}
677
678static bcmos_errno bcmolt_user_appl_gpon_utils_create(bcmcli_entry *top_dir)
679{
680 static bcmcli_enum_val generated_packet_pattern_table[] =
681 {
682 { .name = "byte_cycle", .val = GENERATED_PACKET_PATTERN_BYTE_CYCLE },
683 { .name = "word_cycle", .val = GENERATED_PACKET_PATTERN_WORD_CYCLE },
684 { .name = "const", .val = GENERATED_PACKET_PATTERN_CONST },
685 BCMCLI_ENUM_LAST
686 };
687
688 static bcmcli_parm_value gem_port_ids[MAX_GEM_PORTS_FOR_SEND];
689 static bcmcli_parm_value onu_ids[MAX_ONUS_FOR_SEND];
690
691 bcmcli_entry *dir;
692
693 if (bcmcli_dir_find(top_dir, "gpon"))
694 {
695 return BCM_ERR_OK;
696 }
697
698 gpon_utils_cli_dir_cli_destroy();
699
700 dir = bcmcli_dir_add(top_dir, "gpon", "Common GPON/XGPON functions", BCMCLI_ACCESS_ADMIN, NULL);
701 BCMOS_CHECK_RETURN_ERROR(!dir, BCM_ERR_NOMEM);
702
703 BCMCLI_MAKE_CMD(
704 dir,
705 "build_cpu_packet",
706 "Build and save CPU packet",
707 build_cpu_packet_cb,
708 BCMCLI_MAKE_PARM_ENUM("calc_crc", "Auto-calculate CRC", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_NONE),
709 BCMCLI_MAKE_PARM_RANGE(
710 "packet_size", "Full packet size", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, MAX_PACKET_SIZE),
711 BCMCLI_MAKE_PARM_ENUM("pattern", "Background pattern", generated_packet_pattern_table, BCMCLI_PARM_FLAG_NONE),
712 BCMCLI_MAKE_PARM_RANGE("const_value", "Const value", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, 0xFF),
713 BCMCLI_MAKE_PARM("eth_da", "Ethernet destination address", BCMCLI_PARM_MAC, BCMCLI_PARM_FLAG_NONE),
714 BCMCLI_MAKE_PARM("eth_sa", "Ethernet source address", BCMCLI_PARM_MAC, BCMCLI_PARM_FLAG_NONE));
715
716 BCMCLI_MAKE_CMD(
717 dir,
718 "build_omci_packet",
719 "Build and save OMCI packet",
720 build_omci_packet_cb,
721 BCMCLI_MAKE_PARM_ENUM("calc_crc", "Auto-calculate CRC", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_NONE),
722 BCMCLI_MAKE_PARM_RANGE(
723 "packet_size", "Full packet size", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, MAX_PACKET_SIZE),
724 BCMCLI_MAKE_PARM_ENUM("pattern", "Background pattern", generated_packet_pattern_table, BCMCLI_PARM_FLAG_NONE),
725 BCMCLI_MAKE_PARM_RANGE("const_value", "Const value", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, 0xFF));
726
727 BCMCLI_MAKE_CMD(
728 dir,
729 "send_to_gem",
730 "Send saved CPU/OMCI packet to GEM port(s)",
731 send_to_gem_cb,
732 BCMCLI_MAKE_PARM("device", "Device ID", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
733 BCMCLI_MAKE_PARM("pon_ni", "PON NI", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
734 BCMCLI_MAKE_PARM_ARRAY(
735 "gem",
736 "GEM port IDs, comma separated",
737 BCMCLI_PARM_UNUMBER,
738 BCMCLI_PARM_FLAG_NONE,
739 MAX_GEM_PORTS_FOR_SEND,
740 gem_port_ids),
741 BCMCLI_MAKE_PARM("count", "Number of packets (default 1)", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_OPTIONAL));
742
743 BCMCLI_MAKE_CMD(
744 dir,
745 "send_to_onu",
746 "Send saved CPU/OMCI packet to ONU(s) (OMCI GEM port)",
747 send_to_onu_cb,
748 BCMCLI_MAKE_PARM("device", "Device ID", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
749 BCMCLI_MAKE_PARM("pon_ni", "PON NI", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
750 BCMCLI_MAKE_PARM_ARRAY(
751 "onu",
752 "ONU IDs, comma separated",
753 BCMCLI_PARM_UNUMBER,
754 BCMCLI_PARM_FLAG_NONE,
755 MAX_ONUS_FOR_SEND,
756 onu_ids),
757 BCMCLI_MAKE_PARM("count", "Number of packets (default 1)", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_OPTIONAL));
758
759 BCMCLI_MAKE_CMD_NOPARM(
760 dir,
761 "dump_packet",
762 "Print saved CPU/OMCI packet data",
763 dump_packet_cb);
764
765 gpon_utils_cli_dir = dir;
766 gpon_utils_cli_top_dir = top_dir;
767 return BCM_ERR_OK;
768}