bypass/config/bypass_config_example.c

Reference Documentation

product_line_custom
Napatech SmartNIC
category
Reference Information

Description

This source file is an example of how to use the Configuration stream interface in NTAPI for Napatech bypass accelerator and port configuration.

This example switches the state of the relays every time it is run.

Prerequisites

A working system is needed with a Napatech bypass accelerator.

Program flow

The following is required to perform read and write operations on the configuration stream:

/* * %NT_SOFTWARE_LICENSE% */ /** * @example bypass/config/bypass_config_example.c * @section Description Description * * This source file is an example of how to use the @ref ConfigStream * "Configuration stream" interface in NTAPI for Napatech bypass accelerator and port configuration. * * This example switches the state of the relays every time it is run. * * The following NTAPI functions are used: * - @ref NT_Init() * - @ref NT_InfoOpen() * - @ref NT_InfoRead() * - @ref NT_InfoClose() * - @ref NT_ConfigOpen() * - @ref NT_ConfigWrite() * - @ref NT_ConfigRead() * - @ref NT_ConfigClose() * - @ref NT_Done() * - @ref NT_ExplainError() * * <hr> * @section Prerequisites_l Prerequisites * A working system is needed with a Napatech bypass accelerator. * * @section Flow Program flow * @{ * The following is required to perform read and write operations on * the @ref ConfigStream "configuration stream": * * - \#include/nt.h - Applications/Tools only need to include @ref * nt.h to obtain prototypes, macros etc. from NTAPI. * - @ref NT_Init(@ref NTAPI_VERSION) - Initialize the NTAPI * library. @ref NTAPI_VERSION is a define that describes the version * of the API described in the header files included by @ref * nt.h. NT_Init() will ask the NTAPI library to convert return data * to the @ref NTAPI_VERSION if possible. This will ensure that * applications can run on NTAPI libraries of newer versions. * * - @ref NT_InfoOpen() - Open an info stream. * - @ref NT_InfoRead() - Read info stream. * - @ref NT_InfoClose() - Close the stream when terminating. * - @ref NT_ConfigOpen() - Open a configuration stream. * - @ref NT_ConfigRead() - Read configuration. * - @ref NT_ConfigWrite() - Write configuration. * - @ref NT_ConfigClose() - Close the stream when terminating. * - @ref NT_Done() - Close down the NTAPI library. * - @ref NT_ExplainError() - Explain an error code returned by NTAPI functions. * *<hr> * @} */ // std includes #if defined(__linux__) || defined(__FreeBSD__) #include <unistd.h> #endif #include <stdlib.h> #include <stdio.h> #include <errno.h> // NT includes #include "nt.h" // // main() // int main(void) { uint32_t status; char errBuf[NT_ERRBUF_SIZE]; // NtInfoStream_t hInfo; NtInfo_t infoSystem; NtInfo_t infoAdapter; NtInfo_t infoPort; // NtConfigStream_t hConfig; NtConfig_t configPort; // uint8_t adapter; uint8_t port; // const char* aBpState[] = {"NA", "Normal", "Bypass"}; const char* aBpFlags[] = {"Off", "On"}; // // // // Initialize NTAPI library if ((status = NT_Init(NTAPI_VERSION)) != NT_SUCCESS) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_Init failed. Code 0x%x = %s\n", status, errBuf); return status; } // Open the information stream if ((status = NT_InfoOpen(&hInfo, "bypass_config_example")) != NT_SUCCESS) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, ">>> Error: NT_InfoOpen failed. Code 0x%x = %s\n", status, errBuf); return status; } // Read system information infoSystem.cmd = NT_INFO_CMD_READ_SYSTEM; if ((status = NT_InfoRead(hInfo, &infoSystem)) != NT_SUCCESS) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_InfoRead failed. Code 0x%x = %s\n", status, errBuf); return status; } printf("System: %d.%d.%d.%d\n\n", infoSystem.u.system.data.version.major, infoSystem.u.system.data.version.minor, infoSystem.u.system.data.version.patch, infoSystem.u.system.data.version.tag); printf("Adapters: %u\n", infoSystem.u.system.data.numAdapters); printf("Ports: %u\n", infoSystem.u.system.data.numPorts); printf("\n"); // Open the config stream status = NT_ConfigOpen(&hConfig, "bypass_config_example"); if (status != NT_SUCCESS) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, ">>> Error: NT_ConfigOpen failed. Code 0x%x = %s\n", status, errBuf); return status; } for (adapter = 0; adapter < infoSystem.u.system.data.numAdapters; adapter++) { infoAdapter.cmd = NT_INFO_CMD_READ_ADAPTER_V6; infoAdapter.u.adapter_v6.adapterNo = adapter; if ((status = NT_InfoRead(hInfo, &infoAdapter)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_InfoRead failed. Code 0x%x = %s\n", status, errBuf); return status; } printf("Adapter %u (%u ports):\n", infoAdapter.u.adapter_v6.adapterNo, infoAdapter.u.adapter_v6.data.numPorts); configPort.parm = NT_CONFIG_PARM_BYPASS_ADAPTER; configPort.u.bypassConfig.u.adapterNo = adapter; status = NT_ConfigRead(hConfig, &configPort); if (status != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf); continue ; // skip this and continue to next adapter } else { // // Invert bypass adapter state - based on the current bypass adapter state // Skip this step if the already read bypass adapter state is unknown - this means that the ports can be individually configured. // if (configPort.u.bypassConfig.data.currentBypassPortState != NT_BYPASS_PORT_STATE_UNKNOWN) { if (configPort.u.bypassConfig.data.currentBypassPortState == NT_BYPASS_PORT_STATE_NORMAL) { configPort.u.bypassConfig.data.currentBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; configPort.u.bypassConfig.data.onInitBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; configPort.u.bypassConfig.data.onPowerFailBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; configPort.u.bypassConfig.data.onWatchdogFailBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; } else { configPort.u.bypassConfig.data.currentBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; configPort.u.bypassConfig.data.onInitBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; configPort.u.bypassConfig.data.onPowerFailBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; configPort.u.bypassConfig.data.onWatchdogFailBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; } } // // Then write the changed configuration back... // configPort.parm = NT_CONFIG_PARM_BYPASS_ADAPTER; configPort.u.bypassConfig.u.adapterNo = adapter; if ((status = NT_ConfigWrite(hConfig, &configPort)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_ConfigWrite failed. Code 0x%x = %s\n", status, errBuf); return status; } // // Display bypass configuration for the adapter // configPort.parm = NT_CONFIG_PARM_BYPASS_ADAPTER; configPort.u.bypassConfig.u.adapterNo = adapter; if ((status = NT_ConfigRead(hConfig, &configPort)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf); return status; } printf(" bypass adapter current state: %s\n", aBpState[configPort.u.bypassConfig.data.currentBypassPortState]); printf(" bypass adapter onInit state: %s\n", aBpState[configPort.u.bypassConfig.data.onInitBypassPortState]); printf(" bypass adapter onPwrFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onPowerFailBypassPortState]); printf(" bypass adapter onWdtFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onWatchdogFailBypassPortState]); printf(" bypass adapter onPwrFail detect trigger: %s\n", aBpFlags[((configPort.u.bypassConfig.data.bypassTriggerModes & NT_BYPASS_TRIGGER_PWRFAIL)==0?0:1)]); } printf("\n"); for (port = 0; port < infoAdapter.u.adapter_v6.data.numPorts; port++) { infoPort.cmd = NT_INFO_CMD_READ_PORT_V9; infoPort.u.port_v9.portNo = (uint8_t)(infoAdapter.u.adapter_v6.data.portOffset + port); if ((status = NT_InfoRead(hInfo, &infoPort)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_InfoRead failed. Code 0x%x = %s\n", status, errBuf); return status; } printf(" Port %i (adapter #%i port #%i):\n", infoPort.u.port_v9.portNo, infoPort.u.port_v9.data.adapterNo, port); if ( infoPort.u.port_v9.data.capabilities.featureMask & NT_PORT_FEATURE_BYPASS) { // // There is no need to configure both ports in a bypass portset pair. // You only need configure one of the ports in a bypass portset pair. // The other port automatically will mirror the bypass configuration of the first port. // if ((port & 0x01) == 0) { // // Read current configuration // configPort.parm = NT_CONFIG_PARM_BYPASS_PORT; configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v6.data.portOffset + port); if ((status = NT_ConfigRead(hConfig, &configPort)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf); return status; } // // Invert bypass portset state - based on the current bypass portset state // if (configPort.u.bypassConfig.data.currentBypassPortState == NT_BYPASS_PORT_STATE_NORMAL) { configPort.u.bypassConfig.data.currentBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; configPort.u.bypassConfig.data.onInitBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; configPort.u.bypassConfig.data.onPowerFailBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; configPort.u.bypassConfig.data.onWatchdogFailBypassPortState = NT_BYPASS_PORT_STATE_BYPASS; } else { configPort.u.bypassConfig.data.currentBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; configPort.u.bypassConfig.data.onInitBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; configPort.u.bypassConfig.data.onPowerFailBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; configPort.u.bypassConfig.data.onWatchdogFailBypassPortState = NT_BYPASS_PORT_STATE_NORMAL; } // // Then write the changed configuration back... // configPort.parm = NT_CONFIG_PARM_BYPASS_PORT; configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v6.data.portOffset + port); if ((status = NT_ConfigWrite(hConfig, &configPort)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_ConfigWrite failed. Code 0x%x = %s\n", status, errBuf); return status; } } // // Display result of configuration for all ports in a bypass portset // The second port in a bypass portset should have mirrored the settings applied to the first port. // configPort.parm = NT_CONFIG_PARM_BYPASS_PORT; configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v6.data.portOffset + port); if ((status = NT_ConfigRead(hConfig, &configPort)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf); return status; } printf(" bypass port current state: %s\n", aBpState[configPort.u.bypassConfig.data.currentBypassPortState]); printf(" bypass port onInit state: %s\n", aBpState[configPort.u.bypassConfig.data.onInitBypassPortState]); printf(" bypass port onPwrFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onPowerFailBypassPortState]); printf(" bypass port onWdtFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onWatchdogFailBypassPortState]); printf(" bypass port onPwrFail detect trigger: %s\n", aBpFlags[((configPort.u.bypassConfig.data.bypassTriggerModes & NT_BYPASS_TRIGGER_PWRFAIL)==0?0:1)]); configPort.parm = NT_CONFIG_PARM_BYPASS_PORT; configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v6.data.portOffset + port); if ((status = NT_ConfigWrite(hConfig, &configPort)) != 0) { NT_ExplainError(status, errBuf, sizeof(errBuf)); fprintf(stderr, "ERROR: NT_ConfigWrite failed. Code 0x%x = %s\n", status, errBuf); return status; } } printf("\n"); } printf("\n"); } printf("\n"); // Close down the NTAPI library NT_Done(); return 0; } // // EOF //