blob: ca638cea04a11737abba78ae747d48738e5167da [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/******************************************************************************
2 *
3 * <:copyright-BRCM:2016:DUAL/GPL:standard
4 *
5 * Copyright (c) 2016 Broadcom
6 * All Rights Reserved
7 *
8 * Unless you and Broadcom execute a separate written software license
9 * agreement governing use of this software, this software is licensed
10 * to you under the terms of the GNU General Public License version 2
11 * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
12 * with the following added to such license:
13 *
14 * As a special exception, the copyright holders of this software give
15 * you permission to link this software with independent modules, and
16 * to copy and distribute the resulting executable under terms of your
17 * choice, provided that you also meet, for each linked independent
18 * module, the terms and conditions of the license of that module.
19 * An independent module is a module which is not derived from this
20 * software. The special exception does not apply to any modifications
21 * of the software.
22 *
23 * Not withstanding the above, under no circumstances may you combine
24 * this software in any way with any other Broadcom software provided
25 * under a license other than the GPL, without Broadcom's express prior
26 * written consent.
27 *
28 * :>
29 *
30 *****************************************************************************/
31
32/*
33 * unitest.c
34 *
35 * Created on: 2013-12-10
36 * Author: swallace
37 */
38
39#include "bcmos_system.h"
40#include "bcm_db_engine.h"
41
42/* EPON LLID data structure subset */
43typedef enum
44 {
45 /* Free entry in the LLID management table, available for assignment on an
46 MPCP register request. */
47 unassigned_llid,
48 /* Locked out waiting on a timer to release the LLID */
49 not_registered_llid,
50 /* Waiting for permission to register from host */
51 ignored_llid,
52 /* LLID has been assigned to an ONU MAC but not registered. Intermediate
53 state before the ONU returns a registration ack. */
54 wait_reg_ack_llid,
55 /* OLT link is in-service; user traffic is allowed */
56 inservice_llid,
57 wait_no_reports_llid,
58 /* The following state only applies to multicast/flood links */
59 in_service_mcast_llid,
60 /* We want a "Reserved" state for things like Optical monitoring */
61 reserved_llid,
62 /* We have detected a rogue ONU on this LLID - don't use it! */
63 quarantined_llid,
64 llid_state_count,
65 } epon_olt_llid_state;
66
67static char *get_llid_state_string(epon_olt_llid_state llid_state)
68{
69 static char *llid_state_strings[]= {
70 "unassigned",
71 "not_registered",
72 "ignored",
73 "wait_reg_ack",
74 "inservice",
75 "wait_no_reports",
76 "in_service_mcast",
77 "reserved",
78 "quarantined"
79 };
80
81 return llid_state_strings[(uint16_t)(llid_state)];
82}
83
84#define MAX_LINKS_PER_PORT 512
85#define MAX_PORTS_PER_HALF_CHIP 8
86#define MAX_LINKS_PER_HALF_CHIP ((MAX_LINKS_PER_PORT)*(MAX_PORTS_PER_HALF_CHIP))
87
88typedef uint8_t core_epon;
89typedef uint16_t hw_link_index;
90
91typedef struct epon_db_olt_llid_rec
92 {
93 epon_olt_llid_state state;
94 core_epon epon;
95 hw_link_index index;
96 } epon_db_olt_llid_rec;
97
98
99typedef struct epon_msg_olt_llid_rec
100{
101 uint16_t index;
102 epon_db_olt_llid_rec llid_rec;
103} epon_msg_olt_llid_rec;
104
105typedef enum
106 {
107 enabled,
108 disabled,
109 } epon_olt_port_state;
110
111static char *get_port_state_string(epon_olt_port_state port_state)
112{
113 static char *port_state_strings[]= {
114 "enabled",
115 "disabled",
116 };
117
118 return port_state_strings[(uint16_t)(port_state)];
119}
120
121
122typedef struct epon_db_olt_port_rec
123 {
124 epon_olt_port_state state;
125 } epon_db_olt_port_rec;
126
127typedef struct epon_msg_olt_port_rec
128{
129 uint16_t index;
130 epon_db_olt_port_rec port_rec;
131} epon_msg_olt_port_rec;
132
133typedef enum
134{
135 epon_olt_link_record,
136 epon_olt_port_record,
137 num_db_tables,
138} db_tables;
139
140
141/* Master database handle */
142static bcmdb_set *db_sos_set;
143
144static bcmdb_set* epon_get_db_handle(void)
145{
146 return db_sos_set;
147}
148
149#define LINK_REC_DB() bcmdb_set *db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_link_record)
150
151#define PORT_REC_DB bcmdb_set *db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record)
152
153/* Database test messages - */
154typedef enum
155 {
156 update_link_db = 20,
157 update_port_db = 21,
158 dump_db = 30,
159 } dbtest_msgid;
160
161static inline const epon_db_olt_llid_rec *epon_olt_get_llid_rec_read(uint16_t index)
162 {
163 LINK_REC_DB();
164 return bcmdb_record_get_read(db_set, index, epon_db_olt_llid_rec);
165 };
166
167static inline void epon_db_olt_unlock_llid_rec(uint16_t index)
168 {
169 LINK_REC_DB();
170 bcmdb_record_unlock_read(db_set, index);
171 }
172
173
174#define OltGetLlidRecWrite(index) \
175 ({ \
176 LINK_REC_DB(); \
177 bcmdb_record_get_write(db_set, index, epon_db_olt_llid_rec);\
178 })
179
180#define OltCommitLlidRec(index) \
181 ({ \
182 LINK_REC_DB(); \
183 bcmdb_record_unlock_write(db_set, BCMOS_FALSE);\
184 })
185
186
187static void ut_dump_db(void)
188{
189 uint16_t index;
190 bcmdb_set *db_set;
191
192 db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
193 for (index = 0; index < MAX_PORTS_PER_HALF_CHIP; index++)
194 {
195 const epon_db_olt_port_rec *port_rec;
196 port_rec = bcmdb_record_get_read(db_set, index, epon_db_olt_port_rec);
197 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
198 "Record %d, state %s\n", index,
199 get_port_state_string(port_rec->state));
200 bcmdb_record_unlock_read(db_set, index);
201 }
202
203 for (index = 0; index < MAX_LINKS_PER_HALF_CHIP; index++)
204 {
205 const epon_db_olt_llid_rec *llid_rec;
206 llid_rec = epon_olt_get_llid_rec_read(index);
207 if (llid_rec->state != unassigned_llid)
208 {
209 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
210 "Record %d, port %d, state %s\n", llid_rec->index,
211 llid_rec->epon, get_llid_state_string(llid_rec->state));
212 }
213 epon_db_olt_unlock_llid_rec(index);
214 }
215
216
217}
218
219static void ut_update_link_db(epon_msg_olt_llid_rec *rec)
220{
221 epon_db_olt_llid_rec *llid_rec;
222 llid_rec=OltGetLlidRecWrite(rec->index);
223 llid_rec->state=rec->llid_rec.state;
224
225 OltCommitLlidRec(index);
226}
227
228static void ut_update_port_db(epon_msg_olt_port_rec *rec)
229{
230 bcmdb_set *db_set;
231 epon_db_olt_port_rec *port_rec;
232
233 db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
234 port_rec = bcmdb_record_get_write(db_set, rec->index, epon_db_olt_port_rec);
235
236 port_rec->state=rec->port_rec.state;
237
238 bcmdb_record_unlock_write(db_set, BCMOS_FALSE);
239}
240
241
242static void ut_msg_handler(dbtest_msgid id, void *data)
243 {
244 switch (id)
245 {
246 case update_link_db:
247 ut_update_link_db((epon_msg_olt_llid_rec*)data);
248 break;
249
250 case update_port_db:
251 ut_update_port_db((epon_msg_olt_port_rec*)data);
252 break;
253
254 case dump_db:
255 ut_dump_db();
256 break;
257
258 default:
259 break;
260 }
261
262 }
263
264/* Database engine unit test functions */
265static uint16_t epon_db_data_init(void)
266 {
267 uint16_t index;
268 bcmdb_set *db_set;
269 int rc = 0;
270
271 db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_link_record);
272 for ( index = 0;
273 (index < MAX_LINKS_PER_HALF_CHIP) && (rc >= 0) && (db_set != NULL) ;
274 index++)
275 {
276 epon_db_olt_llid_rec llid_rec;
277
278 llid_rec.state = unassigned_llid;
279 llid_rec.epon = index/MAX_LINKS_PER_PORT;
280 llid_rec.index = index;
281 rc = bcmdb_record_add(db_set, index, (void *)&llid_rec);
282 }
283
284 db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
285 for ( index = 0;
286 (index < MAX_PORTS_PER_HALF_CHIP) && (rc >= 0) && (db_set != NULL) ;
287 index++)
288 {
289 epon_db_olt_port_rec port_rec;
290 port_rec.state = disabled;
291 rc = bcmdb_record_add(db_set, index, (void *)&port_rec);
292 }
293 return rc;
294 }
295
296static int epon_db_instance_init(void)
297 {
298 bcmdb_sos_init db_sos_inst;
299 bcmdb_sor_init db_sor_inst;
300 const char* db_name = "EPON STACK";
301 const char* db_llid_name = "EPON LINK REC";
302 const char* db_eport_name = "EPON PORT REC";
303 bcmdb_set *db_sor_set;
304 int rc;
305
306 db_sos_inst.name = db_name;
307 db_sos_inst.backend_type = BCMDB_BACKEND_ARRAY;
308 db_sos_inst.max_entries = num_db_tables;
309 rc = bcmdb_make_set_of_sets(&db_sos_inst, &db_sos_set);
310
311 if (rc >= 0)
312 {
313 db_sor_inst.name = db_llid_name;
314 db_sor_inst.backend_type = BCMDB_BACKEND_ARRAY;
315 db_sor_inst.lock_policy = BCMDB_LOCK_NB_READ_SHADOW_WRITE;
316 db_sor_inst.max_entries = MAX_LINKS_PER_HALF_CHIP;
317 db_sor_inst.record_size = sizeof(epon_db_olt_llid_rec);
318 db_sor_inst.format = NULL;
319 bcmdb_make_set_of_records(&db_sor_inst, BCMOS_TRUE, &db_sor_set);
320
321 rc = bcmdb_set_add(epon_get_db_handle(),
322 epon_olt_link_record, db_sor_set);
323 }
324 if (rc >= 0)
325 {
326 db_sor_inst.name = db_eport_name;
327 db_sor_inst.backend_type = BCMDB_BACKEND_ARRAY;
328 db_sor_inst.lock_policy = BCMDB_LOCK_NB_READ_SHADOW_WRITE;
329 db_sor_inst.max_entries = MAX_PORTS_PER_HALF_CHIP;
330 db_sor_inst.record_size = sizeof(epon_db_olt_port_rec);
331 db_sor_inst.format = NULL;
332 rc = bcmdb_make_set_of_records(&db_sor_inst, BCMOS_TRUE, &db_sor_set);
333 }
334
335 rc = bcmdb_set_add(epon_get_db_handle(), epon_olt_port_record, db_sor_set);
336
337 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "database creation returnd %d\n", rc);
338
339 if (rc >= 0)
340 {
341 rc = epon_db_data_init();
342 }
343 return rc;
344 }
345
346/* Thread handlers - so that the DB accesses can be tested across multiple
347 threads. */
348static int task1_handler(long data)
349{
350 bcmos_msg_queue *q = (bcmos_msg_queue *)data;
351 bcmos_msg *msg;
352
353 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "traditional task handler\n");
354
355 while (1)
356 {
357 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "Waiting for message\n");
358
359 bcmos_msg_recv(q, BCMOS_WAIT_FOREVER, &msg);
360 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
361 "Received message ID %d, data %p\n",
362 msg->type, msg->data);
363
364 ut_msg_handler(msg->type, msg->data);
365 bcmos_usleep(100000);
366 }
367
368 return 0;
369}
370
371
372static bcmos_errno mod1_init(long data)
373{
374 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "%ld\n", data);
375 return BCM_ERR_OK;
376}
377
378static void mod_msg_handler(bcmos_module_id module_id, bcmos_msg *msg)
379{
380 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "module %d msg %d data %p\n",
381 module_id, msg->type, msg->data);
382
383 ut_msg_handler(msg->type, msg->data);
384}
385
386
387
388/* Unit test function - */
389int main(int argc, char *argv[])
390{
391 bcmos_task_parm tp = {};
392 bcmos_msg_queue_parm qp = {};
393 bcmos_module_parm mp = {};
394 bcmos_msg msg1 = {};
395 bcmos_msg msg2 = {};
396
397 bcmos_task t1;
398 bcmos_task t2;
399 bcmos_msg_queue q1;
400 bcmos_errno rc;
401 epon_msg_olt_llid_rec link_rec1, link_rec2;
402 epon_msg_olt_port_rec port_msg1, port_msg2;
403
404 bcmos_init();
405 bcmos_trace_level_set(BCMOS_TRACE_LEVEL_DEBUG);
406
407 if (epon_db_instance_init() < 0)
408 {
409 BCMOS_TRACE(BCMOS_TRACE_LEVEL_ERROR,
410 "Could not instantiate a Database\n");
411 return BCM_ERR_NOMEM;
412 }
413
414 BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "Database set %p\n",
415 bcmdb_set_handle(db_sos_set, epon_olt_link_record));
416
417 /* Create message queue */
418 qp.name = "msg queue1";
419 qp.size = 16;
420 qp.high_wm = 14;
421 qp.low_wm = 12;
422 rc = bcmos_msg_queue_create(&q1, &qp);
423
424 /* Create a couple of threads */
425 tp.name = "task1";
426 tp.handler = task1_handler;
427 tp.data = (long)&q1;
428 rc = bcmos_task_create(&t1, &tp);
429
430 tp.name = "task2";
431 tp.handler = NULL;
432 tp.data = 0;
433 rc = bcmos_task_create(&t2, &tp);
434
435 /* Register a module */
436 mp.qparm.name = "module1";
437 mp.qparm.size = 16;
438 mp.init = mod1_init;
439 bcmos_module_create(BCMOS_MODULE_ID_TEST1, &t2, &mp);
440
441 /* Wait some */
442 bcmos_usleep(2000000);
443
444 /* Send a message to update the DB - enable a port*/
445 port_msg1.index=5;
446 port_msg1.port_rec.state=enabled;
447 msg1.type = update_port_db;
448 msg1.data = &port_msg1;
449 bcmos_msg_send(&q1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
450
451 /* Send a message to update the DB - enable a port*/
452 port_msg2.index=3;
453 port_msg2.port_rec.state=enabled;
454 msg2.type = update_port_db;
455 msg2.data = &port_msg2;
456 bcmos_msg_send(&q1, &msg2, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
457
458 /* Wait some */
459 bcmos_usleep(2000000);
460
461 /* Send a message to update the DB - put a link In Service*/
462 link_rec1.index=14;
463 link_rec1.llid_rec.state=inservice_llid;
464 msg1.type = update_link_db;
465 msg1.data = &link_rec1;
466 bcmos_msg_send(&q1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
467
468 /* Send a message to update the DB - quarantine a link */
469 link_rec2.index=22;
470 link_rec2.llid_rec.state=quarantined_llid;
471 msg2.type = update_link_db;
472 msg2.data = &link_rec2;
473 msg2.handler = mod_msg_handler;
474 bcmos_msg_send_to_module(BCMOS_MODULE_ID_TEST1, &msg2, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
475
476 /* Wait some */
477 bcmos_usleep(2000000);
478
479 /* Send a message to dump the DB */
480 msg1.type = dump_db;
481 msg1.handler = mod_msg_handler;
482 msg1.data = NULL;
483 bcmos_msg_send_to_module(BCMOS_MODULE_ID_TEST1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
484
485
486 /* Wait some */
487 bcmos_usleep(2000000);
488
489 return rc;
490}