Open Ethernet Networking (OpEN) API Guide and Reference Manual  3.6.0.3
instru_example.c
/*********************************************************************
*
* Copyright 2016-2018 Broadcom.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*************************************************************************
*
* @filename instru_example.c
*
* @purpose Instrumentation - Buffer Statistics Tracking (BST) Example.
*
* @component OPEN
*
* @note
*
* @create 6/25/2015
*
* @end
*
***************************************************************************/
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include "zlib.h"
#include "rpcclt_openapi.h"
#include "proc_util.h"
#include "openapi_common.h"
/* This is the ASIC internal cell size. It depends on the platform,
for trident 2, this is 208 */
#define ASIC_CELL_SIZE 208
/* These are the example(sample) resources, for which buffer counts are printed.
Any resource number (for example port number, queue number) can be used,
depending on the platform (0 to maximum ports/queue numbers).To observe
non-zero buffer count values, user has to select the resources where traffic is actively flowing. */
/* sample port numbers, where traffic is presently flowing */
#define SAMPLE_PORT_1 1
#define SAMPLE_PORT_2 2
#define SAMPLE_PORT_3 3
/* The sample Lag number */
#define SAMPLE_LAG_1 0
/* The sample ingress port priority groups */
#define SAMPLE_PG_1 1
#define SAMPLE_PG_2 2
/* The sample service pools.
At present only serivce pool 0 is used. */
#define SAMPLE_SP_1 0
#define SAMPLE_SP_2 1
/* The sample unicast, multicast, cpu, rqe queues(queue numbers) */
#define SAMPLE_UCQ_1 16
#define SAMPLE_UCQ_2 48
#define SAMPLE_UCQG_1 10
#define SAMPLE_UCQG_2 12
#define SAMPLE_MCQ_1 15
#define SAMPLE_MCQ_2 22
#define SAMPLE_CPUQ_1 5
#define SAMPLE_CPUQ_2 4
#define SAMPLE_RQE_1 8
#define SAMPLE_RQE_2 5
/* Sample thresholds, these thresholds are applied for various resources to
check the threshold configuration */
#define DEVICE_THRESH_SAMPLE_1 832
#define IPPG_THRESH_SHARED_SAMPLE_1 1001
#define IPPG_THRESH_HEADROOM_SAMPLE_1 1002
#define IPSP_THRESHOLD_SAMPLE_1 2001
#define ISP_THRESHOLD_SAMPLE_1 2402
#define EPSP_UC_THRESHOLD_SAMPLE_1 1664
#define EPSP_UM_THRESHOLD_SAMPLE_1 3328
#define EPSP_MC_THRESHOLD_SAMPLE_1 4992
#define EPSP_MC_SHARE_THRESHOLD_SAMPLE_1 6001
#define ESP_UM_THRESHOLD_SAMPLE_1 1664
#define ESP_MC_THRESHOLD_SAMPLE_1 4992
#define ESP_MC_SHARE_THRESHOLD_SAMPLE_1 3903
#define UCQ_THRESHOLD_SAMPLE_1 4801
#define UCQG_THRESHOLD_SAMPLE_1 4801
#define MCQB_THRESHOLD_SAMPLE_1 4982
#define MCQQ_THRESHOLD_SAMPLE_1 502
#define CPUQB_THRESHOLD_SAMPLE_1 600
#define CPUQQ_THRESHOLD_SAMPLE_1 601
#define RQEB_THRESHOLD_SAMPLE_1 50
#define RQEQ_THRESHOLD_SAMPLE_1 51
/* RPC parameter data area maximum */
#define BST_RPC_PARM_DATA_AREA_MAX (256 * 1024)
/* Max size of all RPC parameter data. Instrumentaion app requires more RPC data size. */
#define BST_RPC_DEVMSG_DATA_MAX (BST_RPC_PARM_DATA_AREA_MAX * 2)
#define BST_MAX_COMPRESSED_LEN (BST_RPC_DEVMSG_DATA_MAX - 1024)
void *cookie;
uint32_t cb_cookie;
bool trigger_event = false;
/* structure to hold ASIC capabilities, the information of this structure is
used by all the functions and while configuring many resources. */
/*************************************************************************/
open_error_t testAsicBasic(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
printf("Testing API -- openapiBstAsicCapabilityGet\n");
printf("------------------------------------------\n\n");
result = openapiBstAsicCapabilityGet(clientHandle, asicId, &asicInfo);
if (OPEN_E_NONE == result)
{
printf("Displaying Basic ASIC Capabilities\n");
printf("---------------------------------- \n");
printf("Number of ports %d\n", asicInfo.numPorts);
printf("Number of unicast queues %d\n", asicInfo.numUnicastQueues);
printf("Number of unicast queues groups %d\n", asicInfo.numUnicastQueueGroups);
printf("Number of multicast queues %d\n", asicInfo.numMulticastQueues);
printf("Number of service pools %d\n", asicInfo.numServicePools);
printf("Number of common pools %d\n", asicInfo.numCommonPools);
printf("Number of CPU queues %d\n", asicInfo.numCpuQueues);
printf("Number of RQE queues %d\n", asicInfo.numRqeQueues);
printf("Number of RQE pools %d\n", asicInfo.numRqeQueuePools);
printf("Number of priority groups %d\n", asicInfo.numPriorityGroups);
}
return result;
}
/*************************************************************************/
open_error_t testAsicPortMap(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
OPEN_ASIC_PORT_MAP_t portMapData;
uint32_t port;
printf("\n\n");
printf("Testing API -- openapiPortMappingGet\n");
printf("-------------------------------------------\n");
result = openapiPortMappingGet(clientHandle, asicId, &portMapData);
if (OPEN_E_NONE == result)
{
printf("Ports mapped to this ASIC\n");
for(port = 0; port < asicInfo.numPorts; port++)
{
printf("0/%d, ", portMapData.portMap[port]);
}
}
return result;
}
/*************************************************************************/
open_error_t testLagToNotation(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
char lagName[32];
open_buffdesc lagbuf;
printf("\n\n");
printf("Testing API -- openapiLagTranslateToNotation\n");
printf("---------------------------------------------\n");
memset(lagName, 0, sizeof(lagName));
lagbuf.size = sizeof(lagName);
lagbuf.pstart = lagName;
result = openapiLagTranslateToNotation(clientHandle, asicId, SAMPLE_LAG_1, &lagbuf);
if (OPEN_E_NONE == result)
{
printf("Lag string for lag number=%d is %s\n", SAMPLE_LAG_1, lagName);
}
return result;
}
/*************************************************************************/
open_error_t testBstConfig(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
OPEN_BST_CONFIG_t bstConfig;
OPEN_BST_CONFIG_t bstReadConfig;
int get_result,set_result;
get_result = set_result = OPEN_E_NONE;
memset(&bstConfig, 0, sizeof(OPEN_BST_CONFIG_t));
memset(&bstReadConfig, 0, sizeof(OPEN_BST_CONFIG_t));
printf("\n\n");
printf("Testing API -- openapiBstConfigSet\n");
printf("------------------------------------\n");
/* We will try to enable the BST at all levels, i.e device, ingress and egress */
bstConfig.enableStatsMonitoring = true;
bstConfig.enableDeviceStatsMonitoring = true;
bstConfig.enableIngressStatsMonitoring = true;
bstConfig.enableEgressStatsMonitoring = true;
/* BST can collect the current stats or the peak stats */
bstConfig.mode = OPEN_BST_MODE_CURRENT;
set_result = openapiBstConfigSet(clientHandle, asicId, &bstConfig);
if (OPEN_E_NONE != result)
{
printf("Setting basic BST configuration failed, result = %d\n", result);
printf("Parameters, mode = current, ingress = enable, egress = enable, device = enable\n");
}
get_result = openapiBstConfigGet(clientHandle, asicId, &bstReadConfig);
if (OPEN_E_NONE != result)
{
printf("Reading basic BST configuration failed, result = %d\n", result);
}
/* If BST enabling and reading status fails, we just exit this test case */
if ((set_result != OPEN_E_NONE) && (get_result != OPEN_E_NONE))
{
return OPEN_E_FAIL;
}
if ((bstConfig.enableStatsMonitoring != bstReadConfig.enableStatsMonitoring) ||
(bstConfig.mode != bstReadConfig.mode))
{
printf("Setting basic BST configuration failed mismatch in get and set \n");
printf("Set parameters mode = %d, device = %d, ingress = %d , egress = %d\n", bstConfig.mode,
bstConfig.enableDeviceStatsMonitoring, bstReadConfig.enableIngressStatsMonitoring,
bstConfig.enableEgressStatsMonitoring);
printf("Read parameters mode = %d, device = %d, ingress = %d , egress = %d\n", bstReadConfig.mode,
bstReadConfig.enableDeviceStatsMonitoring, bstReadConfig.enableIngressStatsMonitoring,
bstReadConfig.enableEgressStatsMonitoring);
return OPEN_E_ERROR;
}
/* Change some parameters and try to set the BST config and read */
bstConfig.mode = OPEN_BST_MODE_PEAK;
bstConfig.enableIngressStatsMonitoring = false;
bstConfig.enableEgressStatsMonitoring = true;
set_result = openapiBstConfigSet(clientHandle, asicId, &bstConfig);
if (OPEN_E_NONE != result)
{
printf("Setting basic BST configuration failed, result =%d \n", result);
printf("Parameters, mode = peak, ingress = false, egress = enable, device = enable\n");
return OPEN_E_FAIL;
}
get_result = openapiBstConfigGet(clientHandle, asicId, &bstReadConfig);
if (OPEN_E_NONE != result)
{
printf("Reading basic BST configuration failed, result = %d\n", result);
return OPEN_E_FAIL;
}
if ((bstConfig.enableIngressStatsMonitoring != bstReadConfig.enableIngressStatsMonitoring) ||
(bstConfig.mode != bstReadConfig.mode))
{
printf("Setting basic BST configuration failed, mismatch in get and set \n");
printf("Set parameters mode = %d, device = %d, ingress = %d , egress = %d\n", bstConfig.mode,
bstConfig.enableDeviceStatsMonitoring, bstReadConfig.enableIngressStatsMonitoring,
bstConfig.enableEgressStatsMonitoring);
printf("Read parameters mode = %d, device = %d, ingress = %d , egress = %d\n", bstReadConfig.mode,
bstReadConfig.enableDeviceStatsMonitoring, bstReadConfig.enableIngressStatsMonitoring,
bstReadConfig.enableEgressStatsMonitoring);
return OPEN_E_ERROR;
}
/* Trying to disable BST */
bstConfig.enableStatsMonitoring = false;
set_result = openapiBstConfigSet(clientHandle, asicId, &bstConfig);
if (OPEN_E_NONE != result)
{
printf("Disabling BST failed, result = %d\n", result);
return OPEN_E_ERROR;
}
/* Check if BST is disabled or not */
get_result = openapiBstConfigGet(clientHandle, asicId, &bstReadConfig);
if (get_result == OPEN_E_NONE)
{
if (bstConfig.enableStatsMonitoring != bstReadConfig.enableStatsMonitoring)
{
printf("Disabling BST configuration failed, result = %d\n", result);
return OPEN_E_ERROR;
}
}
else
{
printf("Reading basic BST configuration failed, result = %d\n", result);
return OPEN_E_FAIL;
}
printf("BST configuration for current and peak successful\n");
printf("BST configuration to enable and disable successful\n");
/* To continue other tests, we reenable BST */
bstConfig.enableStatsMonitoring = true;
bstConfig.enableDeviceStatsMonitoring = true;
bstConfig.enableIngressStatsMonitoring = true;
bstConfig.enableEgressStatsMonitoring = true;
bstConfig.mode = OPEN_BST_MODE_CURRENT;
set_result = openapiBstConfigSet(clientHandle, asicId, &bstConfig);
if (OPEN_E_NONE == set_result)
{
printf("BST is Enabled for other tests\n");
}
return OPEN_E_NONE;
}
/*************************************************************************/
open_error_t testDeviceData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstDeviceDataGet\n");
printf("---------------------------------------\n");
memset(&devicedata, 0, sizeof(OPEN_BST_DEVICE_DATA_t));
result = openapiBstDeviceDataGet(clientHandle, asicId, &devicedata, &time);
if (OPEN_E_NONE == result)
{
printf("Device buffer count = %llu\n", (unsigned long long) devicedata.bufferCount);
return OPEN_E_NONE;
}
else
{
printf("Failed to read Device buffer count, result = %d\n", result);
}
return result;
}
/*************************************************************************/
open_error_t testIspData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
memset(&ispData, 0, sizeof(OPEN_BST_INGRESS_SP_DATA_t));
printf("\n\n");
printf("Testing API -- openapiBstIspDataGet\n");
printf("------------------------------------\n");
result = openapiBstIspDataGet(clientHandle, asicId, &ispData, &time);
if (OPEN_E_NONE == result)
{
/* Only service pool 0 is used */
printf("Ingress service pool buffer count = %llu \n", (unsigned long long) ispData.data[0].umShareBufferCount);
return OPEN_E_NONE;
}
else
{
printf("Failed to read Ingress service pool count, result = %d\n", result);
}
return result;
}
/*************************************************************************/
void printIppg(OPEN_BST_INGRESS_PORT_PG_DATA_t *portData, uint32_t port,
uint32_t pgNum)
{
int num;
char space[24]={" "};
if (portData == NULL)
{
printf("Port Data buffer is null for port = %d\n", port);
return;
}
printf("Ingress Port priority group, port = %d\n\n", port);
printf("Priority group UM Share count UM Headroom count\n");
printf("-------------- -------------- -----------------\n");
if (pgNum == -1)
{
for(num=0; num<OPEN_ASIC_MAX_PRIORITY_GROUPS; num++)
{
printf("%d%-13.13s %-14d %-18d\n",
num, space, portData->data[port][num].umShareBufferCount,
portData->data[port][num].umHeadroomBufferCount);
}
}
else
{
printf("%d%-13.13s %-14d %-18d\n",
pgNum, space, portData->data[port][pgNum].umShareBufferCount,
portData->data[port][pgNum].umHeadroomBufferCount);
}
}
/*************************************************************************/
open_error_t testIppgData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstIppgDataGet\n");
printf("---------------------------------------\n");
memset(&ippgData, 0, sizeof(OPEN_BST_INGRESS_PORT_PG_DATA_t));
result = openapiBstIppgDataGet(clientHandle, asicId, &ippgData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample ports and pririty groups */
printIppg(&ippgData, SAMPLE_PORT_1, SAMPLE_PG_1);
printf("\n\n");
printIppg(&ippgData, SAMPLE_PORT_2, SAMPLE_PG_1);
printf("\n\n");
printIppg(&ippgData, SAMPLE_PORT_2, -1);
printf("\n\n");
}
else
{
printf("Failed to read Ingress port priority group buffer data, result = %d\n", result);
}
return result;
}
/*************************************************************************/
void printIpsp(OPEN_BST_INGRESS_PORT_SP_DATA_t *portData, uint32_t port)
{
if (portData == NULL)
{
printf("Port Data buffer is null for port = %d\n", port);
return;
}
printf("Ingress Port service pool, port = %d\n", port);
printf("Unicast Multicast shared buffer = %d\n", portData->data[port][SAMPLE_SP_1].umShareBufferCount);
}
/*************************************************************************/
open_error_t testIpspData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstIpspDataGet\n");
printf("---------------------------------------\n");
memset(&ipspData, 0, sizeof(OPEN_BST_INGRESS_PORT_SP_DATA_t));
result = openapiBstIpspDataGet(clientHandle, asicId, &ipspData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample ports and pririty groups */
printIpsp(&ipspData, SAMPLE_PORT_1);
printf("\n\n");
printIpsp(&ipspData, SAMPLE_PORT_2);
printf("\n\n");
}
else
{
printf("Failed to read Ingress port service pool buffer data, result = %d\n\n", result);
}
return result;
}
/*************************************************************************/
void printUcq(OPEN_BST_EGRESS_UC_QUEUE_DATA_t *ucqData, uint32_t queue)
{
if (ucqData == NULL)
{
printf("Egress unicast queue buffer is null \n");
return;
}
/* queue number should be between 0 and maximum supported by ASIC */
if ((queue < 0) || (queue > asicInfo.numUnicastQueues))
{
printf("Invaild input for Egress unicast queue, number = %d\n", queue);
return;
}
printf("Egress unicast queue = %d associated port = %llu buffer count = %llu\n",
queue, (unsigned long long) ucqData->data[queue].port, (unsigned long long) ucqData->data[queue].ucBufferCount);
}
/*************************************************************************/
open_error_t testUcqData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstEucqDataGet\n");
printf("------------------------------------\n");
memset(&ucqData, 0, sizeof(OPEN_BST_EGRESS_UC_QUEUE_DATA_t));
result = openapiBstEucqDataGet(clientHandle, asicId, &ucqData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample queues */
printUcq(&ucqData, SAMPLE_UCQ_1);
printf("\n");
printUcq(&ucqData, SAMPLE_UCQ_2);
printf("\n");
}
else
{
printf("Failed to read Egress unicast queue buffer data, result = %d\n", result);
}
return result;
}
/*************************************************************************/
void printUcqg(OPEN_BST_EGRESS_UC_QUEUEGROUPS_DATA_t *ucqgData, uint32_t queue)
{
if (ucqgData == NULL)
{
printf("Egress unicast queue group buffer is null \n");
return;
}
/* queue number should be between 0 and maximum supported by ASIC */
if ((queue < 0) || (queue > asicInfo.numUnicastQueueGroups))
{
printf("Invaild input for Egress unicast queue group, number = %d\n", queue);
return;
}
printf("Egress unicast queue group = %d buffer count = %llu\n",
queue, (unsigned long long) ucqgData->data[queue].ucBufferCount);
}
/*************************************************************************/
open_error_t testUcqgData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstEucqgDataGet\n");
printf("------------------------------------\n");
memset(&ucqgData, 0, sizeof(OPEN_BST_EGRESS_UC_QUEUEGROUPS_DATA_t));
result = openapiBstEucqgDataGet(clientHandle, asicId, &ucqgData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample queues */
printUcqg(&ucqgData, SAMPLE_UCQG_1);
printf("\n\n");
printUcqg(&ucqgData, SAMPLE_UCQG_2);
printf("\n\n");
}
else
{
printf("Failed to read Egress unicast queue group buffer data, result = %d\n\n", result);
}
return result;
}
/*************************************************************************/
void printMcq(OPEN_BST_EGRESS_MC_QUEUE_DATA_t *mcqData, uint32_t queue)
{
if (mcqData == NULL)
{
printf("Egress unicast queue buffer is null \n");
return;
}
/* queue number should be between 0 and maximum supported by ASIC */
if (queue > asicInfo.numMulticastQueues)
{
printf("Invaild input for Egress unicast queue, number = %d\n", queue);
return;
}
printf("Egress multicast queue = %d associated port = %llu buffer count = %llu"
" queue entries = %llu\n", queue,
(unsigned long long) mcqData->data[queue].port, (unsigned long long) mcqData->data[queue].mcBufferCount,
(unsigned long long) mcqData->data[queue].mcQueueEntries);
}
/*************************************************************************/
open_error_t testMcqData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstEmcqDataGet\n");
printf("------------------------------------\n");
memset(&mcqData, 0, sizeof(OPEN_BST_EGRESS_MC_QUEUE_DATA_t));
result = openapiBstEmcqDataGet(clientHandle, asicId, &mcqData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample queues */
printMcq(&mcqData, SAMPLE_MCQ_1);
printf("\n");
printMcq(&mcqData, SAMPLE_MCQ_2);
printf("\n");
}
else
{
printf("Failed to read Egress multicast queue group buffer data, result = %d\n", result);
}
return result;
}
/*************************************************************************/
void printCpuq(OPEN_BST_EGRESS_CPU_QUEUE_DATA_t *cpuData, uint32_t queue)
{
if (cpuData == NULL)
{
printf("CPU queue buffer is null \n");
return;
}
/* queue number should be between 0 and maximum supported by ASIC */
if ((queue < 0) || (queue > asicInfo.numCpuQueues))
{
printf("Invaild input for CPU queue, number = %d\n", queue);
return;
}
printf("CPU queue = %d cpu buffer count = %llu"
" cpu queue entries = %llu\n", queue,
(unsigned long long) cpuData->data[queue].cpuBufferCount,
(unsigned long long) cpuData->data[queue].cpuQueueEntries);
}
/*************************************************************************/
open_error_t testCpuqData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstCpuqDataGet\n");
printf("------------------------------------\n");
memset(&cpuData, 0, sizeof(OPEN_BST_EGRESS_CPU_QUEUE_DATA_t));
result = openapiBstCpuqDataGet(clientHandle, asicId, &cpuData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample queues */
printCpuq(&cpuData, SAMPLE_CPUQ_1);
printf("\n");
printCpuq(&cpuData, SAMPLE_CPUQ_2);
printf("\n");
}
else
{
printf("Failed to read Egress CPU queue group buffer data, result = %d\n\n", result);
}
return result;
}
/*************************************************************************/
void printRqeq(OPEN_BST_EGRESS_RQE_QUEUE_DATA_t *rqeData, uint32_t queue)
{
if (rqeData == NULL)
{
printf("RQE queue buffer is null \n");
return;
}
/* queue number should be between 0 and maximum supported by ASIC */
if ((queue < 0) || (queue > asicInfo.numRqeQueues))
{
printf("Invaild input for RQE queue, number = %d\n", queue);
return;
}
printf("RQE queue = %d rqe buffer count = %llu"
" rqe queue entries = %llu\n", queue,
(long long unsigned) rqeData->data[queue].rqeBufferCount,
(long long unsigned) rqeData->data[queue].rqeQueueEntries);
}
/*************************************************************************/
open_error_t testRqeData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstRqeqDataGet\n");
printf("------------------------------------\n");
memset(&rqeData, 0, sizeof(OPEN_BST_EGRESS_RQE_QUEUE_DATA_t));
result = openapiBstRqeqDataGet(clientHandle, asicId, &rqeData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample queues */
printRqeq(&rqeData, SAMPLE_RQE_1);
printf("\n");
printRqeq(&rqeData, SAMPLE_RQE_2);
printf("\n");
}
else
{
printf("Failed to read Egress RQE queue buffer data, result = %d\n\n", result);
}
return result;
}
/*************************************************************************/
void printEpsp(OPEN_BST_EGRESS_PORT_SP_DATA_t *portData, uint32_t port,
uint32_t spNum)
{
if (portData == NULL)
{
printf("Egress port service pool buffer is null for port = %d\n", port);
return;
}
/* service pools are from 0-3, but only service pool 0 is used */
if ((spNum < 0) || (spNum > 3))
{
printf("Invaild input for Egress port service pool, port = %d, service pool = %d\n", port, spNum);
return;
}
printf("Egress Port service pool buffer counts, port = %d\n", port);
printf("Unicast shared = %d\n", portData->data[port][spNum].ucShareBufferCount);
printf("Unicast Multicast shared = %d\n", portData->data[port][spNum].umShareBufferCount);
printf("Multicast shared = %d\n", portData->data[port][spNum].mcShareBufferCount);
printf("Multicast shared queue entries = %d\n", portData->data[port][spNum].mcShareQueueEntries);
}
/*************************************************************************/
open_error_t testEpspData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstEpspDataGet\n");
printf("------------------------------------\n");
memset(&epspData, 0, sizeof(OPEN_BST_EGRESS_PORT_SP_DATA_t));
result = openapiBstEpspDataGet(clientHandle, asicId, &epspData, &time);
if (OPEN_E_NONE == result)
{
/* we will print the data of few sample ports and pririty groups */
printEpsp(&epspData, SAMPLE_PORT_1, SAMPLE_SP_1);
printf("\n");
printEpsp(&epspData, SAMPLE_PORT_2, SAMPLE_SP_1);
printf("\n");
printEpsp(&epspData, SAMPLE_PORT_2, SAMPLE_SP_1);
printf("\n");
}
else
{
printf("Failed to read Egress port serivce pool buffer data, result =%d\n", result);
}
return result;
}
/*************************************************************************/
open_error_t testEspData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
printf("\n\n");
printf("Testing API -- openapiBstEspDataGet\n");
printf("------------------------------------\n");
memset(&espData, 0, sizeof(OPEN_BST_EGRESS_SP_DATA_t));
result = openapiBstEspDataGet(clientHandle, asicId, &espData, &time);
if (OPEN_E_NONE == result)
{
/* 4 Egress service pools exist, but only 1 (service pool 0) is used */
printf("Buffer counts of Egress service poool\n");
printf("Unicast Multicast shared = %llu\n", (unsigned long long) espData.data[0].umShareBufferCount);
printf("Multicast shared = %llu\n", (unsigned long long) espData.data[0].mcShareBufferCount);
printf("Multicast shared queue entries = %llu\n", (unsigned long long) espData.data[0].mcShareQueueEntries);
}
else
{
printf("Failed to read Egress port serivce pool buffer data, result =%d\n", result);
}
return result;
}
/*************************************************************************/
open_error_t testGlobalData(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
open_error_t snap_get, snap_max_get, thresh_clear, stats_clear, cgsn_drop_ctr_clear;
memset(&snapshot, 0, sizeof(OPEN_BST_ASIC_SNAPSHOT_DATA_t));
memset(&ucqdata, 0, sizeof(OPEN_BST_EGRESS_UC_QUEUE_DATA_t));
memset(&mcqdata, 0, sizeof(OPEN_BST_EGRESS_MC_QUEUE_DATA_t));
snap_get = openapiBstSnapshotGet(clientHandle, asicId, &snapshot, &ucqdata, &mcqdata, &time);
if (snap_get == OPEN_E_NONE)
{
printf("Reading of entire snapshot of all buffers succeeded\n");
}
else
{
printf("Reading of entire snapshot of all buffers failed\n");
}
snap_max_get = openapiBstMaxSnapshotGet(clientHandle, asicId, &snapshot, &ucqdata, &mcqdata, &time);
if (snap_max_get == OPEN_E_NONE)
{
printf("Reading of entire maximum snapshot of all buffers succeeded\n");
}
else
{
printf("Reading of entire maximum default snapshot of all buffers failed\n");
}
thresh_clear = openapiBstThresholdsClear(clientHandle, asicId);
if (thresh_clear == OPEN_E_NONE)
{
printf("Clearing of thresholds succeeded\n");
}
else
{
printf("Clearing of thresholds failed\n");
}
stats_clear = openapiBstStatsClear(clientHandle, asicId);
if (stats_clear == OPEN_E_NONE)
{
printf("Clearing of statistics succeeded\n");
}
else
{
printf("Clearing of statistics failed\n");
}
cgsn_drop_ctr_clear = openapiBstCgsnDropCtrsClear(clientHandle, asicId);
if (cgsn_drop_ctr_clear == OPEN_E_NONE)
{
printf("Clearing of congestion drop counters succeeded\n");
}
else
{
printf("Clearing of congestion drop counters failed, error = %d \n", cgsn_drop_ctr_clear);
}
return result;
}
/*************************************************************************/
uint64_t getSystemthresh(uint64_t threshold)
{
if (threshold % ASIC_CELL_SIZE == 0)
{
return threshold;
}
return ( ((threshold/ASIC_CELL_SIZE)+1) * ASIC_CELL_SIZE);
}
/*************************************************************************/
open_error_t testThresholds(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
time_t time;
open_error_t device_set, ippg_set, ipsp_set, isp_set;
open_error_t epsp_set, esp_set, ucq_set, ucqg_set, mcq_set;
open_error_t cpuq_set, rqeq_set;
open_error_t read_thresh;
/* Fill all buffers with 0 */
memset(&device, 0 , sizeof(OPEN_BST_DEVICE_THRESHOLD_t));
memset(&ippg, 0 , sizeof(OPEN_BST_INGRESS_PORT_PG_THRESHOLD_t));
memset(&ipsp, 0 , sizeof(OPEN_BST_INGRESS_PORT_SP_THRESHOLD_t));
memset(&isp, 0 , sizeof(OPEN_BST_INGRESS_SP_THRESHOLD_t));
memset(&epsp, 0 , sizeof(OPEN_BST_EGRESS_PORT_SP_THRESHOLD_t));
memset(&esp, 0 , sizeof(OPEN_BST_EGRESS_SP_THRESHOLD_t));
memset(&ucq, 0 , sizeof(OPEN_BST_EGRESS_UC_QUEUE_THRESHOLD_t));
memset(&ucqg, 0 , sizeof(OPEN_BST_EGRESS_UC_QUEUEGROUPS_THRESHOLD_t));
memset(&mcq, 0 , sizeof(OPEN_BST_EGRESS_MC_QUEUE_THRESHOLD_t));
memset(&cpuq, 0 , sizeof(OPEN_BST_EGRESS_CPU_QUEUE_THRESHOLD_t));
memset(&rqeq, 0 , sizeof(OPEN_BST_EGRESS_RQE_QUEUE_THRESHOLD_t));
memset(&thSnapshot, 0, sizeof(OPEN_BST_ASIC_SNAPSHOT_DATA_t));
memset(&thUcq, 0 , sizeof(OPEN_BST_EGRESS_UC_QUEUE_DATA_t));
memset(&thMcq, 0, sizeof(OPEN_BST_EGRESS_MC_QUEUE_DATA_t));
/* Setting the thresholds for various resources, here all the sample
thresholds are applied, the return values are checked along with
reading of threshold configuration later */
printf("\n\nTesting the thresholds of various resorces\n");
printf("------------------------------------------\n\n");
/* Setting threshold for device. */
device.threshold = DEVICE_THRESH_SAMPLE_1;
device_set = openapiBstDeviceThresholdSet(clientHandle, asicId, &device);
/* Setting threshold for (Sample port and pririty group) Ingress port, priority group */
ippg.umShareThreshold = IPPG_THRESH_SHARED_SAMPLE_1;
ippg.umHeadroomThreshold = IPPG_THRESH_HEADROOM_SAMPLE_1;
ippg_set = openapiBstIppgThresholdSet(clientHandle, asicId, SAMPLE_PORT_1, SAMPLE_PG_1, &ippg);
/* Setting threshold for (Sample port) Ingress port service pool */
ipsp.umShareThreshold = IPSP_THRESHOLD_SAMPLE_1;
ipsp_set = openapiBstIpspThresholdSet(clientHandle, asicId, SAMPLE_PORT_2, SAMPLE_SP_1, &ipsp);
/* Setting threshold for Ingress service pool */
isp.umShareThreshold = ISP_THRESHOLD_SAMPLE_1;
isp_set = openapiBstIspThresholdSet(clientHandle, asicId, SAMPLE_SP_1, &isp);
/* Setting threshold for Egress port service pool */
epsp.ucShareThreshold = EPSP_UC_THRESHOLD_SAMPLE_1;
epsp.umShareThreshold = EPSP_UM_THRESHOLD_SAMPLE_1;
epsp.mcShareThreshold = EPSP_MC_THRESHOLD_SAMPLE_1;
epsp.mcShareQueueEntriesThreshold = EPSP_MC_SHARE_THRESHOLD_SAMPLE_1;
epsp_set = openapiBstEpspThresholdSet(clientHandle, asicId, SAMPLE_PORT_3,
SAMPLE_SP_1, &epsp);
/* Setting threshold for Egress service pool */
esp.umShareThreshold = ESP_UM_THRESHOLD_SAMPLE_1;
esp.mcShareThreshold = ESP_MC_THRESHOLD_SAMPLE_1;
esp_set = openapiBstEspThresholdSet(clientHandle, asicId, SAMPLE_SP_1, &esp);
/* Setting threshold for Egress unicast queue */
ucq.ucBufferThreshold = UCQ_THRESHOLD_SAMPLE_1;
ucq_set = openapiBstEucqThresholdSet(clientHandle, asicId, SAMPLE_UCQ_1, &ucq);
/* Setting threshold for Egress unicast queue group*/
ucqg.ucBufferThreshold = UCQG_THRESHOLD_SAMPLE_1;
ucqg_set = openapiBstEucqgThresholdSet(clientHandle, asicId, SAMPLE_UCQG_1, &ucqg);
/* Setting threshold for Egress multicast queue */
mcq.mcBufferThreshold = MCQB_THRESHOLD_SAMPLE_1;
mcq.mcQueueThreshold = MCQQ_THRESHOLD_SAMPLE_1;
mcq_set = openapiBstEmcqThresholdSet(clientHandle, asicId, SAMPLE_MCQ_1, &mcq);
/* Setting threshold for CPU queue */
cpuq.cpuBufferThreshold = CPUQB_THRESHOLD_SAMPLE_1;
cpuq.cpuQueueThreshold = CPUQQ_THRESHOLD_SAMPLE_1;
cpuq_set = openapiBstCpuqThresholdSet(clientHandle, asicId, SAMPLE_CPUQ_1, &cpuq);
/* Setting threshold for RQE queue */
rqeq.rqeBufferThreshold = RQEB_THRESHOLD_SAMPLE_1;
rqeq.rqeQueueThreshold = RQEQ_THRESHOLD_SAMPLE_1;
rqeq_set = openapiBstRqeqThresholdSet(clientHandle, asicId, SAMPLE_RQE_1, &rqeq);
/* Now try to read, all the thresholds */
read_thresh = openapiBstThresholdGet(clientHandle, asicId, &thSnapshot, &thUcq,
&thMcq, &time);
/* If reading of threshold configuration has failed, applied thresholds
cannot be compared with anything so, we treat as total failure and exit the test case */
if (read_thresh != OPEN_E_NONE)
{
printf("Reading of threshold configuration has failed.\n");
return OPEN_E_FAIL;
}
/* now compare what is configured and what is read for all the resources */
printf("Testing API -- openapiBstDeviceThresholdSet\n");
if (device_set == OPEN_E_NONE)
{
if (getSystemthresh(device.threshold) == thSnapshot.device.bufferCount)
{
printf("Device threshold configuration succeeded.\n");
}
else
{
printf("Device threshold configuration failed.\n");
}
}
printf("\n\n");
/* while accessing the buffer data array , we use (sample_port-1), becasue
the array is indexed from 0, and port number used by the system starts from 1 */
printf("Testing API -- openapiBstIppgThresholdSet\n");
if (ippg_set == OPEN_E_NONE)
{
if ((getSystemthresh(ippg.umShareThreshold) ==
thSnapshot.iPortPg.data[SAMPLE_PORT_1-1][SAMPLE_PG_1].umShareBufferCount) &&
(getSystemthresh(ippg.umHeadroomThreshold) ==
thSnapshot.iPortPg.data[SAMPLE_PORT_1-1][SAMPLE_PG_1].umHeadroomBufferCount))
{
printf("Ingress port priority group threshold configuration succeeded.\n");
}
else
{
printf("Ingress port priority group threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstIpspThresholdSet\n");
if (ipsp_set == OPEN_E_NONE)
{
if ((getSystemthresh(ipsp.umShareThreshold) ==
thSnapshot.iPortSp.data[SAMPLE_PORT_2-1][SAMPLE_SP_1].umShareBufferCount))
{
printf("Ingress per port service pool threshold configuration succeeded.\n");
}
else
{
printf("Ingress per port service pool threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstIspThresholdSet\n");
if (isp_set == OPEN_E_NONE)
{
if ((getSystemthresh(isp.umShareThreshold) ==
thSnapshot.iSp.data[SAMPLE_SP_1].umShareBufferCount))
{
printf("Ingress service pool threshold configuration succeeded.\n");
}
else
{
printf("Ingress service pool threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstEpspThresholdSet\n");
if (epsp_set == OPEN_E_NONE)
{
if ((getSystemthresh(epsp.ucShareThreshold) ==
thSnapshot.ePortSp.data[SAMPLE_PORT_3-1][SAMPLE_SP_1].ucShareBufferCount))
{
printf("Egress per port service pool threshold configuration succeeded.\n");
}
else
{
printf("Egress per port service pool threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstEspThresholdSet\n");
if (esp_set == OPEN_E_NONE)
{
if ((getSystemthresh(esp.umShareThreshold) ==
thSnapshot.eSp.data[SAMPLE_SP_1].umShareBufferCount) &&
(getSystemthresh(epsp.mcShareThreshold) ==
thSnapshot.eSp.data[SAMPLE_SP_1].mcShareBufferCount))
{
printf("Egress service pool threshold configuration succeeded.\n");
}
else
{
printf("Egress service pool threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstEucqThresholdSet\n");
if (ucq_set == OPEN_E_NONE)
{
if (getSystemthresh(ucq.ucBufferThreshold) == thUcq.data[SAMPLE_UCQ_1].ucBufferCount)
{
printf("Egress unicast queue threshold configuration succeeded.\n");
}
else
{
printf("Egress unicast queue threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstEucqgThresholdSet\n");
if (ucqg_set == OPEN_E_NONE)
{
if (getSystemthresh(ucqg.ucBufferThreshold) == thSnapshot.eUcQg.data[SAMPLE_UCQG_1].ucBufferCount)
{
printf("Egress unicast queue group threshold configuration succeeded.\n");
}
else
{
printf("Egress unicast queue group threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstEmcqThresholdSet\n");
if (mcq_set == OPEN_E_NONE)
{
if (getSystemthresh(mcq.mcBufferThreshold) == thMcq.data[SAMPLE_MCQ_1].mcBufferCount)
{
printf("Egress multicast queue threshold configuration succeeded.\n");
}
else
{
printf("Egress multicast queue threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstCpuqThresholdSet\n");
if (cpuq_set == OPEN_E_NONE)
{
if (getSystemthresh(cpuq.cpuBufferThreshold) == thSnapshot.cpqQ.data[SAMPLE_CPUQ_1].cpuBufferCount)
{
printf("Egress CPU queue threshold configuration succeeded.\n");
}
else
{
printf("Egress CPU queue threshold configuration failed.\n");
}
}
printf("\n\n");
printf("Testing API -- openapiBstRqeqThresholdSet\n");
if (rqeq_set == OPEN_E_NONE)
{
if (getSystemthresh(rqeq.rqeBufferThreshold) == thSnapshot.rqeQ.data[SAMPLE_RQE_1].rqeBufferCount)
{
printf("Egress RQE queue threshold configuration succeeded.\n");
}
else
{
printf("Egress RQE queue threshold configuration failed.\n");
}
}
printf("\n\n");
return result;
}
/*************************************************************************/
void bst_trigger_callback(void)
{
printf("Threshold breached, trigger function called\n");
trigger_event = true;
}
/*************************************************************************/
open_error_t testTrigger(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
open_error_t tenable, register_t;
uint32_t enable = 1;
int clientId;
tenable = register_t = OPEN_E_NONE;
cookie = &cb_cookie;
tenable = openapiBstTriggerEnable(clientHandle, asicId, enable, getpid(),
&clientId);
if (tenable == OPEN_E_NONE)
{
register_t = openapiBstTriggerRegister(clientHandle, asicId, clientId,
(OPEN_BST_TRIGGER_CALLBACK_t )bst_trigger_callback,
cookie);
}
return tenable;
}
/*************************************************************************/
open_error_t testBstSnapshotCompressedGet(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
unsigned char compData[BST_MAX_COMPRESSED_LEN];
open_buffdesc compSnapshot;
time_t time;
uLongf uncompressedLength = 0;
int retCode;
memset(&snapshot, 0, sizeof(snapshot));
memset(&compData, 0, sizeof(compData));
compSnapshot.pstart = compData;
compSnapshot.size = sizeof(compData);
result = openapiBstSnapshotCompressedGet(clientHandle, asicId, &compSnapshot, &time);
if (result == OPEN_E_NONE)
{
printf("Reading of compressed threshold of all buffers succeeded\n");
uncompressedLength = sizeof(snapshot);
retCode = uncompress((unsigned char *)&snapshot, &uncompressedLength,
(unsigned char *)compSnapshot.pstart, compSnapshot.size);
if (Z_OK == retCode)
{
printf("Successfully decompressed data\n");
}
else
{
printf("Unable to decompress data\n");
result = OPEN_E_ERROR;
}
}
else
{
printf("Reading of compressed threshold of all buffers failed\n");
}
return result;
}
/*************************************************************************/
open_error_t testBstThresholdCompressedGet(openapiClientHandle_t *clientHandle, uint32_t asicId)
{
unsigned char compData[BST_MAX_COMPRESSED_LEN];
open_buffdesc compSnapshot;
time_t time;
uLongf uncompressedLength = 0;
int retCode;
memset(&snapshot, 0, sizeof(snapshot));
memset(&compData, 0, sizeof(compData));
compSnapshot.pstart = compData;
compSnapshot.size = sizeof(compData);
result = openapiBstThresholdCompressedGet(clientHandle, asicId, &compSnapshot, &time);
if (result == OPEN_E_NONE)
{
printf("Reading of compressed snapshot of all buffers succeeded\n");
uncompressedLength = sizeof(snapshot);
retCode = uncompress((unsigned char *)&snapshot, &uncompressedLength,
(unsigned char *)compSnapshot.pstart, compSnapshot.size);
if (Z_OK == retCode)
{
printf("Successfully decompressed data\n");
}
else
{
printf("Unable to decompress data\n");
result = OPEN_E_ERROR;
}
}
else
{
printf("Reading of compressed snapshot of all buffers failed\n");
}
return result;
}
/****************************************************************/
int main (int argc, char **argv)
{
openapiClientHandle_t clientHandle;
open_error_t trigger_test = OPEN_E_NONE;
uint32_t asicId = 0;
l7proc_crashlog_register();
/* Register with OpEN */
if ((result =
openapiClientRegister ("instru_example", &clientHandle)) != OPEN_E_NONE)
{
printf ("\nFailed to initialize RPC to OpEN. result = %d exit test\n", result);
exit (2);
}
/* RPC call can fail until server starts. Keep trying */
while (openapiConnectivityCheck (&clientHandle) != OPEN_E_NONE)
{
sleep (1);
}
L7PROC_LOGF (L7PROC_LOG_SEVERITY_INFO, 0, "Starting BST API example application");
printf ("\n");
/* Execute sanity tests */
printf ("Begin Sanity tests...\n");
/* Basic ASIC capabilities, here we try to read the basic ASIC capabilities
like number of ports, queues and other information , failing to read the
basic capabilities can be understood as fatal error and test exits */
result = testAsicBasic(&clientHandle, asicId);
if (result != OPEN_E_NONE)
{
printf("Reading of ASIC capabilities failed, exit test\n");
exit(1);
}
result = testAsicPortMap(&clientHandle, asicId);
if (result != OPEN_E_NONE)
{
printf("Reading of ASIC port mapping failed\n");
}
result = testLagToNotation(&clientHandle, asicId);
if (result != OPEN_E_NONE)
{
printf("Reading of Lag string failed\n");
}
/* Test if BST can be enabled/disabled */
result = testBstConfig(&clientHandle, asicId);
if (result == OPEN_E_FAIL)
{
printf("BST configuration setting/getting failed, exit test\n");
exit(1);
}
/* Read device buffer count, the device does not take any index
i.e it is not indexed by port/queue number. This is an example
of resource (device) with no index */
testDeviceData(&clientHandle, asicId);
/* Inress side resource examples */
/* Read ingress service pool buffer count, this resource is indexed by
service pool number. An example of the resource which takes
single index */
testIspData(&clientHandle, asicId);
/* Read ingress port priority group buffer count. This resource is indexed by
2 values, port number and priority group number.*/
testIppgData(&clientHandle, asicId);
testIpspData(&clientHandle, asicId);
/* Egress side resource examples */
/* Read egress service pool buffer count, this resource is indexed by
2 values, port number and service pool number.*/
testEpspData(&clientHandle, asicId);
testEspData(&clientHandle, asicId);
/* Testing of Unicast queue statistics */
testUcqData(&clientHandle, asicId);
/* Testing of Multicast queue statistics */
testMcqData(&clientHandle, asicId);
/* Testing of CPU queue statistics */
testCpuqData(&clientHandle, asicId);
testRqeData(&clientHandle, asicId);
/* Apply buffer thresholds to various resources and read the
thresholds back. Applied value is compared with the value read. */
testThresholds(&clientHandle, asicId);
/* Some API act on all the resources, for example
read all statistics, clear all statistics, this function will test them. */
testGlobalData(&clientHandle, asicId);
/* Testing of compressed BST snapshot get */
testBstSnapshotCompressedGet(&clientHandle, asicId);
/* Testing of compressed BST threshold get */
testBstThresholdCompressedGet(&clientHandle, asicId);
trigger_test = testTrigger(&clientHandle, asicId);
if (trigger_test == OPEN_E_NONE)
{
printf("Waiting for 30 seconds for threshold to trigger\n");
sleep(30);
// call back called deregister
de_reg = openapiBstTriggerDeRegister(&clientHandle, asicId,
(OPEN_BST_TRIGGER_CALLBACK_t )bst_trigger_callback, cookie);
if (de_reg != OPEN_E_NONE)
{
printf("Unable to de-register trigger function\n");
}
}
printf ("\nComplete.\n");
/* Log goodbye message with OPEN */
L7PROC_LOGF (L7PROC_LOG_SEVERITY_INFO, 0, "Stopping BST API example application");
(void) openapiClientTearDown(&clientHandle);
return 0;
}