BAL and Maple Release 2.2
Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bal_release/src/common/db_engine/unitest.c b/bal_release/src/common/db_engine/unitest.c
new file mode 100644
index 0000000..ca638ce
--- /dev/null
+++ b/bal_release/src/common/db_engine/unitest.c
@@ -0,0 +1,490 @@
+/******************************************************************************
+ *
+ * <:copyright-BRCM:2016:DUAL/GPL:standard
+ *
+ * Copyright (c) 2016 Broadcom
+ * All Rights Reserved
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2
+ * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+ * with the following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give
+ * you permission to link this software with independent modules, and
+ * to copy and distribute the resulting executable under terms of your
+ * choice, provided that you also meet, for each linked independent
+ * module, the terms and conditions of the license of that module.
+ * An independent module is a module which is not derived from this
+ * software. The special exception does not apply to any modifications
+ * of the software.
+ *
+ * Not withstanding the above, under no circumstances may you combine
+ * this software in any way with any other Broadcom software provided
+ * under a license other than the GPL, without Broadcom's express prior
+ * written consent.
+ *
+ * :>
+ *
+ *****************************************************************************/
+
+/*
+ * unitest.c
+ *
+ * Created on: 2013-12-10
+ * Author: swallace
+ */
+
+#include "bcmos_system.h"
+#include "bcm_db_engine.h"
+
+/* EPON LLID data structure subset */
+typedef enum
+ {
+ /* Free entry in the LLID management table, available for assignment on an
+ MPCP register request. */
+ unassigned_llid,
+ /* Locked out waiting on a timer to release the LLID */
+ not_registered_llid,
+ /* Waiting for permission to register from host */
+ ignored_llid,
+ /* LLID has been assigned to an ONU MAC but not registered. Intermediate
+ state before the ONU returns a registration ack. */
+ wait_reg_ack_llid,
+ /* OLT link is in-service; user traffic is allowed */
+ inservice_llid,
+ wait_no_reports_llid,
+ /* The following state only applies to multicast/flood links */
+ in_service_mcast_llid,
+ /* We want a "Reserved" state for things like Optical monitoring */
+ reserved_llid,
+ /* We have detected a rogue ONU on this LLID - don't use it! */
+ quarantined_llid,
+ llid_state_count,
+ } epon_olt_llid_state;
+
+static char *get_llid_state_string(epon_olt_llid_state llid_state)
+{
+ static char *llid_state_strings[]= {
+ "unassigned",
+ "not_registered",
+ "ignored",
+ "wait_reg_ack",
+ "inservice",
+ "wait_no_reports",
+ "in_service_mcast",
+ "reserved",
+ "quarantined"
+ };
+
+ return llid_state_strings[(uint16_t)(llid_state)];
+}
+
+#define MAX_LINKS_PER_PORT 512
+#define MAX_PORTS_PER_HALF_CHIP 8
+#define MAX_LINKS_PER_HALF_CHIP ((MAX_LINKS_PER_PORT)*(MAX_PORTS_PER_HALF_CHIP))
+
+typedef uint8_t core_epon;
+typedef uint16_t hw_link_index;
+
+typedef struct epon_db_olt_llid_rec
+ {
+ epon_olt_llid_state state;
+ core_epon epon;
+ hw_link_index index;
+ } epon_db_olt_llid_rec;
+
+
+typedef struct epon_msg_olt_llid_rec
+{
+ uint16_t index;
+ epon_db_olt_llid_rec llid_rec;
+} epon_msg_olt_llid_rec;
+
+typedef enum
+ {
+ enabled,
+ disabled,
+ } epon_olt_port_state;
+
+static char *get_port_state_string(epon_olt_port_state port_state)
+{
+ static char *port_state_strings[]= {
+ "enabled",
+ "disabled",
+ };
+
+ return port_state_strings[(uint16_t)(port_state)];
+}
+
+
+typedef struct epon_db_olt_port_rec
+ {
+ epon_olt_port_state state;
+ } epon_db_olt_port_rec;
+
+typedef struct epon_msg_olt_port_rec
+{
+ uint16_t index;
+ epon_db_olt_port_rec port_rec;
+} epon_msg_olt_port_rec;
+
+typedef enum
+{
+ epon_olt_link_record,
+ epon_olt_port_record,
+ num_db_tables,
+} db_tables;
+
+
+/* Master database handle */
+static bcmdb_set *db_sos_set;
+
+static bcmdb_set* epon_get_db_handle(void)
+{
+ return db_sos_set;
+}
+
+#define LINK_REC_DB() bcmdb_set *db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_link_record)
+
+#define PORT_REC_DB bcmdb_set *db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record)
+
+/* Database test messages - */
+typedef enum
+ {
+ update_link_db = 20,
+ update_port_db = 21,
+ dump_db = 30,
+ } dbtest_msgid;
+
+static inline const epon_db_olt_llid_rec *epon_olt_get_llid_rec_read(uint16_t index)
+ {
+ LINK_REC_DB();
+ return bcmdb_record_get_read(db_set, index, epon_db_olt_llid_rec);
+ };
+
+static inline void epon_db_olt_unlock_llid_rec(uint16_t index)
+ {
+ LINK_REC_DB();
+ bcmdb_record_unlock_read(db_set, index);
+ }
+
+
+#define OltGetLlidRecWrite(index) \
+ ({ \
+ LINK_REC_DB(); \
+ bcmdb_record_get_write(db_set, index, epon_db_olt_llid_rec);\
+ })
+
+#define OltCommitLlidRec(index) \
+ ({ \
+ LINK_REC_DB(); \
+ bcmdb_record_unlock_write(db_set, BCMOS_FALSE);\
+ })
+
+
+static void ut_dump_db(void)
+{
+ uint16_t index;
+ bcmdb_set *db_set;
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
+ for (index = 0; index < MAX_PORTS_PER_HALF_CHIP; index++)
+ {
+ const epon_db_olt_port_rec *port_rec;
+ port_rec = bcmdb_record_get_read(db_set, index, epon_db_olt_port_rec);
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
+ "Record %d, state %s\n", index,
+ get_port_state_string(port_rec->state));
+ bcmdb_record_unlock_read(db_set, index);
+ }
+
+ for (index = 0; index < MAX_LINKS_PER_HALF_CHIP; index++)
+ {
+ const epon_db_olt_llid_rec *llid_rec;
+ llid_rec = epon_olt_get_llid_rec_read(index);
+ if (llid_rec->state != unassigned_llid)
+ {
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
+ "Record %d, port %d, state %s\n", llid_rec->index,
+ llid_rec->epon, get_llid_state_string(llid_rec->state));
+ }
+ epon_db_olt_unlock_llid_rec(index);
+ }
+
+
+}
+
+static void ut_update_link_db(epon_msg_olt_llid_rec *rec)
+{
+ epon_db_olt_llid_rec *llid_rec;
+ llid_rec=OltGetLlidRecWrite(rec->index);
+ llid_rec->state=rec->llid_rec.state;
+
+ OltCommitLlidRec(index);
+}
+
+static void ut_update_port_db(epon_msg_olt_port_rec *rec)
+{
+ bcmdb_set *db_set;
+ epon_db_olt_port_rec *port_rec;
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
+ port_rec = bcmdb_record_get_write(db_set, rec->index, epon_db_olt_port_rec);
+
+ port_rec->state=rec->port_rec.state;
+
+ bcmdb_record_unlock_write(db_set, BCMOS_FALSE);
+}
+
+
+static void ut_msg_handler(dbtest_msgid id, void *data)
+ {
+ switch (id)
+ {
+ case update_link_db:
+ ut_update_link_db((epon_msg_olt_llid_rec*)data);
+ break;
+
+ case update_port_db:
+ ut_update_port_db((epon_msg_olt_port_rec*)data);
+ break;
+
+ case dump_db:
+ ut_dump_db();
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+/* Database engine unit test functions */
+static uint16_t epon_db_data_init(void)
+ {
+ uint16_t index;
+ bcmdb_set *db_set;
+ int rc = 0;
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_link_record);
+ for ( index = 0;
+ (index < MAX_LINKS_PER_HALF_CHIP) && (rc >= 0) && (db_set != NULL) ;
+ index++)
+ {
+ epon_db_olt_llid_rec llid_rec;
+
+ llid_rec.state = unassigned_llid;
+ llid_rec.epon = index/MAX_LINKS_PER_PORT;
+ llid_rec.index = index;
+ rc = bcmdb_record_add(db_set, index, (void *)&llid_rec);
+ }
+
+ db_set = bcmdb_set_handle(epon_get_db_handle(), epon_olt_port_record);
+ for ( index = 0;
+ (index < MAX_PORTS_PER_HALF_CHIP) && (rc >= 0) && (db_set != NULL) ;
+ index++)
+ {
+ epon_db_olt_port_rec port_rec;
+ port_rec.state = disabled;
+ rc = bcmdb_record_add(db_set, index, (void *)&port_rec);
+ }
+ return rc;
+ }
+
+static int epon_db_instance_init(void)
+ {
+ bcmdb_sos_init db_sos_inst;
+ bcmdb_sor_init db_sor_inst;
+ const char* db_name = "EPON STACK";
+ const char* db_llid_name = "EPON LINK REC";
+ const char* db_eport_name = "EPON PORT REC";
+ bcmdb_set *db_sor_set;
+ int rc;
+
+ db_sos_inst.name = db_name;
+ db_sos_inst.backend_type = BCMDB_BACKEND_ARRAY;
+ db_sos_inst.max_entries = num_db_tables;
+ rc = bcmdb_make_set_of_sets(&db_sos_inst, &db_sos_set);
+
+ if (rc >= 0)
+ {
+ db_sor_inst.name = db_llid_name;
+ db_sor_inst.backend_type = BCMDB_BACKEND_ARRAY;
+ db_sor_inst.lock_policy = BCMDB_LOCK_NB_READ_SHADOW_WRITE;
+ db_sor_inst.max_entries = MAX_LINKS_PER_HALF_CHIP;
+ db_sor_inst.record_size = sizeof(epon_db_olt_llid_rec);
+ db_sor_inst.format = NULL;
+ bcmdb_make_set_of_records(&db_sor_inst, BCMOS_TRUE, &db_sor_set);
+
+ rc = bcmdb_set_add(epon_get_db_handle(),
+ epon_olt_link_record, db_sor_set);
+ }
+ if (rc >= 0)
+ {
+ db_sor_inst.name = db_eport_name;
+ db_sor_inst.backend_type = BCMDB_BACKEND_ARRAY;
+ db_sor_inst.lock_policy = BCMDB_LOCK_NB_READ_SHADOW_WRITE;
+ db_sor_inst.max_entries = MAX_PORTS_PER_HALF_CHIP;
+ db_sor_inst.record_size = sizeof(epon_db_olt_port_rec);
+ db_sor_inst.format = NULL;
+ rc = bcmdb_make_set_of_records(&db_sor_inst, BCMOS_TRUE, &db_sor_set);
+ }
+
+ rc = bcmdb_set_add(epon_get_db_handle(), epon_olt_port_record, db_sor_set);
+
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "database creation returnd %d\n", rc);
+
+ if (rc >= 0)
+ {
+ rc = epon_db_data_init();
+ }
+ return rc;
+ }
+
+/* Thread handlers - so that the DB accesses can be tested across multiple
+ threads. */
+static int task1_handler(long data)
+{
+ bcmos_msg_queue *q = (bcmos_msg_queue *)data;
+ bcmos_msg *msg;
+
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "traditional task handler\n");
+
+ while (1)
+ {
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "Waiting for message\n");
+
+ bcmos_msg_recv(q, BCMOS_WAIT_FOREVER, &msg);
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO,
+ "Received message ID %d, data %p\n",
+ msg->type, msg->data);
+
+ ut_msg_handler(msg->type, msg->data);
+ bcmos_usleep(100000);
+ }
+
+ return 0;
+}
+
+
+static bcmos_errno mod1_init(long data)
+{
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "%ld\n", data);
+ return BCM_ERR_OK;
+}
+
+static void mod_msg_handler(bcmos_module_id module_id, bcmos_msg *msg)
+{
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "module %d msg %d data %p\n",
+ module_id, msg->type, msg->data);
+
+ ut_msg_handler(msg->type, msg->data);
+}
+
+
+
+/* Unit test function - */
+int main(int argc, char *argv[])
+{
+ bcmos_task_parm tp = {};
+ bcmos_msg_queue_parm qp = {};
+ bcmos_module_parm mp = {};
+ bcmos_msg msg1 = {};
+ bcmos_msg msg2 = {};
+
+ bcmos_task t1;
+ bcmos_task t2;
+ bcmos_msg_queue q1;
+ bcmos_errno rc;
+ epon_msg_olt_llid_rec link_rec1, link_rec2;
+ epon_msg_olt_port_rec port_msg1, port_msg2;
+
+ bcmos_init();
+ bcmos_trace_level_set(BCMOS_TRACE_LEVEL_DEBUG);
+
+ if (epon_db_instance_init() < 0)
+ {
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_ERROR,
+ "Could not instantiate a Database\n");
+ return BCM_ERR_NOMEM;
+ }
+
+ BCMOS_TRACE(BCMOS_TRACE_LEVEL_INFO, "Database set %p\n",
+ bcmdb_set_handle(db_sos_set, epon_olt_link_record));
+
+ /* Create message queue */
+ qp.name = "msg queue1";
+ qp.size = 16;
+ qp.high_wm = 14;
+ qp.low_wm = 12;
+ rc = bcmos_msg_queue_create(&q1, &qp);
+
+ /* Create a couple of threads */
+ tp.name = "task1";
+ tp.handler = task1_handler;
+ tp.data = (long)&q1;
+ rc = bcmos_task_create(&t1, &tp);
+
+ tp.name = "task2";
+ tp.handler = NULL;
+ tp.data = 0;
+ rc = bcmos_task_create(&t2, &tp);
+
+ /* Register a module */
+ mp.qparm.name = "module1";
+ mp.qparm.size = 16;
+ mp.init = mod1_init;
+ bcmos_module_create(BCMOS_MODULE_ID_TEST1, &t2, &mp);
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ /* Send a message to update the DB - enable a port*/
+ port_msg1.index=5;
+ port_msg1.port_rec.state=enabled;
+ msg1.type = update_port_db;
+ msg1.data = &port_msg1;
+ bcmos_msg_send(&q1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Send a message to update the DB - enable a port*/
+ port_msg2.index=3;
+ port_msg2.port_rec.state=enabled;
+ msg2.type = update_port_db;
+ msg2.data = &port_msg2;
+ bcmos_msg_send(&q1, &msg2, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ /* Send a message to update the DB - put a link In Service*/
+ link_rec1.index=14;
+ link_rec1.llid_rec.state=inservice_llid;
+ msg1.type = update_link_db;
+ msg1.data = &link_rec1;
+ bcmos_msg_send(&q1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Send a message to update the DB - quarantine a link */
+ link_rec2.index=22;
+ link_rec2.llid_rec.state=quarantined_llid;
+ msg2.type = update_link_db;
+ msg2.data = &link_rec2;
+ msg2.handler = mod_msg_handler;
+ bcmos_msg_send_to_module(BCMOS_MODULE_ID_TEST1, &msg2, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ /* Send a message to dump the DB */
+ msg1.type = dump_db;
+ msg1.handler = mod_msg_handler;
+ msg1.data = NULL;
+ bcmos_msg_send_to_module(BCMOS_MODULE_ID_TEST1, &msg1, BCMOS_MSG_SEND_NO_FREE_ON_ERROR);
+
+
+ /* Wait some */
+ bcmos_usleep(2000000);
+
+ return rc;
+}