blob: f32ff7e27394b897e506ee1ed2f7c5d357882636 [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 <bcmos_system.h>
31#include <bcmolt_api.h>
32#include <bcmolt_model_types.h>
33#include <bcm_dev_log.h>
34#include <bcmolt_board.h>
35#include "omon.h"
36#include "bcmolt_utils.h"
37/* These macros need to be defined before the following include. */
38#define BCM_I2C_DEV_ADDR_START typedef enum {
39#define BCM_I2C_DEV_ADDR(name, desc, val) name = val,
40#define BCM_I2C_DEV_ADDR_END } bcm_i2c_dev_addr;
41#include "bcmolt_i2c_devs_addr.h"
42
43
44/* Fixed sample delay exceeds the sum of the maximum grant size and a worst case
45 retrieval time based on various optics modules' data sheets */
46#define OMON_FIXED_SAMPLE_DELAY_US 12000
47#define SFF_8472_IDENTIFIER_ADDR 0x00 /* SFP and XFP Identifier byte*/
48#define SFF_8077i_IDENTIFIER_ADDR 128 /* XFP Identifier byte */
49#define SFF_8472_RX_POWER_ADDR 104 /* SFP offeset into A2 */
50#define SFF_8077i_RX_POWER_ADDR 104 /* XFP byte 104/105 into A0 (yes A0) */
51#define SFF_8077i_VENDOR_NAME_ADDR 148 /* XFP bytes 163-148 into A0 */
52#define SFF_8077i_VENDOR_NAME_LEN 16 /* XFP name length */
53#define SFF_8077i_VENDOR_PN_ADDR 168 /* XFP bytes 183-168 into A0 */
54#define SFF_8077i_VENDOR_PN_LEN 16 /* XFP part number length */
55#define SFF_8077i_VENDOR_REV_ADDR 184 /* XFP bytes 185-184 into A0 */
56#define SFF_8077i_VENDOR_REV_LEN 2 /* XFP revision len */
57#define SFF_8077i_VENDOR_SN_ADDR 196 /* XFP bytes 211-196 into A0 */
58#define SFF_8077i_VENDOR_SN_LEN 16 /* XFP serial number len */
59#define OMON_TASK_MSG_Q_SIZE 16 /* allow one message per port */
60#define SFF_PAGE_ADDR1 0 /* use SFP_I2C_ADDR1 for I2C read A0 */
61#define SFF_PAGE_ADDR2 1 /* use SFP_I2C_ADDR2 for 12C read A2 */
62
63#define SFF_8472_VENDOR_NAME_ADDR 20 /* SFP bytes 20-35 into A0 */
64#define SFF_8472_VENDOR_NAME_LEN 16 /* SFP name length */
65#define SFF_8472_VENDOR_OUI_ADDR 37 /* SFP bytes 37-39 into A0 */
66#define SFF_8472_VENDOR_OUI_LEN 3 /* SFP oui length */
67#define SFF_8472_VENDOR_PN_ADDR 40 /* SFP bytes 40-55 into A0 */
68#define SFF_8472_VENDOR_PN_LEN 16 /* SFP part number length */
69#define SFF_8472_VENDOR_REV_ADDR 56 /* SFP bytes 56-59 into A0 */
70#define SFF_8472_VENDOR_REV_LEN 4 /* SFP revision len */
71#define SFF_8472_VENDOR_SN_ADDR 68 /* SFP bytes 68-83 into A0 */
72#define SFF_8472_VENDOR_SN_LEN 16 /* SFP serial number len */
73#define SFF_8472_VENDOR_SFF_ADDR 94 /* SFP bytes 94 into A0 */
74#define SFF_8472_VENDOR_SFF_LEN 1 /* SFP SFF-8472 Compliance revision len */
75
76#define SFF_8472_DIAG_MON_ADDR 92 /* SFP bytes 92 into A0 */
77#define SFF_8472_ENHANCED_OPT_ADDR 93 /* SFP bytes 93 into A0 */
78#define SFF_8472_TEMPERATURE_ADDR 96 /* SFP bytes 96 into A0 */
79#define SFF_8472_DIAG_MON_LEN 1 /* SFP SFF-8472 Diagnostic Monitoring Type len */
80
81/* Table 32 5.2 Identifier values SFF8077i*/
82#define SFF_IDENTIFIER_SFP 0x03
83#define SFF_IDENTIFIER_XFP 0x06
84
85typedef uint32_t omon_rssi_value;
86
87
88/* Uniquely identifies specific EPON links under management by this
89 application */
90typedef struct
91{
92 bcmolt_devid device_id;
93 bcmolt_epon_ni epon_ni;
94 bcmos_mac_address mac_address;
95} omon_link_key;
96
97
98typedef struct
99{
100 uint32_t caddr; /* I2C switch control address */
101 uint32_t sctrl; /* I2C switch control command value */
102} i2c_coords;
103
104
105typedef struct
106{
107 bcmos_msg os_msg;
108 omon_link_key link_key;
109 uint16_t trigger_width_ns;
110 uint16_t trigger_delay_ns;
111 uint16_t sample_period_us;
112 bcmcli_session *session;
113 bcmolt_epon_llid llid;
114 uint8_t scan_mode;
115} omon_task_msg;
116
117
118static dev_log_id omon_log_id = DEV_LOG_INVALID_ID;
119static bcmos_task omon_task;
120static bcmos_bool is_running = BCMOS_FALSE;
121
122
123/*******************************************************************************
124 * BCM968620 platform dependent I2C access
125 ******************************************************************************/
126
127
128uint8_t bcm968620_client_switchctrl_sfp[16][2] =
129{
130 { 0x72, 0x80, },
131 { 0x72, 0x40, },
132 { 0x72, 0x20, },
133 { 0x72, 0x10, },
134 { 0x72, 0x8, },
135 { 0x72, 0x4, },
136 { 0x72, 0x2, },
137 { 0x72, 0x1, },
138 { 0x73, 0x10, },
139 { 0x73, 0x20, },
140 { 0x73, 0x40, },
141 { 0x73, 0x80, },
142 { 0x73, 0x1, },
143 { 0x73, 0x2, },
144 { 0x73, 0x4, },
145 { 0x73, 0x8, },
146};
147
148
149uint8_t bcm968620_client_switchctrl_xfp[8][2] =
150{
151 /* caddr, sctrl */
152 { 0x72, 0x8, },
153 { 0x72, 0x4, },
154 { 0x72, 0x2, },
155 { 0x72, 0x1, },
156 { 0x73, 0x10, },
157 { 0x73, 0x20, },
158 { 0x73, 0x40, },
159 { 0x73, 0x80, },
160};
161
162static bcmos_bool omon_is_epon_ni_valid(bcmolt_epon_ni epon)
163{
164 bcmolt_system_mode system_mode;
165
166 bcmolt_system_mode_get(current_device, &system_mode);
167
168 switch (system_mode)
169 {
170 case BCMOLT_SYSTEM_MODE_EPON__16_X:
171 return epon < 16;
172 case BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA:
173 case BCMOLT_SYSTEM_MODE_EPON__8_X_10_G:
174 case BCMOLT_SYSTEM_MODE_EPON__8_X:
175 return epon < 8;
176 case BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA:
177 case BCMOLT_SYSTEM_MODE_EPON__4_X_10_G:
178 case BCMOLT_SYSTEM_MODE_EPON__4_X:
179 return epon < 4;
180 case BCMOLT_SYSTEM_MODE_EPON__2_X_10_G:
181 return epon < 2;
182 default:
183 return BCMOS_FALSE;
184 }
185}
186
187static bcmos_bool trx_id_from_epon_ni(bcmolt_epon_ni epon, uint8_t *trx_id)
188{
189 static const uint8_t epon_4x[4] = { 2, 3, 6, 7 };
190 static const uint8_t epon_2x_10g[2] = { 3, 4 };
191 bcmolt_system_mode system_mode;
192
193 bcmolt_system_mode_get(current_device, &system_mode);
194
195 switch (system_mode)
196 {
197 case BCMOLT_SYSTEM_MODE_EPON__16_X:
198 case BCMOLT_SYSTEM_MODE_EPON__8_X:
199 case BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA:
200 case BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA:
201 case BCMOLT_SYSTEM_MODE_EPON__8_X_10_G:
202 case BCMOLT_SYSTEM_MODE_EPON__4_X_10_G:
203 *trx_id = (uint8_t)epon;
204 return BCMOS_TRUE;
205 case BCMOLT_SYSTEM_MODE_EPON__4_X:
206 *trx_id = epon_4x[epon];
207 return BCMOS_TRUE;
208 case BCMOLT_SYSTEM_MODE_EPON__2_X_10_G:
209 *trx_id = epon_2x_10g[epon];
210 return BCMOS_TRUE;
211 default:
212 *trx_id = (uint8_t)-1;
213 return BCMOS_FALSE;
214 }
215}
216
217static char * bcmolt_get_scan_result(bcmolt_rogue_scan_status status)
218{
219 switch (status)
220 {
221 case BCMOLT_ROGUE_SCAN_STATUS_COMPLETE:
222 return "OK: EPON ROGUE SCAN IS COMPLETE";
223 case BCMOLT_ROGUE_SCAN_STATUS_LLID_STATE_IS_BAD:
224 return "FAIL: REQUESTED LLID IS IN USE";
225 case BCMOLT_ROGUE_SCAN_STATUS_SCAN_ERR_INTERNAL:
226 return "FAIL: SCAN HAD AN INTERNAL SW ERROR";
227 case BCMOLT_ROGUE_SCAN_STATUS_SCAN_ERR_NORES:
228 return "FAIL: NO RESOURCES AVAILABLE";
229 case BCMOLT_ROGUE_SCAN_STATUS_LLID_IS_OOR:
230 return "FAIL: REQUESTED LLID IS OUT OF RANGE";
231 default:
232 return "OK: BCMOLT_ROGUE_SCAN_STATUS_COMPLETE";
233 }
234}
235
236/**
237 * \brief Get I2C address
238 *
239 * This function returns the I2C mux target address for the given link_key
240 * object.
241 *
242 * \param epon_ni EPON port index
243 * \param coords I2C mux target container
244 *
245 * \return
246 * None
247 */
248static
249void omon_get_i2c_coords(uint8_t trx_id, i2c_coords* coords)
250{
251 bcmolt_system_mode system_mode;
252
253 bcmolt_system_mode_get(0, &system_mode);
254
255 if (system_mode == BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA)
256 {
257 coords->caddr = bcm968620_client_switchctrl_xfp[trx_id][0];
258 coords->sctrl = bcm968620_client_switchctrl_xfp[trx_id][1];
259 }
260 else
261 {
262 coords->caddr = bcm968620_client_switchctrl_sfp[trx_id][0];
263 coords->sctrl = bcm968620_client_switchctrl_sfp[trx_id][1];
264 }
265} /* omon_get_i2c_coords */
266
267
268/**
269 * \brief Configure I2C mux
270 *
271 * This function configures the I2C mux to target the correct optics module for
272 * the currently executing RSSI measurement.
273 *
274 * \param epon_ni EPON port index
275 *
276 * \return
277 * BCM_ERR_OK if successful, error code if not
278 */
279static
280bcmos_errno omon_platform_configure_i2c(uint8_t trx_id, uint8_t page)
281{
282
283 i2c_coords coords;
284 bcmos_errno rc;
285
286 omon_get_i2c_coords(trx_id, &coords);
287
288 rc = bcm_board_dev_change(coords.caddr);
289 if (rc != BCM_ERR_OK)
290 {
291 BCM_LOG(WARNING, omon_log_id,
292 "bcm_board_dev_change(%u) failed\n", coords.caddr);
293 }
294 else
295 {
296 rc = bcm_board_switch_write(coords.sctrl);
297 if (rc != BCM_ERR_OK)
298 {
299 BCM_LOG(WARNING, omon_log_id,
300 "bcm_board_switch_write(%u) failed\n", coords.sctrl);
301 }
302 else
303 {
304 if (page == SFF_PAGE_ADDR1)
305 {
306 rc = bcm_board_dev_change(SFP_I2C_ADDR1);
307 }
308 else
309 { // SFF_PAGE_ADDR2
310 rc = bcm_board_dev_change(SFP_I2C_ADDR2);
311 }
312 if (rc != BCM_ERR_OK)
313 {
314 BCM_LOG(WARNING, omon_log_id,
315 "bcm_board_dev_change(%u) failed\n", (SFP_I2C_ADDR1+page));
316 }
317 }
318 }
319 return rc;
320
321} /* omon_platform_configure_i2c */
322
323
324/**
325 * \brief Read Manufacturing data from Optic Module
326 *
327 * This function reads the XFP Tranceiver Data (according to
328 * SFF8077i for an XFP) from an optics module. The result is
329 * displayed for this sample code.
330 *
331 * \param epon_ni EPON NI to take measurement
332 *
333 * \return
334 * BCM_ERR_OK if successful, error code if not
335 */
336static
337bcmos_errno omon_trx_status_read(bcmolt_epon_ni epon_ni, bcmcli_session *session)
338{
339 uint32_t sff_identifier = 1;
340 bcmos_errno rc = BCM_ERR_OK;
341 uint8_t i;
342
343 // 80771 XFP Specific stuff
344 uint32_t raw_vendorId_8077i;
345 uint8_t vendorId_8077i[SFF_8077i_VENDOR_NAME_LEN+1];
346 uint32_t raw_vendorPn_8077i;
347 uint8_t vendorPn_8077i[SFF_8077i_VENDOR_PN_LEN+1];
348 uint32_t raw_vendorSn_8077i;
349 uint8_t vendorSn_8077i[SFF_8077i_VENDOR_SN_LEN+1];
350 uint32_t raw_vendorRev_8077i;
351 uint8_t vendorRev_8077i[SFF_8077i_VENDOR_REV_LEN+1];
352
353 memset(&vendorId_8077i, 0, sizeof(vendorId_8077i));
354 memset(&vendorPn_8077i, 0, sizeof(vendorPn_8077i));
355 memset(&vendorSn_8077i, 0, sizeof(vendorSn_8077i));
356 memset(&vendorRev_8077i, 0, sizeof(vendorRev_8077i));
357
358 // 8472 SFP Specific stuff
359 uint32_t raw_vendorId_8472;
360 uint8_t vendorId_8472[SFF_8472_VENDOR_NAME_LEN+1];
361 uint32_t raw_vendorPn_8472;
362 uint8_t vendorPn_8472[SFF_8472_VENDOR_PN_LEN+1];
363 uint32_t raw_vendorSn_8472;
364 uint8_t vendorSn_8472[SFF_8472_VENDOR_SN_LEN+1];
365 uint32_t raw_vendorRev_8472;
366 uint8_t vendorRev_8472[SFF_8472_VENDOR_REV_LEN+1];
367 uint32_t raw_vendorSff_8472;
368 uint8_t vendorSff_8472[SFF_8472_VENDOR_SFF_LEN+1];
369 uint32_t raw_vendorOui_8472;
370 uint8_t vendorOui_8472[SFF_8472_VENDOR_OUI_LEN+1];
371 uint32_t raw_diagMon_8472;
372 uint8_t diagMon_8472 = 0;
373 uint32_t raw_enhancedOpt_8472;
374 uint8_t enhancedOpt_8472 = 0;
375
376 memset(&vendorId_8472, 0, sizeof(vendorId_8472));
377 memset(&vendorPn_8472, 0, sizeof(vendorPn_8472));
378 memset(&vendorSn_8472, 0, sizeof(vendorSn_8472));
379 memset(&vendorRev_8472, 0, sizeof(vendorRev_8472));
380 memset(&vendorSff_8472, 0, sizeof(vendorSff_8472));
381 memset(&vendorOui_8472, 0, sizeof(vendorOui_8472));
382
383 uint8_t* tmpresult;
384 int16_t temp_result = 0;
385 uint32_t raw_temp_result = 0;
386
387 uint8_t trx_id;
388
389 if ( ! trx_id_from_epon_ni(epon_ni, &trx_id) )
390 {
391 BCM_LOG(ERROR, omon_log_id,
392 "TRX Id is invalid for EPON NI %d \n", epon_ni);
393 return BCM_ERR_RANGE;
394 }
395
396 char *pSfpType;
397
398 pSfpType = "UNKN";
399
400
401 // Check for transevier presence
402 if ( (rc = omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR1)) == BCM_ERR_OK)
403 {
404 /* Read module identifier */
405 if ( (rc = bcm_board_dev_read(8, SFF_8472_IDENTIFIER_ADDR, &sff_identifier)) == BCM_ERR_OK)
406 {
407 switch (sff_identifier & 0x000F)
408 {
409 case SFF_IDENTIFIER_SFP:
410 pSfpType = "SFP\0";
411 // Read the vendor Id
412 for (i=0; i<SFF_8472_VENDOR_NAME_LEN; i++)
413 {
414 rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_NAME_ADDR+i, &raw_vendorId_8472);
415 vendorId_8472[i] = (uint8_t)raw_vendorId_8472;
416 }
417
418 // Read the part Number, serial number, SFF revision, and Revision
419 for (i=0; i<SFF_8472_VENDOR_PN_LEN; i++)
420 {
421 rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_PN_ADDR+i, &raw_vendorPn_8472);
422 vendorPn_8472[i] = (uint8_t)raw_vendorPn_8472;
423 }
424
425 for (i=0; i<SFF_8472_VENDOR_SN_LEN; i++)
426 {
427 rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_SN_ADDR+i, &raw_vendorSn_8472);
428 vendorSn_8472[i] = (uint8_t)raw_vendorSn_8472;
429 }
430
431 for (i=0; i<SFF_8472_VENDOR_REV_LEN; i++)
432 {
433 rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_REV_ADDR+i, &raw_vendorRev_8472);
434 vendorRev_8472[i] = (uint8_t)raw_vendorRev_8472;
435 }
436
437 for (i=0; i<SFF_8472_VENDOR_SFF_LEN; i++)
438 {
439 rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_SFF_ADDR+i, &raw_vendorSff_8472);
440 vendorSff_8472[i] = (uint8_t)raw_vendorSff_8472;
441 }
442 for (i=0; i<SFF_8472_VENDOR_OUI_LEN; i++)
443 {
444 rc = rc | bcm_board_dev_read(8, SFF_8472_VENDOR_OUI_ADDR+i, &raw_vendorOui_8472);
445 vendorOui_8472[i] = (uint8_t)raw_vendorOui_8472;
446 }
447
448 rc = rc | bcm_board_dev_read(8, SFF_8472_DIAG_MON_ADDR, &raw_diagMon_8472);
449 diagMon_8472 = (uint8_t)raw_diagMon_8472;
450
451 rc = rc | bcm_board_dev_read(8, SFF_8472_ENHANCED_OPT_ADDR, &raw_enhancedOpt_8472);
452 enhancedOpt_8472 = (uint8_t)raw_enhancedOpt_8472;
453
454 // Shift to A2
455 rc = rc | omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR2);
456 rc = rc | bcm_board_dev_read(16, SFF_8472_TEMPERATURE_ADDR, &raw_temp_result);
457
458 tmpresult = (uint8_t*)(&raw_temp_result);
459
460 temp_result = tmpresult[3];
461 temp_result = (temp_result << 8) | tmpresult[2];
462
463 break;
464
465 case SFF_IDENTIFIER_XFP:
466
467 pSfpType = "XFP\0";
468 // Read the vendor Id
469 for (i=0; i<SFF_8077i_VENDOR_NAME_LEN; i++)
470 {
471 rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_NAME_ADDR+i, &raw_vendorId_8077i);
472 vendorId_8077i[i] = (uint8_t)raw_vendorId_8077i;
473 }
474
475 // Read the part Number, SN, and Revision
476 for (i=0; i<SFF_8077i_VENDOR_PN_LEN; i++)
477 {
478 rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_PN_ADDR+i, &raw_vendorPn_8077i);
479 vendorPn_8077i[i] = (uint8_t)raw_vendorPn_8077i;
480 }
481
482 for (i=0; i<SFF_8077i_VENDOR_SN_LEN; i++)
483 {
484 rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_SN_ADDR+i, &raw_vendorSn_8077i);
485 vendorSn_8077i[i] = (uint8_t)raw_vendorSn_8077i;
486 }
487
488 for (i=0; i<SFF_8077i_VENDOR_REV_LEN; i++)
489 {
490 rc = rc | bcm_board_dev_read(8, SFF_8077i_VENDOR_REV_ADDR+i, &raw_vendorRev_8077i);
491 vendorRev_8077i[i] = (uint8_t)raw_vendorRev_8077i;
492 }
493
494 break;
495 default:
496 rc = BCM_ERR_NODEV;
497 break;
498 }
499 }
500 else
501 {
502 BCM_LOG(ERROR, omon_log_id,
503 "TRX Could not read device : SFF_8472_IDENTIFIER_ADDR for PON %d rc %d (%s)\n",
504 epon_ni, rc, bcmos_strerror(rc));
505 }
506 }
507 else
508 {
509 BCM_LOG(ERROR, omon_log_id,
510 "TRX Could not configure platform : SFF_PAGE_ADDR1 for PON %d rc %d (%s)\n",
511 epon_ni, rc, bcmos_strerror(rc));
512 rc = BCM_ERR_NODEV;
513 }
514
515
516 if (rc == BCM_ERR_OK)
517 {
518 if ( (sff_identifier & 0x000F) == SFF_IDENTIFIER_XFP)
519 {
520 bcmcli_session_print(session,
521 "\n[OMON] %s Tranceiver is present on PON %d\r\n"
522 " [OMON] Trx Vendor Id is: %s\r\n "
523 " [OMON] Vendor Part Number: %s\r\n "
524 " [OMON] Vendor Serial Number: %s\r\n "
525 " [OMON] Vendor Revision: %s\r\n ",
526 pSfpType, epon_ni, vendorId_8077i,
527 vendorPn_8077i, vendorSn_8077i, vendorRev_8077i);
528 }
529 else
530 {
531 // SFP stuff
532 bcmcli_session_print(session,
533 "\n[OMON] %s Tranceiver is present on PON %d\r\n"
534 " [OMON] Trx Vendor Id is: %s\r\n "
535 " [OMON] Vendor Part Number: %s\r\n "
536 " [OMON] Vendor Serial Number: %s\r\n "
537 " [OMON] Vendor Revision: %s\r\n "
538 " [OMON] Vendor OUI: %s\r\n "
539 " [OMON] Transceiver Temperature: %dC\r\n "
540 " [OMON] Enhanced Options SFF-8472 Byte 93: %x\r\n "
541 " [OMON] Diagnostic Monitor Type SFF-8472 Byte 92: %x\r\n ",
542 pSfpType, epon_ni, vendorId_8472,
543 vendorPn_8472, vendorSn_8472, vendorRev_8472, vendorOui_8472,
544 temp_result/256, enhancedOpt_8472, diagMon_8472 );
545 }
546 }
547
548 return rc;
549} /* omon_rssi_read */
550
551/**
552 * \brief Read RSSI results from I2C
553 *
554 * This function reads the RX Power Measurement (SFF8472 for an
555 * SFP and SFF8077i for an XFP) from an optics module. The
556 * result is stored in the global omon_state.
557 *
558 * \param epon_ni EPON NI to take measurement
559 * \param rssi_value Returned RSSI value if successful
560 *
561 * \return
562 * BCM_ERR_OK if successful, error code if not
563 */
564static
565bcmos_errno omon_rssi_read(bcmolt_epon_ni epon_ni, uint32_t *rssi_value)
566{
567 uint32_t raw_rssi_result = 0;
568 uint32_t sff_identifier = 1;
569 uint8_t trx_id;
570 uint32_t rssi_result = 0;
571 bcmos_errno rc = BCM_ERR_OK;
572 uint8_t* result;
573
574 if ( ! trx_id_from_epon_ni(epon_ni, &trx_id) )
575 {
576 BCM_LOG(ERROR, omon_log_id,
577 "TRX Id is invalid for EPON NI %d \n", epon_ni);
578 return BCM_ERR_RANGE;
579 }
580
581 // Check for transevier presence
582 if (bcm_board_trx_present(trx_id) == BCM_ERR_OK)
583 {
584 rc = omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR1);
585 /* Read module identifier */
586
587 if (rc == BCM_ERR_OK)
588 {
589 /* Read module identifier */
590 rc = bcm_board_dev_read(8, SFF_8472_IDENTIFIER_ADDR, &sff_identifier);
591
592 if (rc == BCM_ERR_OK)
593 {
594 result = (uint8_t*)(&raw_rssi_result);
595
596 switch (sff_identifier & 0x000F)
597 {
598 case SFF_IDENTIFIER_SFP:
599 rc = omon_platform_configure_i2c(trx_id, SFF_PAGE_ADDR2);
600 if (rc == BCM_ERR_OK)
601 {
602 rc = bcm_board_dev_read(16, SFF_8472_RX_POWER_ADDR, &raw_rssi_result);
603 }
604 break;
605 case SFF_IDENTIFIER_XFP:
606
607 rc = bcm_board_dev_read(16, SFF_8077i_RX_POWER_ADDR, &raw_rssi_result);
608
609 break;
610 default:
611 rc = BCM_ERR_NODEV;
612 break;
613 }
614
615 if (rc == BCM_ERR_OK)
616 {
617 rssi_result = result[3];
618 rssi_result = (rssi_result << 8) | result[2];
619
620 *rssi_value = rssi_result;
621
622 }
623 }
624 else
625 {
626 BCM_LOG(ERROR, omon_log_id,
627 "TRX Could not read device : SFF_8472_IDENTIFIER_ADDR for PON %d rc %d (%s)\n",
628 epon_ni, rc, bcmos_strerror(rc));
629 rc = BCM_ERR_IO;
630 }
631 }
632 else
633 {
634 BCM_LOG(ERROR, omon_log_id,
635 "TRX Could not read platform : SFF_PAGE_ADDR1 for PON %d rc %d (%s)\n",
636 epon_ni, rc, bcmos_strerror(rc));
637 rc = BCM_ERR_IO;
638 }
639 }
640 else
641 {
642 rc = BCM_ERR_NODEV;
643 }
644
645 return rc;
646} /* omon_rssi_read */
647
648
649/*******************************************************************************
650 * Platform independent RSSI measurement
651 ******************************************************************************/
652
653/**
654 * \brief Read XFP/SFP Data from Transceiver Module1
655 *
656 * This function reads the manufacturing data from the SFP
657 * module via I2C.
658 *
659 * \param link_key EPON NI
660 *
661 * \return
662 * None
663 */
664static
665void omon_trx_status_initiate(bcmcli_session *session,
666 omon_link_key *link_key)
667{
668
669 bcmos_errno rc;
670
671 /* Perform the I2C operations specified in SFF-8472 (SFP)/SFF-8077i (XFP) to
672 retrieve the pmanufacturer data from the optics module. */
673
674 if (! omon_is_epon_ni_valid(link_key->epon_ni))
675 {
676 BCM_LOG(ERROR, omon_log_id,
677 "[OMON] TRX Status: epon_ni of (%d) is out of range for platform\n", link_key->epon_ni);
678 return ;
679 }
680 // Check for transceiver presence
681
682 uint8_t trx_id;
683
684 if ( ! trx_id_from_epon_ni(link_key->epon_ni, &trx_id) )
685 {
686 BCM_LOG(ERROR, omon_log_id,
687 "[OMON] TRX Id is invalid for EPON NI %d \n", link_key->epon_ni);
688 return;
689 }
690
691 rc = bcm_board_trx_present(trx_id);
692
693 if (rc == BCM_ERR_NODEV)
694 {
695 bcmcli_session_print(session,
696 "[OMON] TRX Status: Trx_id %d Not Present on PON %d\r\n ", trx_id, link_key->epon_ni);
697 return;
698 }
699
700 rc = omon_trx_status_read(trx_id, session);
701
702 if (rc != BCM_ERR_OK)
703 {
704 BCM_LOG(ERROR, omon_log_id,
705 "[OMON] Issue TRX Status: Read operation failed with rc %d (%s)\n",
706 rc, bcmos_strerror(rc));
707 return;
708 }
709
710 /* Notify external host code of the outcome through an optional callback,
711 defaulting to output in the CLI session where the command was initiated
712 if no callback is supplied. */
713
714 bcmcli_session_print(session,
715 "\n[OMON] TRX Status: Data on PON %d Complete\r\n", link_key->epon_ni);
716}
717/**
718 * \brief Read RSSI Measurement Result from Transceiver Module
719 *
720 * This function reads the stored RSSI measurement from the
721 * XFP/SFP module via I2C.
722 *
723 * \param link_key EPON NI
724 *
725 * \return
726 * None
727 */
728static
729void omon_rssi_read_initiate(bcmcli_session *session,
730 omon_link_key *link_key)
731{
732 uint32_t rssi_value = 0;
733 bcmos_errno rc;
734
735 if (! omon_is_epon_ni_valid(link_key->epon_ni))
736 {
737 BCM_LOG(ERROR, omon_log_id,
738 "[OMON] Rssi Read: epon_ni of (%d) is out of range for platform\n", link_key->epon_ni);
739 return ;
740 }
741
742 /* Perform the I2C operations specified in SFF-8472 (SFP)/SFF-8077i (XFP) to
743 retrieve the power measurements from the optics module. */
744 rc = omon_rssi_read(link_key->epon_ni, &rssi_value);
745
746 if (rc == BCM_ERR_NODEV)
747 {
748 bcmcli_session_print(session,
749 "[OMON] Rssi Read: TRX Not Present on PON %d\r\n ", link_key->epon_ni);
750 return;
751 }
752
753 if (rc == BCM_ERR_IO)
754 {
755 bcmcli_session_print(session,
756 "[OMON] Rssi Read: Could not read device for PON %d \n",link_key->epon_ni);
757 return;
758 }
759
760 if (rc != BCM_ERR_OK)
761 {
762 bcmcli_session_print(session,
763 "Issue RSSI Read operation failed with rc %d (%s)\n",
764 rc, bcmos_strerror(rc));
765 return;
766 }
767 /* Notify external host code of the outcome through an optional callback,
768 defaulting to output in the CLI session where the command was initiated
769 if no callback is supplied. */
770
771 bcmcli_session_print(session,
772 "[OMON] RSSI Read RX Power: Pon_ni=%d rx power %d.%duW\r\n",
773 link_key->epon_ni,
774 rssi_value/10,
775 rssi_value%10);
776
777 bcmcli_session_print(session,
778 "\n[OMON] RSSI Read on PON %d Complete\r\n",
779 link_key->epon_ni);
780}
781/*omon_rssi_read_initiate*/
782
783
784/**
785 * \brief Request Maple Firmware to run the Rogue ONU LLID scan.
786 *
787 * This function sends an API message to the OLT to run a scan
788 * on a specific EPON LLID or across all LLIDs in the PON.
789 * Results are returned upon completion. Rogue LLIDs are marked
790 * and quarentined for the host to examine.
791 *
792 * \param link_key EPON link information
793 * \param epopn_llid Specific LLID to scan
794 * \param scan_mode Specifies a single LLID or All.
795 *
796 * \return
797 * None
798 */
799
800static
801void omon_run_rogue_llid_scan(bcmcli_session *session,
802 omon_link_key *link_key,
803 bcmolt_epon_llid llid,
804 uint8_t scan_mode)
805{
806 const bcmolt_epon_ni_key ni_key = { .epon_ni = link_key->epon_ni };
807 bcmolt_epon_ni_rogue_llid_scan issue_llid_scan_op;
808 bcmos_errno rc = BCM_ERR_OK;
809
810 /* Perform an API operation directing the Maple firmware to issue an bcmolt_epon_ni_issue_rogue_rx_power
811 RSSI grant to the specified EPON link. BCMOLT_EPON_NI_OPER_ID_ISSUE_ROGUE_RX_POWER*/
812
813 BCMOLT_OPER_INIT(&issue_llid_scan_op, epon_ni, rogue_llid_scan , ni_key);
814 BCMOLT_OPER_PROP_SET(&issue_llid_scan_op, epon_ni, rogue_llid_scan, mode, scan_mode);
815 BCMOLT_OPER_PROP_SET(&issue_llid_scan_op, epon_ni, rogue_llid_scan, llid, llid);
816
817 BCM_LOG_CALLER_FMT(INFO, omon_log_id,
818 "Issue Rogue Scan Operation for LLID 0x%x, Pon_ni=%d\r\n", llid, link_key->epon_ni);
819
820 rc = bcmolt_oper_submit(link_key->device_id, &issue_llid_scan_op.hdr);
821
822 if (rc != BCM_ERR_OK)
823 {
824 BCM_LOG(ERROR, omon_log_id,
825 "Rogue Scan Operation Failed with rc %d (%s)\n",
826 rc, bcmos_strerror(rc));
827
828 return;
829 }
830}/*omon_run_rogue_llid_scan*/
831
832/**
833 * \brief Execute RSSI measurement
834 *
835 * This function sends an API message to the OLT to issue an RSSI grant. It
836 * then reads back the results via I2C. Set grant_length_tq to 0 to retreive the
837 * RSSI value without issuing the strobe command to the OLT.
838 *
839 * \param link_key EPON RSSI link information
840 * \param grant_length_tq Size of the RSSI grant
841 * \param start_offset Strobe offset from start of the RSSI grant
842 * \param end_offset Strobe offset from the end of the RSSI grant
843 *
844 * \return
845 * None
846 */
847static
848void omon_rssi_measurement_initiate(bcmcli_session *session,
849 omon_link_key *link_key,
850 uint16_t trigger_width_tq,
851 uint16_t trigger_delay_tq,
852 uint16_t sample_period)
853{
854 const bcmolt_epon_ni_key ni_key = { .epon_ni = link_key->epon_ni };
855 bcmolt_epon_ni_issue_rssi_grant issue_rssi_grant_op;
856 bcmos_errno rc = BCM_ERR_OK;
857
858 if (! omon_is_epon_ni_valid(link_key->epon_ni))
859 {
860 BCM_LOG(ERROR, omon_log_id,
861 "[OMON] Rx Power: epon_ni of (%d) is out of range for platform\n", link_key->epon_ni);
862 return ;
863 }
864
865 uint8_t trx_id;
866
867 if ( ! trx_id_from_epon_ni(link_key->epon_ni, &trx_id) )
868 {
869 BCM_LOG(ERROR, omon_log_id,
870 "[OMON] Rx Power: TRX Id is invalid for EPON NI %d \n", link_key->epon_ni);
871 return;
872 }
873
874 // Check for transevier presence
875 rc = bcm_board_trx_present(trx_id);
876
877 if (rc == BCM_ERR_NODEV)
878 {
879 bcmcli_session_print(session,
880 "[OMON] Rx Power: TRX Not Present on PON %d\r\n ", link_key->epon_ni);
881 return;
882 }
883
884 /* Perform an API operation directing the Maple firmware to issue an bcmolt_epon_ni_issue_rogue_rx_power
885 RSSI grant to the specified EPON link. BCMOLT_EPON_NI_OPER_ID_ISSUE_ROGUE_RX_POWER*/
886
887 BCMOLT_OPER_INIT(&issue_rssi_grant_op, epon_ni, issue_rssi_grant , ni_key);
888 BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
889 granted_link, link_key->mac_address);
890 BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
891 trigger_width, trigger_width_tq);
892 BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
893 trigger_delay, trigger_delay_tq);
894 BCMOLT_OPER_PROP_SET(&issue_rssi_grant_op, epon_ni, issue_rssi_grant,
895 sample_period, sample_period);
896
897 rc = bcmolt_oper_submit(link_key->device_id, &issue_rssi_grant_op.hdr);
898 if (rc != BCM_ERR_OK)
899 {
900 BCM_LOG(ERROR, omon_log_id,
901 "issue RSSI grant operation failed with rc %d (%s)\n",
902 rc, bcmos_strerror(rc));
903
904 return;
905 }
906}
907/*omon_rssi_measurement_initiate*/
908
909// rssi specific indication handler interface --
910static bcmos_errno bcmolt_user_appl_rssi_handle_ind(bcmolt_devid device_id,
911 uint8_t instance,
912 bcmolt_auto *ind)
913{
914
915 bcmolt_epon_ni_rssi_measurement_completed* omon_ind;
916 uint32_t rssi_value = 0;
917 bcmolt_epon_ni epon_ni;
918 bcmos_errno rc = BCM_ERR_OK;
919 char tBuf[40];
920
921 omon_ind = (bcmolt_epon_ni_rssi_measurement_completed *) ind;
922 epon_ni = omon_ind->key.epon_ni;
923
924 if (omon_ind->data.status == BCMOLT_RESULT_SUCCESS)
925 {
926 /* Perform the I2C operations specified in SFF-8472 (SFP)/SFF-8077i (XFP) to
927 retrieve the power measurements from the optics module. */
928 rc = omon_rssi_read(epon_ni, &rssi_value);
929
930 }
931 /* Notify external host code of the outcome through an optional callback,
932 defaulting to output in the CLI session where the command was initiated
933 if no callback is supplied. */
934
935 BCM_LOG_CALLER_FMT(INFO, omon_log_id,
936 " RSSI Indication Rcv: for Link Mac %s, LLID 0x%x, Dev=%01d, Pon_ni=%d\r\n",
937 bcmos_mac_2_str(&omon_ind->data.link_mac, tBuf),
938 omon_ind->data.llid,
939 device_id,
940 omon_ind->key.epon_ni);
941
942 if (rc == BCM_ERR_OK)
943 {
944 BCM_LOG(INFO, omon_log_id,
945 " %s measured rx power %d.%duW raw_data %d\n",
946 (omon_ind->data.status == BCMOLT_RESULT_SUCCESS ? "Succeeded" : "Failed"),
947 rssi_value/10, rssi_value%10, rssi_value);
948 }
949 else
950 {
951 BCM_LOG(INFO, omon_log_id,
952 "pon %d, failed with errno %d (%s)\n",
953 epon_ni, rc, bcmos_strerror(rc));
954 }
955 return rc;
956}
957
958// epon rogue onu specific indication handler interface --
959static bcmos_errno bcmolt_user_appl_rogue_handle_ind(bcmolt_devid device_id,
960 uint8_t instance,
961 bcmolt_auto *ind)
962{
963 (void)instance;
964 bcmolt_epon_denied_link_rogue_violation* rogue_ind;
965 char tBuf[40];
966
967 rogue_ind = (bcmolt_epon_denied_link_rogue_violation *) ind;
968
969 /* Notify external host code of the outcome through an optional callback,
970 defaulting to output in the CLI session where the command was initiated
971 if no callback is supplied. */
972
973 BCM_LOG_CALLER_FMT(INFO, omon_log_id,
974 "Rogue ONU Scan Violation: AlmState = %s, Link Mac %s, LLID 0x%x, Range=%0d, Pon_ni=%2d\r\n",
975 (rogue_ind->data.alarm_status.alarm_status == BCMOLT_STATUS_ON ? "ON" : "OFF"),
976 bcmos_mac_2_str(&rogue_ind->key.mac_address, tBuf),
977 rogue_ind->data.alarm_status.denied_llid,
978 rogue_ind->data.alarm_status.denied_range,
979 rogue_ind->key.epon_ni);
980
981 return BCM_ERR_OK;
982}
983
984// epon rogue scan complete specific indication handler interface --
985static bcmos_errno bcmolt_user_appl_rogue_complete_handle_ind(bcmolt_devid device_id,
986 uint8_t instance,
987 bcmolt_auto *ind)
988{
989 (void)instance;
990 bcmolt_epon_ni_rogue_scan_complete* rogue_ind;
991
992 rogue_ind = (bcmolt_epon_ni_rogue_scan_complete *) ind;
993
994 /* Notify external host code of the outcome through an optional callback,
995 defaulting to output in the CLI session where the command was initiated
996 if no callback is supplied. */
997
998 BCM_LOG_CALLER_FMT(INFO, omon_log_id,
999 "Rogue ONU scan complete for Pon %d, Status = %s\r\n",
1000 rogue_ind->key.epon_ni,
1001 bcmolt_get_scan_result(rogue_ind->data.return_ind_status));
1002 return BCM_ERR_OK;
1003}
1004
1005// public indication handler interface -- called in transport layer context
1006bcmos_errno bcmolt_user_appl_omon_handle_ind(bcmolt_devid device_id, uint8_t instance, bcmolt_auto *ind)
1007{
1008
1009 // Not an error, we just don't care about this indication.
1010 bcmos_errno rc = BCM_ERR_OK;
1011
1012 // We look at message targetting epon ni.
1013 if (ind->hdr.obj_type == BCMOLT_OBJ_ID_EPON_NI)
1014 {
1015 // We look at RSSI Completion event indications.
1016 if (ind->hdr.subgroup == (uint16_t)BCMOLT_EPON_NI_AUTO_ID_RSSI_MEASUREMENT_COMPLETED)
1017 {
1018 rc = bcmolt_user_appl_rssi_handle_ind(device_id,instance,ind);
1019 }
1020 else
1021 {
1022 // We look for Rogue Scan Complete event indications.
1023 if (ind->hdr.subgroup == (uint16_t)BCMOLT_EPON_NI_AUTO_ID_ROGUE_SCAN_COMPLETE)
1024 {
1025 rc = bcmolt_user_appl_rogue_complete_handle_ind(device_id, instance, ind);
1026 }
1027 }
1028
1029 if (rc != BCM_ERR_OK )
1030 {
1031 BCM_LOG_CALLER_FMT(INFO, omon_log_id,
1032 "OMON Handle Indication Error: Pon %d, Type %d, Rc %d\r\n",
1033 instance, ind->hdr.subgroup, rc);
1034 }
1035
1036 // Not an error, we just don't care about this indication.
1037 return BCM_ERR_OK;
1038 }
1039
1040 // We look at message targetting epon denied links.
1041 if (ind->hdr.obj_type == BCMOLT_OBJ_ID_EPON_DENIED_LINK)
1042 {
1043 // We look at Denied Link Events of this type.
1044 if (ind->hdr.subgroup == BCMOLT_EPON_DENIED_LINK_AUTO_ID_ROGUE_VIOLATION)
1045 {
1046 rc = bcmolt_user_appl_rogue_handle_ind(device_id, instance, ind);
1047 }
1048 else
1049 {
1050 // Not an error, we just don't care about this object.
1051 return BCM_ERR_OK;
1052 }
1053 }
1054 return rc;
1055
1056} /* bcmolt_user_appl_omon_handle_ind */
1057
1058/**
1059 * \brief Optical monitoring task message handler
1060 *
1061 * This function is the optical monitoring task handler. At this time the only
1062 * message is BCMOS_MSG_ID_INITIATE_RSSI_SAMPLE which starts the RSSI
1063 * measurement on the OLT.
1064 *
1065 * \param module_id BCMOS_MODULE_ID_USER_APPL_OMON
1066 * \param os_msg Message contents
1067 */
1068static
1069void omon_os_msg_handle(bcmos_module_id module_id, bcmos_msg *os_msg)
1070{
1071 omon_task_msg *msg = (omon_task_msg *)os_msg;
1072
1073 switch (msg->os_msg.type)
1074 {
1075 case BCMOS_MSG_ID_INITIATE_RX_POWER:
1076 omon_rssi_measurement_initiate(msg->session,
1077 &msg->link_key,
1078 msg->trigger_width_ns ,
1079 msg->trigger_delay_ns,
1080 msg->sample_period_us);
1081 break;
1082 case BCMOS_MSG_ID_INITIATE_TRX_STATUS:
1083
1084 omon_trx_status_initiate(msg->session,
1085 &msg->link_key);
1086 break;
1087 case BCMOS_MSG_ID_INITIATE_ROGUE_SCAN:
1088 omon_run_rogue_llid_scan(msg->session,
1089 &msg->link_key,
1090 msg->llid,
1091 msg->scan_mode);
1092
1093 break;
1094 case BCMOS_MSG_ID_INITIATE_RSSI_READ:
1095 omon_rssi_read_initiate(msg->session,
1096 &msg->link_key);
1097 break;
1098 default:
1099 break;
1100 }
1101 bcmos_free(os_msg);
1102} /* omon_os_msg_handle */
1103
1104
1105/**
1106 * \brief Start the optical monitoring task
1107 *
1108 * This function starts the user level optical monitoring task and creates the
1109 * optical monitoring module. It should only be called once at start up.
1110 *
1111 * \return
1112 * None
1113 */
1114void bcmolt_epon_omon_appl_init(void)
1115{
1116 bcmos_errno rc;
1117 bcmos_task_parm task_params =
1118 {
1119 .name = "user_appl_omon",
1120 .priority = TASK_PRIORITY_USER_APPL_OMON,
1121 .core = BCMOS_CPU_CORE_ANY, /* No CPU affinity */
1122 .init_handler = NULL
1123 };
1124 bcmos_module_parm module_params =
1125 {
1126 .qparm =
1127 {
1128 .name = "user_appl_omon",
1129 .size = OMON_TASK_MSG_Q_SIZE
1130 }
1131 };
1132
1133 if (is_running)
1134 {
1135 return;
1136 }
1137
1138 omon_log_id = bcm_dev_log_id_register("user_appl_omon",
1139 DEV_LOG_LEVEL_INFO,
1140 DEV_LOG_ID_TYPE_BOTH);
1141 BUG_ON(DEV_LOG_INVALID_ID == omon_log_id);
1142
1143 rc = bcmos_task_create(&omon_task, &task_params);
1144 BUG_ON(rc != BCM_ERR_OK);
1145
1146 rc = bcmos_module_create(BCMOS_MODULE_ID_USER_APPL_OMON, &omon_task,
1147 &module_params);
1148 BUG_ON(rc != BCM_ERR_OK);
1149
1150 is_running = BCMOS_TRUE;
1151} /* bcmolt_epon_omon_appl_init */
1152
1153
1154/*******************************************************************************
1155 * CLI
1156 ******************************************************************************/
1157
1158
1159/**
1160 * \brief RX power sample CLI command
1161 *
1162 * This function handles the "sample" CLI command. It processes the CLI
1163 * parameters and dispatches a start sample message to the optical monitoring
1164 * task.
1165 *
1166 * \param session CLI session ID
1167 * \param parm Command parameters
1168 * \param n_parms Number of parameters
1169 *
1170 * \return
1171 * BCM_ERR_OK if successful, error code if not
1172 */
1173static
1174bcmos_errno omon_cmd_rx_power(bcmcli_session *session,
1175 const bcmcli_cmd_parm parm[],
1176 uint16_t n_parms)
1177{
1178 omon_link_key link_key;
1179 bcmos_errno rc;
1180 bcmcli_cmd_parm *epon_ni;
1181 bcmcli_cmd_parm *mac_addr;
1182 bcmcli_cmd_parm *Twidth_ns;
1183 bcmcli_cmd_parm *Tdelay_ns;
1184 bcmcli_cmd_parm *Tsample_us;
1185 omon_task_msg *msg;
1186
1187 /* Get the CLI parameters. */
1188 epon_ni = bcmcli_find_named_parm(session, "epon_ni");
1189 mac_addr = bcmcli_find_named_parm(session, "granted_link");
1190 Twidth_ns = bcmcli_find_named_parm(session, "trigger_width"); // RSSI Twidth in ns
1191 Tdelay_ns = bcmcli_find_named_parm(session, "trigger_delay"); // RSSI Tdelay in ns
1192 Tsample_us = bcmcli_find_named_parm(session, "sample_period"); // RSSI Tsample in us
1193
1194 link_key.device_id = current_device;
1195 link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;
1196 link_key.mac_address = (bcmos_mac_address)mac_addr->value.mac;
1197
1198 /* Send an indication to the internal task's message queue to be
1199 processed. */
1200 msg = bcmos_calloc(sizeof(*msg));
1201 BUG_ON(msg == NULL);
1202 msg->os_msg.type = BCMOS_MSG_ID_INITIATE_RX_POWER;
1203 msg->os_msg.handler = omon_os_msg_handle;
1204 msg->link_key = link_key;
1205 msg->trigger_width_ns = Twidth_ns->value.number;
1206 msg->trigger_delay_ns = Tdelay_ns->value.number;
1207 msg->sample_period_us = Tsample_us->value.number;
1208 msg->session = session;
1209 rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
1210 &msg->os_msg, 0);
1211 BUG_ON(rc);
1212
1213
1214 return rc;
1215} /* omon_cmd_sample */
1216
1217static
1218bcmos_errno omon_cmd_trx_data(bcmcli_session *session,
1219 const bcmcli_cmd_parm parm[],
1220 uint16_t n_parms)
1221{
1222 omon_link_key link_key;
1223 bcmos_errno rc;
1224 bcmcli_cmd_parm *epon_ni;
1225 omon_task_msg *msg;
1226
1227 /* Get the CLI parameters. */
1228 epon_ni = bcmcli_find_named_parm(session, "epon_ni");
1229
1230 link_key.device_id = current_device;
1231 link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;
1232
1233 /* Send an indication to the internal task's message queue to be
1234 processed. */
1235 msg = bcmos_calloc(sizeof(*msg));
1236 BUG_ON(msg == NULL);
1237 msg->os_msg.type = BCMOS_MSG_ID_INITIATE_TRX_STATUS;
1238 msg->os_msg.handler = omon_os_msg_handle;
1239 msg->link_key = link_key;
1240 msg->session = session;
1241 rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
1242 &msg->os_msg, 0);
1243 BUG_ON(rc);
1244
1245
1246 return rc;
1247}
1248/* omon_cmd_trx_data */
1249
1250static
1251bcmos_errno omon_cmd_read_rssi_result(bcmcli_session *session,
1252 const bcmcli_cmd_parm parm[],
1253 uint16_t n_parms)
1254{
1255 omon_link_key link_key;
1256 bcmos_errno rc;
1257 bcmcli_cmd_parm *epon_ni;
1258 omon_task_msg *msg;
1259
1260 /* Get the CLI parameters. */
1261 epon_ni = bcmcli_find_named_parm(session, "epon_ni");
1262
1263 link_key.device_id = current_device;
1264 link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;
1265
1266 /* Send an indication to the internal task's message queue to be
1267 processed. */
1268 msg = bcmos_calloc(sizeof(*msg));
1269 BUG_ON(msg == NULL);
1270 msg->os_msg.type = BCMOS_MSG_ID_INITIATE_RSSI_READ;
1271 msg->os_msg.handler = omon_os_msg_handle;
1272 msg->link_key = link_key;
1273 msg->session = session;
1274 rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
1275 &msg->os_msg, 0);
1276 BUG_ON(rc);
1277
1278
1279 return rc;
1280}
1281/* omon_cmd_read_rssi_result */
1282
1283static
1284bcmos_errno omon_cmd_llid_scan(bcmcli_session *session,
1285 const bcmcli_cmd_parm parm[],
1286 uint16_t n_parms)
1287{
1288 omon_link_key link_key;
1289 bcmos_errno rc;
1290 bcmcli_cmd_parm *epon_ni;
1291 bcmcli_cmd_parm *epon_llid;
1292 bcmcli_cmd_parm *epon_mode;
1293 omon_task_msg *msg;
1294
1295 /* Get the CLI parameters. */
1296 epon_ni = bcmcli_find_named_parm(session, "epon_ni");
1297 epon_mode = bcmcli_find_named_parm(session, "scan_mode");
1298 epon_llid = bcmcli_find_named_parm(session, "epon_llid");
1299
1300 link_key.device_id = current_device;
1301 link_key.epon_ni = (bcmolt_epon_ni)epon_ni->value.number;
1302
1303 /* Send an indication to the internal task's message queue to be
1304 processed. */
1305 msg = bcmos_calloc(sizeof(*msg));
1306 BUG_ON(msg == NULL);
1307 msg->os_msg.type = BCMOS_MSG_ID_INITIATE_ROGUE_SCAN;
1308 msg->os_msg.handler = omon_os_msg_handle;
1309 msg->link_key = link_key;
1310 msg->session = session;
1311 msg->llid = epon_llid->value.number;
1312 msg->scan_mode = epon_mode->value.number;
1313 rc = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_OMON,
1314 &msg->os_msg, 0);
1315 BUG_ON(rc);
1316
1317
1318 return rc;
1319}
1320
1321
1322/**
1323 * \brief Install CLI commands
1324 *
1325 * This function creates and optical monitoring command directoy "omon" and
1326 * installs optical monitoring CLI commands to this directory.
1327 *
1328 * \param top_dir Parent of "omon" directory
1329 *
1330 * \return
1331 * BCM_ERR_OK if successful, error code if not
1332 */
1333void bcmolt_user_appl_epon_omon_cli_init(bcmcli_entry *top_dir)
1334{
1335 static const char *dir_name = "omon";
1336
1337 if (bcmcli_dir_find(top_dir, dir_name))
1338 {
1339 return;
1340 }
1341
1342 bcmcli_entry *dir = bcmcli_dir_add(top_dir,
1343 dir_name,
1344 "EPON optical monitoring commands",
1345 BCMCLI_ACCESS_ADMIN, NULL);
1346 BUG_ON(dir == NULL);
1347
1348 BCMCLI_MAKE_CMD(dir, "rx_power", "Issue RX Power Measurement", omon_cmd_rx_power,
1349 BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0),
1350 BCMCLI_MAKE_PARM("granted_link", "Link mac address, 000000000000 for Idle Power", BCMCLI_PARM_MAC, 0),
1351 BCMCLI_MAKE_PARM("trigger_width",
1352 "RSSI Trigger Width (Tw) in ns, Desired width of RSSI Trigger based on the Optical Module Specifications."
1353 "This is a mandatory parameter used for all RX Power measurements ( including Idle power) and must not be 0."
1354 "Note: The granularity of the device is 1 TQ (16ns) the input will be rounded up to the next TQ."
1355 , BCMCLI_PARM_NUMBER, 0),
1356 BCMCLI_MAKE_PARM("trigger_delay",
1357 "RSSI Trigger Delay (Td) in ns, Desired delay to meet the trigger delay timing requirement of the Optical Module Specifications."
1358 "The rssi trigger delay is measured from the start of sync_time and is adjusted as needed. "
1359 "The trigger delay moves the assertion of the RSSI Trigger strobe into the grant window."
1360 "Note: The granularity of the device is 1 TQ (16ns) the input will be rounded up to the next TQ."
1361 , BCMCLI_PARM_NUMBER, 0),
1362 BCMCLI_MAKE_PARM("sample_period",
1363 "(Ti2c) Sample period in uS, internal I2C hold/prohibit time where access to device is not allowed."
1364 "During this period the internal RSSI data is invalid and I2C opertions on this device must not be executed."
1365 "A value of 500uS is recommended for most applications. "
1366 , BCMCLI_PARM_NUMBER, 0));
1367
1368 BCMCLI_MAKE_CMD(dir, "trx_data", "Read Tranceiver Data", omon_cmd_trx_data,
1369 BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0));
1370
1371 BCMCLI_MAKE_CMD(dir, "read_rssi", "Read RSSI Result from Tranceiver", omon_cmd_read_rssi_result,
1372 BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0));
1373
1374 BCMCLI_MAKE_CMD(dir, "llid_scan", "Run Rogue ONU LLID Scan", omon_cmd_llid_scan,
1375 BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, 0),
1376 BCMCLI_MAKE_PARM("scan_mode", "LLID scan mode 1 for full pon scan, 0 for targeted (llid required for targeted)", BCMCLI_PARM_NUMBER, 0),
1377 BCMCLI_MAKE_PARM("epon_llid", "EPON llid to scan when mode=0", BCMCLI_PARM_HEX, 0));
1378}
1379/* bcmolt_user_appl_epon_omon_cli_init */
1380
1381
1382/* End of file omon.c */
1383