Commit 9aee73bf authored by Adam Wujek's avatar Adam Wujek 💬

Merge branch 'adam-snmp2'

Please not that some commits had non backward compatible changes in MIB.
However, end result of MIB is backward compatible.
parents f0bdc562 a08d32c7
......@@ -70,44 +70,6 @@ config REMOTE_SYSLOG_UDP
help
Select UDP to send system logs. If not set, TCP is used.
config SNMP_TRAPSINK_ADDRESS
string "Static IP address or name where to send SNMPv1 traps"
help
If not empty, the address or name is ussed as "trapsink"
destination in the SNMP configuration file for the switch.
It empty, no v1 traps are generated. If both this and
the following TRAP2SINK_ADDRESS are set, snmpd sends two
traps (one per protocol version). Trapcommunity is "public"
(not configurable so far).
config SNMP_TRAP2SINK_ADDRESS
string "Static IP address or name where to send SNMPv2c traps"
help
If not empty, the address or name is ussed as "trap2sink"
destination in the SNMP configuration file for the switch.
It empty, no v2c traps are generated. Trapcommunity is "public"
(not configurable so far).
config SNMP_RO_COMMUNITY
string "Read-only community name for SNMP V1/V2 management"
default "public"
help
If not empty, the 'community' name is a sort of password,
that travels as clear text (we don't support encrypted SNMPv3
yet). The default is good for testing, but should be changed
for production. Please note, however, that the switch processes
SNMP only on the CPU Ethernet port (the copper "management" port).
config SNMP_RW_COMMUNITY
string "Read-write community name for SNMP V1/V2 management"
default "private"
help
If not empty, the 'community' name is a sort of password,
that travels as clear text (we don't support encrypted SNMPv3
yet). The default is good for testing, but should be changed
for production. Please note, however, that the switch processes
SNMP only on the CPU Ethernet port (the copper "management" port).
config WRS_LOG_HAL
string "Logging directions for the WR hal"
default "daemon.info"
......@@ -231,7 +193,7 @@ menu "SFP and Media Timing Configuration"
config SFP00_PARAMS
string "Parameters for one SFP device type"
default "name=AXGE-1254-0531,tx=10,rx=10,wl_txrx=1310+1490"
default "vn=Axcen Photonics,pn=AXGE-1254-0531,tx=10,rx=10,wl_txrx=1310+1490"
help
This parameter, and the following ones, are used to
configure the timing parameters of a specific SFP
......@@ -242,7 +204,7 @@ config SFP00_PARAMS
config SFP01_PARAMS
string "Parameters for one SFP device type"
default "name=AXGE-3454-0531,tx=10,rx=10,wl_txrx=1490+1310"
default "vn=Axcen Photonics,pn=AXGE-3454-0531,tx=10,rx=10,wl_txrx=1490+1310"
config SFP02_PARAMS
string "Parameters for one SFP device type"
......@@ -361,8 +323,76 @@ config PTP_CUSTOM
endchoice
menu "Management configuration"
config SNMP_TRAPSINK_ADDRESS
string "Static IP address or name where to send SNMPv1 traps"
help
If not empty, the address or name is ussed as "trapsink"
destination in the SNMP configuration file for the switch.
It empty, no v1 traps are generated. If both this and
the following TRAP2SINK_ADDRESS are set, snmpd sends two
traps (one per protocol version). Trapcommunity is "public"
(not configurable so far).
config SNMP_TRAP2SINK_ADDRESS
string "Static IP address or name where to send SNMPv2c traps"
help
If not empty, the address or name is ussed as "trap2sink"
destination in the SNMP configuration file for the switch.
It empty, no v2c traps are generated. Trapcommunity is "public"
(not configurable so far).
config SNMP_RO_COMMUNITY
string "Read-only community name for SNMP V1/V2 management"
default "public"
help
If not empty, the 'community' name is a sort of password,
that travels as clear text (we don't support encrypted SNMPv3
yet). The default is good for testing, but should be changed
for production. Please note, however, that the switch processes
SNMP only on the CPU Ethernet port (the copper "management" port).
config SNMP_RW_COMMUNITY
string "Read-write community name for SNMP V1/V2 management"
default "private"
help
If not empty, the 'community' name is a sort of password,
that travels as clear text (we don't support encrypted SNMPv3
yet). The default is good for testing, but should be changed
for production. Please note, however, that the switch processes
SNMP only on the CPU Ethernet port (the copper "management" port).
config SNMP_TEMP_THOLD_FPGA
int "Threshold level for FPGA temperature"
default "0"
help
Threshold level for FPGA temperature, when exceeded warning is
notified by WR-SWITCH-MIB::tempWarning
config SNMP_TEMP_THOLD_PLL
int "Threshold level for PLL temperature"
default "0"
help
Threshold level for PLL temperature, when exceeded warning is
notified by WR-SWITCH-MIB::tempWarning
config SNMP_TEMP_THOLD_PSL
int "Threshold level for Power Supply Left (PSL) temperature"
default "0"
help
Threshold level for Power Supply Left (PSL) temperature, when
exceeded warning is notified by WR-SWITCH-MIB::tempWarning
config SNMP_TEMP_THOLD_PSR
int "Threshold level for Power Supply Right (PSR) temperature"
default "0"
help
Threshold level for Power Supply Right (PSR) temperature, when
exceeded warning is notified by WR-SWITCH-MIB::tempWarning
endmenu
config PTP_CUSTOM_FILENAME
string "Pathname for your custom ppsi.conf"
depends on PTP_CUSTOM
default "/wr/etc/ppsi-custom.conf"
......@@ -564,12 +564,6 @@ but sooner or later I'll fix it. As a side effect, I now use
the two contexts concurrently in an ambiguous way. No, I'm not
proud of this code.
I don't feel confident with all the data structures as yet, and there
still is some magic in all of this. This is confirmed by a buglet in
the current code, that makes @i{snmpwalk} always return one item after
the end of the table -- most likely I need to fix @t{next_entry()}
to return @t{NULL} earlier.
@c =========================================================================
@node wrsPpsi
@section wrsPpsi
......
......@@ -1490,10 +1490,8 @@ RPC servers are created in the following places:
@table @code
@item userspace/wrsw_rtud/rtud_exports.c
@c FIXME: rtud should use shmem for status
The socket is called @t{rtud} and is used by the @i{rtu_stat}
program to gather runtime information, and by @i{wrs_vlans}
The socket is called @t{rtud} and is used by @i{wrs_vlans}
to request actual actions.
@item userspace/ppsi/arch-wrs/wrs-startup.c
......@@ -1507,9 +1505,8 @@ RPC servers are created in the following places:
This channel is called @t{wrsw_hal} but the code uses is through
the macro @t{WRSW_HAL_SERVER_ADDR}. The RPC server is used
both for status and commands, but status is already exported
in shared memory, and we are converting the clients; status
RPC calls will be removed soon.
only for commands. All clients use shared memory to get status
information.
@item wrpc-sw::ipc/rt_ipc.c
......@@ -1522,28 +1519,17 @@ Clients are created in the following places:
@table @code
@item userspace/tools/rtu_stat.c
@c FIXME: rtu_stat should use shmem
The tool connects to @i{rtud} to get runtime information.
@item userspace/tools/wrs_vlans.c
@t{wrs_vlans} connects to the @i{rtud} to request configuration
actions related to vlan setup.
@item userspace/wrsw_hal/hal_exports.c
@c FIXME: don't check with a socket, but with the shmem mechanism
A temporary client is created to check whether a HAL process
is already running.
actions related to vlan setup. All status information is passed
through shared memory.
@item userspace/tools/wr_mon.c
@c FIXME: wr_mon should use shmem
The tty-based monitoring interface connects to @i{ptpd} (@i{ppsi})
to get run-time information. It is going to be moved to
shared memory.
to enable or disable tracking. All status information is passed
from @i{HAL} and @i{ppsi} through shared memory.
@item userspace/libwr/hal_client.c
......@@ -1600,13 +1586,6 @@ the processes (excluding the @sc{rt} subsystem).
Called by library code (@t{halexp_lock_cmd}) but not used.
Called by @i{ppsi} directly in @t{wrs-time.c}.
@item rtud::get_fd_list
@itemx rtud::get_vd_list
@c FIXME: shmem these
Called by @i{rtu_stat} to report information. They can be
moved to shared memory.
@item rtud::clear_entries
@itemx rtud::add_entry
......
......@@ -217,13 +217,6 @@ interface with gateware is now simpler than it was, but software still
has remnants of old data structure. Also, the multi-threaded approach
is overkill, and the program could benefit from a simplification.
@item The SFP code needs to be cleaned up. There is unsafe string
management in 16-wide non-terminated fields, and we don't really
report all the information we have (we should copy all SFP
information to shmem: we are almost there but not completely).
Moreover, using the device name without the vendor
name is unsafe: some vendors use generic device names.
@item The @t{TRACE} support it not really working. We have serious
warning messages that were never reported. We should really print
everything to stderr and let syslog manage it (according to user
......
......@@ -464,6 +464,15 @@ value is changed by the web interface, proper action is taken.
default. Community values are strings and they default to
@t{public} and @t{private}.
@item CONFIG_SNMP_TEMP_THOLD_FPGA
@itemx CONFIG_SNMP_TEMP_THOLD_PLL
@itemx CONFIG_SNMP_TEMP_THOLD_PSL
@itemx CONFIG_SNMP_TEMP_THOLD_PSR
Threshold levels for FPGA, PLL, Power Supply Left (PSL) and Power
Supply Right (PSR) temperature sensors. When any temperature exceeds
threshold level SNMP object @t{WR-SWITCH-MIB::tempWarning} will change
accordingly.
@item CONFIG_WRS_LOG_HAL
@itemx CONFIG_WRS_LOG_RTU
@itemx CONFIG_WRS_LOG_PTP
......@@ -553,7 +562,7 @@ This is, for explanation's sake, an example of such items:
@smallexample
CONFIG_PORT09_PARAMS="name=wr9,tx=226214,rx=226758,role=slave,fiber=2"
CONFIG_SFP00_PARAMS="name=AXGE-1254-0531,tx=0,rx=0,wl_txrx=1310+1490"
CONFIG_SFP00_PARAMS="pn=AXGE-1254-0531,tx=0,rx=0,wl_txrx=1310+1490"
CONFIG_FIBER02_PARAMS="alpha_1310_1490=2.6787e-04"
@end smallexample
......@@ -589,6 +598,35 @@ wavelength, and is determined, again, by calibration.
Please note that only one alpha value is provided, because the
opposite one (@t{alpha_1490_1310}) is calculated by software.
@subheading SFP name matching
SFP matching is based on vendor name (@i{vn}), part number (@i{pn}) and vendor
serial (@i{vs}). While matching SFP's values are compared with values stored in
@t{CONFIG_SFPXX_PARAMS}.
First try is to match all SFP identifiers (@i{vn}, @i{pn} and @i{vs}) with
stored in config. If match is not successful, @i{vn} and @i{pn} of SFP are
compared only with config entries without vendor serial. If match is still not
found SFP's values are compared with config entries, which has defined only
part number. Such approach prevents matching SFPs to config entires with
defined serial.
Below are shown matching examples:
@smallexample
CONFIG_SFP00_PARAMS="vn=Axcen Photonics,pn=AXGE-3454-0531,vs=AX12390009629,tx=0,rx=0,..."
@end smallexample
Above config may be matched only to one SFP.
@smallexample
CONFIG_SFP01_PARAMS="vn=Axcen Photonics,pn=AXGE-3454-0531,tx=0,rx=0,wl_txrx=1310+1490"
@end smallexample
Above config may be matched only to SFP with vendor name "Axcen Photonics" and
part number "AXGE-3454-0531", with exception to these SFPs that were matched to
example like above (with vendor serial defined).
@smallexample
CONFIG_SFP02_PARAMS="pn=AXGE-3454-0531,tx=0,rx=0,wl_txrx=1310+1490"
@end smallexample
Config above will be matched to all SFPs with part number "AXGE-3454-0531",
that were not matched by configs above.
@subheading Other Deployments
The example above matches the choices we make at CERN, where our
......@@ -1232,10 +1270,6 @@ This a summary of the available tables and scalars:
@end table
@b{Note:} due to a buglet of mine, there is an extra item at
the end of each table (@t{96.100.2} and @t{96.100.3.2}. It makes no
harm, so its removal is not high priority.
@c @b{Note:} due to a bug in management of 64-bit values in @i{net-snmp},
@c we are using a bad work-around in the code, that may cause wrong values
@c to be returned by other versions of the agent, where this bug is fixed.
......@@ -1296,6 +1330,14 @@ WR-SWITCH-MIB::wrsDateTAI.0 = Counter64: 1406623390
WR-SWITCH-MIB::wrsDateString.0 = STRING: 2014-07-29-08:43:10
@end smallexample
Another example is to print all objects exported by switch.
@smallexample
snmpwalk -c public -v 2c wrs -m all \
-M ${WRS_OUTPUT_DIR}/build/buildroot-2011.11/output/build/netsnmp-5.6.1.1/mibs/\
:${WR_SWITCH_SW}/userspace/snmpd/ \
1
@end smallexample
@c ==========================================================================
@node show-pstats
@section show-pstats
......
......@@ -86,46 +86,12 @@ typedef struct {
*/
/* Prototypes of functions that call on rpc */
extern int halexp_check_running(void);
extern int halexp_reset_port(const char *port_name);
extern int halexp_calibration_cmd(const char *port_name, int command, int on_off);
extern int halexp_lock_cmd(const char *port_name, int command, int priority);
extern int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
/* Export structures, shared by server and client for argument matching */
#ifdef HAL_EXPORT_STRUCTURES
//int halexp_check_running();
struct minipc_pd __rpcdef_check_running = {
.name = "check_running",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_END,
},
};
//int halexp_reset_port(const char *port_name);
struct minipc_pd __rpcdef_reset_port = {
.name = "reset_port",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_END,
},
};
//int halexp_calibration_cmd(const char *port_name, int command, int on_off);
struct minipc_pd __rpcdef_calibration_cmd = {
.name = "calibration_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_lock_cmd(const char *port_name, int command, int priority);
struct minipc_pd __rpcdef_lock_cmd = {
.name = "lock_cmd",
......
......@@ -4,43 +4,14 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int valid;
char slave_servo_state[32];
char sync_source[32];
int tracking_enabled;
int64_t mu;
int64_t delay_ms;
int64_t delta_tx_m;
int64_t delta_rx_m;
int64_t delta_tx_s;
int64_t delta_rx_s;
int64_t fiber_asymmetry;
int64_t total_asymmetry;
int64_t cur_offset;
int64_t cur_setpoint;
int64_t cur_skew;
int64_t update_count;
} ptpdexp_sync_state_t ;
#define PTPDEXP_COMMAND_TRACKING 1
#define PTPDEXP_COMMAND_MAN_ADJUST_PHASE 2
extern int ptpdexp_get_sync_state(ptpdexp_sync_state_t *state);
extern int ptpdexp_cmd(int cmd, int value);
/* Export structures, shared by server and client for argument matching */
#ifdef PTP_EXPORT_STRUCTURES
//int ptpdexp_get_sync_state(ptpdexp_sync_state_t *state);
struct minipc_pd __rpcdef_get_sync_state = {
.name = "get_sync_state",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, ptpdexp_sync_state_t),
.args = {
MINIPC_ARG_END,
},
};
//int ptpdexp_cmd(int cmd, int value);
struct minipc_pd __rpcdef_cmd = {
.name = "cmd",
......
......@@ -28,6 +28,7 @@
#include <libwr/pio.h>
#include <libwr/fan.h>
#include <libwr/hal_shmem.h>
#include <at91_softpwm.h>
......@@ -39,7 +40,10 @@
#include "spwm-regs.h"
#include <libwr/util.h>
#define FAN_TEMP_SENSOR_ADDR 0x4c
#define TEMP_SENSOR_ADDR_FPGA 0x4A /* (7bits addr) IC19 Below FPGA */
#define TEMP_SENSOR_ADDR_PLL 0x4C /* (7bits addr) IC18 PLLs */
#define TEMP_SENSOR_ADDR_PSL 0x49 /* (7bits addr) IC20 Power supply left */
#define TEMP_SENSOR_ADDR_PSR 0x4D /* (7bits addr) IC17 Power supply right */
#define DESIRED_TEMPERATURE 55.0
......@@ -204,7 +208,7 @@ static int shw_init_i2c_sensors()
return 0;
}
int shw_init_fans()
int shw_init_fans(void)
{
uint32_t val = 0;
......@@ -250,7 +254,11 @@ int shw_init_fans()
shw_init_i2c_sensors();
tmp100_write_reg(FAN_TEMP_SENSOR_ADDR, 1, 0x60); // 12-bit resolution
/* set all to 12-bit resolution */
tmp100_write_reg(TEMP_SENSOR_ADDR_FPGA, 1, 0x60);
tmp100_write_reg(TEMP_SENSOR_ADDR_PLL, 1, 0x60);
tmp100_write_reg(TEMP_SENSOR_ADDR_PSL, 1, 0x60);
tmp100_write_reg(TEMP_SENSOR_ADDR_PSR, 1, 0x60);
pi_init(&fan_pi);
......@@ -263,17 +271,24 @@ int shw_init_fans()
* Reads out the temperature and drives the fan accordingly
* note: This call is done by hal_main.c:hal_update()
*/
void shw_update_fans()
void shw_update_fans(struct hal_temp_sensors *sensors)
{
static int64_t last_tics = -1;
int64_t cur_tics = shw_get_tics();
if (fan_update_timeout > 0
&& (last_tics < 0 || (cur_tics - last_tics) > fan_update_timeout)) {
float t_cur = tmp100_read_temp(FAN_TEMP_SENSOR_ADDR);
/* drive fan based on PLL temperature */
float t_cur = tmp100_read_temp(TEMP_SENSOR_ADDR_PLL);
float drive = pi_update(&fan_pi, t_cur - DESIRED_TEMPERATURE);
//pr_info("t=%f,pwm=%f\n",t_cur , drive);
shw_pwm_speed(0xFF, drive / 1000); //enable two and one
/* update sensor values */
sensors->fpga = tmp100_read_reg(TEMP_SENSOR_ADDR_FPGA, 0, 2);
sensors->pll = tmp100_read_reg(TEMP_SENSOR_ADDR_PLL, 0, 2);
sensors->psl = tmp100_read_reg(TEMP_SENSOR_ADDR_PSL, 0, 2);
sensors->psr = tmp100_read_reg(TEMP_SENSOR_ADDR_PSR, 0, 2);
last_tics = cur_tics;
}
}
......@@ -6,15 +6,10 @@
#define HAL_EXPORT_STRUCTURES
#include <hal/hal_exports.h>
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
#define DEFAULT_TO 200000 /* ms */
static struct minipc_ch *hal_ch;
static struct wrs_shm_head *hal_head;
static struct hal_port_state *hal_ports;
static int hal_nports;
int halexp_lock_cmd(const char *port_name, int command, int priority)
{
......@@ -39,17 +34,6 @@ int halexp_pps_cmd(int cmd, hexp_pps_params_t * params)
/* Some clients call this, some call the client_init() defined later */
int halexp_client_try_connect(int retries, int timeout)
{
struct hal_shmem_header *h;
struct hal_port_state *p;
hal_head = wrs_shm_get(wrs_shm_hal,"", WRS_SHM_READ);
if (!hal_head)
return -1;
h = (void *)hal_head + hal_head->data_off;
hal_nports = h->nports;
p = wrs_shm_follow(hal_head, h->ports);
hal_ports = p; /* This is used in later calls */
for (;;) {
hal_ch =
minipc_client_create(WRSW_HAL_SERVER_ADDR,
......@@ -67,8 +51,3 @@ int halexp_client_try_connect(int retries, int timeout)
return -1;
}
int halexp_client_init()
{
return halexp_client_try_connect(0, 0);
}
#ifndef I2C_SFP_H
#define I2C_SFP_H
#ifndef I2C_IO_H
#define I2C_IO_H
#include "i2c.h"
......@@ -25,4 +25,4 @@ int shw_i2c_io_scan(uint8_t * dev_map);
int shw_get_hw_ver();
uint8_t shw_get_fpga_type();
#endif //I2C_SFP_H
#endif //I2C_IO_H
......@@ -520,7 +520,7 @@ int shw_sfp_read_header(int num, struct shw_sfp_header *head)
ret = shw_sfp_module_scan();
if (!(ret & (1 << num)))
return -1;
return -2;
ret =
shw_sfp_read(num, I2C_SFP_ADDRESS, 0x0,
......@@ -562,14 +562,28 @@ int shw_sfp_read_db(void)
int error, val, index;
for (index = 0; ; index++) {
error = libwr_cfg_convert2("SFP%02i_PARAMS", "name",
error = libwr_cfg_convert2("SFP%02i_PARAMS", "pn",
LIBWR_STRING, s, index);
if (error)
return 0; /* no more, no error */
sfp = calloc(1, sizeof(*sfp));
strncpy(sfp->part_num, s, sizeof(sfp->part_num));
error = libwr_cfg_convert2("SFP%02i_PARAMS", "vn",
LIBWR_STRING, s, index);
/* copy vendor name if found */
if (!error)
strncpy(sfp->vendor_name, s, sizeof(sfp->vendor_name));
sfp->vendor_serial[0] = 0;
error = libwr_cfg_convert2("SFP%02i_PARAMS", "vs",
LIBWR_STRING, s, index);
/* copy serial name if found */
if (!error)
strncpy(sfp->vendor_serial, s,
sizeof(sfp->vendor_serial));
sfp->flags = SFP_FLAG_CLASS_DATA; /* never used */
/* These are uint32_t as I write this. So use "int val" */
......@@ -605,45 +619,60 @@ int shw_sfp_read_db(void)
return 0;
}
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num)
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num,
struct shw_sfp_header *head)
{
uint32_t ret;
struct shw_sfp_header head;
struct shw_sfp_caldata *t;
struct shw_sfp_caldata *other = NULL;
struct shw_sfp_caldata *match_pn_vn = NULL;
struct shw_sfp_caldata *match_pn = NULL;
char *vn = (char *)head->vendor_name;
char *pn = (char *)head->vendor_pn;
char *vs = (char *)head->vendor_serial;
int i;
ret = shw_sfp_module_scan();
if (!(ret & (1 << num))) {
printf("sfp not inserted into slot: %d\n", num);
return NULL;
/* Replace spaces at the end of strings with 0 needed for
* string comparison inside shw_sfp_get_cal_data.
* String may contain spaces, standard says only about space padding */
for (i = 15; i >= 0 ; i--) {
if (vn[i] != 0x20)
break;
vn[i] = 0;
}
if (shw_sfp_read_header(num, &head) < 0) {
printf("failed to read sfp header for slot %d\n", num);
return NULL;
for (i = 15; i >= 0 ; i--) {
if (pn[i] != 0x20)
break;
pn[i] = 0;
}
char *pn = (char *)head.vendor_pn;
char *vs = (char *)head.vendor_serial;
int i;
for (i = 0; i < 16; i++) {
if (pn[i] == 0x20)
pn[i] = 0;
if (vs[i] == 0x20)
vs[i] = 0;
for (i = 15; i >= 0 ; i--) {
if (vs[i] != 0x20)
break;
vs[i] = 0;
}
t = shw_sfp_cal_list;
/* In the first pass, look for serial number */
while (t) {
// printf("search1 %s %s\n", t->part_num, t->vendor_serial);
if (strncmp(pn, t->part_num, 16) == 0
&& strncmp(t->vendor_serial, "", 16) == 0)
other = t;
else if (strncmp(pn, t->part_num, 16) == 0
&& strncmp(vs, t->vendor_serial, 16) == 0)
if (t->vendor_name[0] == 0
&& strncmp(pn, t->part_num, 16) == 0
&& t->vendor_serial[0] == 0)
/* matched pn, but vn and vs not defined */
match_pn = t;
else if (strncmp(vn, t->vendor_name, 16) == 0
&& strncmp(pn, t->part_num, 16) == 0
&& t->vendor_serial[0] == 0)
/* matched vn, pn, but vs not defined */
match_pn_vn = t;
else if (strncmp(vn, t->vendor_name, 16) == 0
&& strncmp(pn, t->part_num, 16) == 0
&& strncmp(vs, t->vendor_serial, 16) == 0)
/* matched vn, pn, vs */
return t;
t = t->next;
}
if (other)
return other;
if (match_pn_vn)
return match_pn_vn;
if (match_pn)
return match_pn;
return NULL;
}
#ifndef __LIBWR_FAN_H
#define __LIBWR_FAN_H
#include <libwr/hal_shmem.h>
#define SHW_FAN_UPDATETO_DEFAULT 5
int shw_init_fans();
void shw_update_fans();
int shw_init_fans(void);
void shw_update_fans(struct hal_temp_sensors *sensors);
#endif /* __LIBWR_FAN_H */
......@@ -4,7 +4,6 @@
#include <hal/hal_exports.h>
int halexp_client_init();
int halexp_client_try_connect(int retries, int timeout);
#endif /* __LIBWR_HAL_CLIENT_H */
......@@ -102,12 +102,24 @@ struct hal_port_state {
uint32_t ep_base;
};
struct hal_temp_sensors {
int fpga; /* IC19 */
int pll; /* IC18 */
int psl; /* IC20 Power Supply Left (PSL) */
int psr; /* IC17 Power Supply Right (PSR) */
int fpga_thold; /* Threshold value for FPGA temperature */
int pll_thold; /* Threshold value for PLL temperature */
int psl_thold; /* Threshold value for PSL temperature */
int psr_thold; /* Threshold value for PSR temperature */
};
/* This is the overall structure stored in shared memory */
#define HAL_SHMEM_VERSION 4 /* Version 4 because of new fields in struct
* hal_port_state */
#define HAL_SHMEM_VERSION 6 /* Version 6 because of new structure
* hal_temp_sensors in hal_shmem_header */
struct hal_shmem_header {
int nports;
struct hal_port_state *ports;
struct hal_temp_sensors temp;
};
static inline int state_up(int state)
......
......@@ -20,14 +20,23 @@
#define SFP_FLAG_CLASS_DATA (1 << 0)
#define SFP_FLAG_DEVICE_DATA (1 << 1)
#define SFP_FLAG_1GbE (1 << 2) /* SFP is 1GbE */
#define SFP_FLAG_IN_DB (1 << 3) /* SFP is present in data base */
#define SFP_SPEED_1Gb 0x0D /* Speed of SFP in 100MB/s. According to
* SFF-8472.PDF: By convention 1.25 Gb/s
* should be rounded up to 0Dh (13 in
* units of 100 MBd) for Ethernet
* 1000BASE-X. */
struct shw_sfp_caldata {
int flags;
uint32_t flags;
/*
* Part number used to identify it. Serial number because we
* may specify per-specimen delays, but it is not used at this
* point in time
*/
char vendor_name[16];
char part_num[16];
char vendor_serial[16];
/* Callibration data */
......@@ -103,7 +112,8 @@ int shw_sfp_read_db(void);
int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head);
/* return NULL if no data found */
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num);
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num,
struct shw_sfp_header *head);
/* Read and verify the header all at once. returns -1 on failure */
int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head);
......
ppsi @ ea68c737
Subproject commit 2181324ae355f72299abc63b5fa8c9e1fcc742b1
Subproject commit ea68c737c6049f6fbe75827f3be236956c2207bc
......@@ -20,7 +20,7 @@ OBJDUMP = $(CROSS_COMPILE)objdump
# defer running "net-snmp-config --cflags" so it is visible in make output
CFLAGS += -fPIC -Wall $$($(NET_SNMP_CONFIG) --cflags | sed s,-I/usr/include,,)
LDFLAGS = -shared $$($(NET_SNMP_CONFIG) --ldflags)
CFLAGS += -I../include -I../libwr/include -I../ppsi/include -I../mini-rpc
CFLAGS += -I../include -I../libwr/include -I../ppsi/include -I../ppsi/arch-wrs/include
CFLAGS += -DWRS_WITH_SNMP_HACKISH_LOG=0
SHLIB = wrsSnmp.so
......
This diff is collapsed.
......@@ -18,21 +18,3 @@ void init_wrsSnmp(void)
init_wrsVersion();
init_wrsDate();
}
/* open a file or a pipe, so I test with files, and run with pipes */
FILE *wrs_fpopen(char *file_or_pipe, char *mode)
{
if (file_or_pipe[0] == '|')
return popen(file_or_pipe + 1, mode);
else
return fopen(file_or_pipe, mode);
}
void wrs_fpclose(FILE *f, char *file_or_pipe)
{
if (file_or_pipe[0] == '|')
pclose(f);
else
fclose(f);
}
This diff is collapsed.
......@@ -57,9 +57,18 @@ wrsPstats_handler(netsnmp_mib_handler *handler,
logmsg("%s: %i\n", __func__, __LINE__);
/* our "context" is the counter number; "subid" the column i.e. the port */
counter = (intptr_t)netsnmp_extract_iterator_context(request);
if (!counter)
/* NULL returned from
* netsnmp_extract_iterator_context shuld be
* interpreted as end of table */
continue;
/* change range of counter (1..39 (snmp is 1 based) ->
* 0..38 (pstats_global_data array is 0 based)) */
counter--;
table_info = netsnmp_extract_table_info(request);
wrport = table_info->colnum - 2; /* port is 0-based and position 1 is the string */
/* port is 0-based and position 1 is the string */
wrport = table_info->colnum - 2;
logmsg("counter %i, port %i\n", counter, wrport);
if (wrport < 0) {
......@@ -110,8 +119,10 @@ wrsPstats_next_entry(void **loop_context,
/* Create the row OID: only the counter index */
snmp_set_var_value(index, (u_char *)&i, sizeof(i));
/* Set the data context (1..39 -> 0..38) */
*data_context = (void *)(intptr_t)(i - 1);
/* Set the data context (1..39)
* Cannot be set to 0, because netsnmp_extract_iterator_context returns
* NULL in function wrsPstats_handler when table is over */
*data_context = (void *)i;
/* and set the loop context for the next iteration */
*loop_context = (void *)i;
return index;
......
......@@ -85,8 +85,4 @@ extern void init_wrsDate(void);
#define WRS_OID 1, 3, 6, 1, 4, 1, 96, 100
/* Open a file or a pipe according to name[0] (e.g. "|wr_mon", "/tmp/log") */
extern FILE *wrs_fpopen(char *file_or_pipe, char *mode);
extern void wrs_fpclose(FILE *f, char *file_or_pipe);
#endif /* WRS_SNMP_H */
......@@ -23,33 +23,26 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libwr/util.h>
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
#include <libwr/rtu_shmem.h>
#include <minipc.h>
#include <rtud_exports.h>
#include <mac.h>
#include <errno.h>
#define MINIPC_TIMEOUT 200
static struct minipc_ch *rtud_ch;
// forwarding entries
void rtudexp_get_fd_list(rtudexp_fd_list_t *list, int start_from)
{
minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_get_fd_list, list,
start_from);
}
// vlan entries
void rtudexp_get_vd_list(rtudexp_vd_list_t *list, int current)
{
minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_get_vd_list, list,
current);
}
struct wrs_shm_head *rtu_port_shmem;
static struct rtu_vlan_table_entry vlan_tab_local[NUM_VLANS];
static struct rtu_filtering_entry rtu_htab_local[RTU_BUCKETS * HTAB_ENTRIES];
int rtudexp_clear_entries(int netif, int force)
{
......@@ -76,42 +69,6 @@ int rtudexp_vlan_entry(int vid, int fid, const char *ch_mask, int drop, int prio
return (ret<0)?ret:val;
}
#define RTU_MAX_ENTRIES 8192
#define NUM_VLANS 4096
void fetch_rtu_fd(rtudexp_fd_entry_t *d, int *n_entries)
{
int start = 0, n = 0;
rtudexp_fd_list_t list;
do {
rtudexp_get_fd_list(&list, start);
// printf("num_rules %d\n", list.num_rules);
memcpy( d+n, list.list, sizeof(rtudexp_fd_entry_t) * list.num_rules);
start=list.next;
n+=list.num_rules;
} while(start > 0);
// printf("%d rules \n", n);
*n_entries = n;
}
int fetch_rtu_vd(rtudexp_vd_entry_t *d, int *n_entries)
{
int start = 0, n = 0;
rtudexp_vd_list_t list;
do {
rtudexp_get_vd_list(&list, start);
memcpy( d+n, list.list, sizeof(rtudexp_vd_entry_t) * list.num_entries);
start=list.next;
n+=list.num_entries;
} while(start > 0);
*n_entries = n;
return 0;
}
/**
* \brief Write mac address into a buffer to avoid concurrent access on static variable.
*/
......@@ -123,15 +80,12 @@ char *mac_to_buffer(uint8_t mac[ETH_ALEN],char buffer[ETH_ALEN_STR])
return buffer;
}
static int cmp_entries(const void *p1, const void *p2)
static int cmp_rtu_entries(const void *p1, const void *p2)
{
rtudexp_fd_entry_t *e1 = (rtudexp_fd_entry_t *)p1;
rtudexp_fd_entry_t *e2 = (rtudexp_fd_entry_t *)p2;
const struct rtu_filtering_entry *e1 = p1;
const struct rtu_filtering_entry *e2 = p2;
return memcmp(e1->mac, e2->mac, 6);
// return strcmp(* (char * const *) p1, * (char * const *) p2);
}
char *decode_ports(int dpm, int nports)
......@@ -185,6 +139,13 @@ int get_nports_from_hal(void)
fprintf(stderr, "unable to open shm for HAL!\n");
exit(-1);
}
/* check hal's shm version */
if (hal_head->version != HAL_SHMEM_VERSION) {
fprintf(stderr, "rtu_stat: unknown hal's shm version %i "
"(known is %i)\n",
hal_head->version, HAL_SHMEM_VERSION);
exit(-1);
}
h = (void *)hal_head + hal_head->data_off;
/* Assume number of ports does not change in runtime */
hal_nports_local = h->nports;
......@@ -197,26 +158,119 @@ int get_nports_from_hal(void)
return hal_nports_local;
}
int main(int argc, char **argv)
int read_vlans(void)
{
unsigned ii;
unsigned retries = 0;
struct rtu_vlan_table_entry *vlan_tab_shm;
struct rtu_shmem_header *rtu_hdr;
rtu_hdr = (void *)rtu_port_shmem + rtu_port_shmem->data_off;
vlan_tab_shm = wrs_shm_follow(rtu_port_shmem, rtu_hdr->vlans);
if (!vlan_tab_shm)
return -2;
/* read data, with the sequential lock to have all data consistent */
while (1) {
ii = wrs_shm_seqbegin(rtu_port_shmem);
memcpy(&vlan_tab_local, vlan_tab_shm,
NUM_VLANS * sizeof(*vlan_tab_shm));
retries++;
if (retries > 100)
return -1;
if (!wrs_shm_seqretry(rtu_port_shmem, ii))
break; /* consistent read */
usleep(1000);
}
return 0;
}
/* Read filtes from rtud's shm, convert hashtable to regular table */
int read_htab(int *read_entries)
{
unsigned ii;
unsigned retries = 0;
struct rtu_filtering_entry *htab_shm;
struct rtu_shmem_header *rtu_hdr;
struct rtu_filtering_entry *empty;
rtu_hdr = (void *)rtu_port_shmem + rtu_port_shmem->data_off;
htab_shm = wrs_shm_follow(rtu_port_shmem, rtu_hdr->filters);
if (!htab_shm)
return -2;
/* Read data, with the sequential lock to have all data consistent */
while (1) {
ii = wrs_shm_seqbegin(rtu_port_shmem);
memcpy(&rtu_htab_local, htab_shm,
RTU_BUCKETS * HTAB_ENTRIES * sizeof(*htab_shm));
retries++;
if (retries > 100)
return -1;
if (!wrs_shm_seqretry(rtu_port_shmem, ii))
break; /* consistent read */
usleep(1000);
}
rtudexp_fd_entry_t fd_list[RTU_MAX_ENTRIES];
rtudexp_vd_entry_t vd_list[NUM_VLANS];
/* Convert hash table to ordered table. Table will be qsorted later,
* no need to qsort entire table */
*read_entries = 0;
empty = rtu_htab_local;
for (ii = 0; ii < RTU_BUCKETS * HTAB_ENTRIES; ii++) {
if (rtu_htab_local[ii].valid) {
memcpy(empty, &rtu_htab_local[ii], sizeof(*htab_shm));
empty++;
(*read_entries)++;
}
}
int n_fd_entries, n_vd_entries;
return 0;
}
int open_rtu_shm(void)
{
/* open rtu shm */
rtu_port_shmem = wrs_shm_get(wrs_shm_rtu, "", WRS_SHM_READ);
if (!rtu_port_shmem) {
printf("rtu_stat: %s: Can't join shmem: %s\n", __func__,
strerror(errno));
return -1;
}
/* check rtu shm version */
if (rtu_port_shmem->version != RTU_SHMEM_VERSION) {
printf("dump rtu: unknown version %i (known is %i)\n",
rtu_port_shmem->version, RTU_SHMEM_VERSION);
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
int i, isok;
int nports;
int htab_read_entries;
int vid_active = 0;
char mac_buf[ETH_ALEN_STR];
nports = get_nports_from_hal();
rtud_ch = minipc_client_create("rtud", 0);
if(!rtud_ch)
if (!rtud_ch)
{
printf("Can't connect to RTUd mini-rpc server\n");
return -1;
}
minipc_set_logfile(rtud_ch,stderr);
/* Open rtud's shmem */
if (open_rtu_shm()) {
printf("Can't open RTUd shmem\n");
return -1;
}
isok=0;
if(argc>1)
{
......@@ -247,52 +301,77 @@ int main(int argc, char **argv)
}
fetch_rtu_fd(fd_list, &n_fd_entries);
/* read filter entires from shm to local memory for data consistency */
if (read_htab(&htab_read_entries)) {
printf("Too many retries while reading htab entries from RTUd "
"shmem\n");
return -1;
}
qsort(fd_list, n_fd_entries, sizeof(rtudexp_fd_entry_t), cmp_entries);
qsort(rtu_htab_local, htab_read_entries,
sizeof(struct rtu_filtering_entry), cmp_rtu_entries);
printf("RTU Filtering Database Dump: %d rules\n", n_fd_entries);
printf("RTU Filtering Database Dump: %d rules\n", htab_read_entries);
printf("\n");
printf("MAC Dst.ports FID Type Age [s]\n");
printf("----------------------------------------------------------------------------------\n");
char mac_buf[ETH_ALEN_STR];
for(i=0;i<n_fd_entries;i++)
for (i = 0; i < htab_read_entries; i++)
{
if (!rtu_htab_local[i].valid)
continue;
printf("%-25s %-12s %2d %s (hash %03x:%x) ",
mac_to_buffer(fd_list[i].mac,mac_buf),
decode_ports(fd_list[i].dpm, nports),
fd_list[i].fid,
fd_list[i].dynamic ? "DYNAMIC":"STATIC ",
fd_list[i].hash,
fd_list[i].bucket);
if(fd_list[i].dynamic)
printf("%d\n", fd_list[i].age);
mac_to_buffer(rtu_htab_local[i].mac, mac_buf),
decode_ports(rtu_htab_local[i].port_mask_dst, nports),
rtu_htab_local[i].fid,
rtu_htab_local[i].dynamic ? "DYNAMIC" : "STATIC ",
rtu_htab_local[i].addr.hash,
rtu_htab_local[i].addr.bucket);
if (rtu_htab_local[i].dynamic)
printf("%d\n", rtu_htab_local[i].age);
else
printf("-\n");
}
printf("\n");
fetch_rtu_vd(vd_list, &n_vd_entries);
/* read vlans from shm to local memory for data consistency */
if (read_vlans()) {
printf("Too many retries while reading vlans from RTUd "
"shmem\n");
return -1;
}
printf("RTU VLAN Table Dump: %d active VIDs defined\n", n_vd_entries);
printf("RTU VLAN Table Dump:\n");
printf("\n");
printf(" VID FID MASK DROP PRIO PRIO_OVERRIDE\n");
printf("-----------------------------------------------------------\n");
for(i=0;i<n_vd_entries;i++)
{
printf("%4d %4d 0x%8x ", vd_list[i].vid, vd_list[i].fid, vd_list[i].port_mask);
if(vd_list[i].drop == 0) printf("NO ");
else printf("YES");
if(vd_list[i].has_prio == 0) printf(" -- ");
else printf(" %1d ",vd_list[i].prio);
if(vd_list[i].prio_override == 0) printf(" NO ");
else printf(" YES ");
for (i = 0; i < NUM_VLANS; i++) {
if ((vlan_tab_local[i].drop != 0)
&& (vlan_tab_local[i].port_mask == 0x0))
continue;
printf("%4d %4d 0x%8x ", i, vlan_tab_local[i].fid,
vlan_tab_local[i].port_mask);
if (vlan_tab_local[i].drop == 0)
printf("NO ");
else
printf("YES");
if (vlan_tab_local[i].has_prio == 0)
printf(" -- ");
else
printf(" %1d ", vlan_tab_local[i].prio);
if (vlan_tab_local[i].prio_override == 0)
printf(" NO ");
else
printf(" YES ");
printf("\n");
vid_active++;
}
printf("\n");
printf("%d active VIDs defined\n", vid_active);
printf("\n");
return 0;
}
This diff is collapsed.
......@@ -67,6 +67,13 @@ int hal_shm_init(void)
"FATAL: wr_phytool unable to open shm to HAL.\n");
return -1;
}
/* check hal's shm version */
if (hal_head->version != HAL_SHMEM_VERSION) {
fprintf(stderr, "wr_mon: unknown hal's shm version %i "
"(known is %i)\n",
hal_head->version, HAL_SHMEM_VERSION);
return -1;
}
h = (void *)hal_head + hal_head->data_off;
......
......@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <libwr/shmem.h>
......@@ -11,6 +12,7 @@
#include <ppsi/ppsi.h>
#include <ppsi-wrs.h>
/* be safe, in case some other header had them slightly differently */
#undef container_of
#undef offsetof
......@@ -23,7 +25,6 @@
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
char *name_id_to_name[WRS_SHM_N_NAMES] = {
[wrs_shm_ptp] = "ptpd/ppsi",
[wrs_shm_rtu] = "wrsw_rtud",
......@@ -45,8 +46,11 @@ enum dump_type {
dump_type_unsigned_char,
dump_type_unsigned_short,
dump_type_double,
dump_type_float,
dump_type_pointer,
/* and strange ones, from IEEE */
dump_type_UInteger64,
dump_type_Integer64,
dump_type_UInteger32,
dump_type_Integer32,
dump_type_UInteger16,
......@@ -61,8 +65,14 @@ enum dump_type {
/* and this is ours */
dump_type_TimeInternal,
dump_type_ip_address,
dump_type_sfp_flags,
dump_type_port_mode,
dump_type_sensor_temp,
};
static int dump_all_rtu_entries = 0; /* rtu exports 4096 vlans and 2048 htab
entries */
/*
* A structure to dump fields. This is meant to simplify things, see use here
*/
......@@ -93,6 +103,12 @@ void dump_one_field(void *addr, struct dump_info *info)
printf("%02x%c", ((unsigned char *)p)[i],
i == info->size - 1 ? '\n' : ':');
break;
case dump_type_UInteger64:
printf("%lld\n", *(unsigned long long *)p);
break;
case dump_type_Integer64:
printf("%lld\n", *(long long *)p);
break;
case dump_type_uint32_t:
printf("0x%08lx\n", (long)*(uint32_t *)p);
break;
......@@ -118,13 +134,15 @@ void dump_one_field(void *addr, struct dump_info *info)
case dump_type_double:
printf("%lf\n", *(double *)p);
break;
case dump_type_float:
printf("%f\n", *(float *)p);
break;
case dump_type_pointer:
printf("%p\n", *(void **)p);
break;
case dump_type_Integer16:
printf("%i\n", *(short *)p);
break;
case dump_type_TimeInternal:
printf("correct %i: %10i.%09i:%04i\n", ti->correct,
ti->seconds, ti->nanoseconds, ti->phase);
......@@ -154,12 +172,49 @@ void dump_one_field(void *addr, struct dump_info *info)
cq->clockClass, cq->clockAccuracy, cq->clockAccuracy,
cq->offsetScaledLogVariance);
break;
case dump_type_sfp_flags:
if (*(uint32_t *)p & SFP_FLAG_CLASS_DATA)
printf("SFP class data, ");
if (*(uint32_t *)p & SFP_FLAG_DEVICE_DATA)
printf("SFP device data, ");
if (*(uint32_t *)p & SFP_FLAG_1GbE)
printf("SFP is 1GbE, ");
if (*(uint32_t *)p & SFP_FLAG_IN_DB)
printf("SFP in data base, ");
printf("\n");
break;
case dump_type_port_mode:
switch (*(uint32_t *)p) {
case HEXP_PORT_MODE_WR_MASTER:
printf("WR Master\n");
break;
case HEXP_PORT_MODE_WR_SLAVE:
printf("WR Slave\n");
break;
case HEXP_PORT_MODE_NON_WR:
printf("Non-WR\n");
break;
case HEXP_PORT_MODE_WR_M_AND_S:
printf("Auto\n");
break;
default:
printf("Undefined\n");
break;
}
break;
case dump_type_sensor_temp:
printf("%f\n", ((float)(*(int *)p >> 4)) / 16.0);
break;
}
}
void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
{
int i;
if (!addr) {
fprintf(stderr, "dump: pointer not valid\n");
return;
}
for (i = 0; i < ninfo; i++)
dump_one_field(addr, info + i);
}
......@@ -177,6 +232,20 @@ void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
.size = _size, \
}
#undef DUMP_STRUCT
#define DUMP_STRUCT struct hal_shmem_header
struct dump_info hal_shmem_info [] = {
DUMP_FIELD(int, nports),
DUMP_FIELD(sensor_temp, temp.fpga),
DUMP_FIELD(sensor_temp, temp.pll),
DUMP_FIELD(sensor_temp, temp.psl),
DUMP_FIELD(sensor_temp, temp.psr),
DUMP_FIELD(int, temp.fpga_thold),
DUMP_FIELD(int, temp.pll_thold),
DUMP_FIELD(int, temp.psl_thold),
DUMP_FIELD(int, temp.psr_thold),
};
/* map for fields of hal_port_state (hal_shmem.h) */
#undef DUMP_STRUCT
#define DUMP_STRUCT struct hal_port_state
......@@ -187,7 +256,7 @@ struct dump_info hal_port_info [] = {
DUMP_FIELD(int, hw_index),
DUMP_FIELD(int, fd),
DUMP_FIELD(int, hw_addr_auto),
DUMP_FIELD(int, mode),
DUMP_FIELD(port_mode, mode),
DUMP_FIELD(int, state),
DUMP_FIELD(int, fiber_index),
DUMP_FIELD(int, locked),
......@@ -202,7 +271,8 @@ struct dump_info hal_port_info [] = {
DUMP_FIELD(int, calib.tx_calibrated),
/* Another internal structure, with a final pointer */
DUMP_FIELD(int, calib.sfp.flags),
DUMP_FIELD(sfp_flags, calib.sfp.flags),
DUMP_FIELD_SIZE(char, calib.sfp.vendor_name, 16),
DUMP_FIELD_SIZE(char, calib.sfp.part_num, 16),
DUMP_FIELD_SIZE(char, calib.sfp.vendor_serial, 16),
DUMP_FIELD(double, calib.sfp.alpha),
......@@ -235,6 +305,10 @@ int dump_hal_mem(struct wrs_shm_head *head)
return -1;
}
h = (void *)head + head->data_off;
/* dump hal's shmem */
dump_many_fields(h, hal_shmem_info, ARRAY_SIZE(hal_shmem_info));
n = h->nports;
p = wrs_shm_follow(head, h->ports);
......@@ -293,6 +367,7 @@ int dump_rtu_mem(struct wrs_shm_head *head)
{
struct rtu_shmem_header *rtu_h;
struct rtu_filtering_entry *rtu_filters;
struct rtu_filtering_entry *rtu_filters_cur;
struct rtu_vlan_table_entry *rtu_vlans;
int i, j;
......@@ -312,16 +387,24 @@ int dump_rtu_mem(struct wrs_shm_head *head)
for (i = 0; i < HTAB_ENTRIES; i++) {
for (j = 0; j < RTU_BUCKETS; j++) {
rtu_filters_cur = rtu_filters + i*RTU_BUCKETS + j;
if ((!dump_all_rtu_entries)
&& (!rtu_filters_cur->valid))
/* don't display empty entries */
continue;
printf("dump htab[%d][%d]\n", i, j);
dump_many_fields(rtu_filters+i*RTU_BUCKETS+j,
htab_info, ARRAY_SIZE(htab_info));
dump_many_fields(rtu_filters_cur, htab_info,
ARRAY_SIZE(htab_info));
}
}
for (i = 0; i < NUM_VLANS; i++) {
for (i = 0; i < NUM_VLANS; i++, rtu_vlans++) {
if ((!dump_all_rtu_entries) && (rtu_vlans->drop != 0
&& rtu_vlans->port_mask == 0x0))
/* don't display empty entries */
continue;
printf("dump vlan %i\n", i);
dump_many_fields(rtu_vlans, vlan_info, ARRAY_SIZE(vlan_info));
rtu_vlans++;
}
return 0;
}
......@@ -345,6 +428,7 @@ struct dump_info ppg_info [] = {
DUMP_FIELD(int, rxdrop),
DUMP_FIELD(int, txdrop),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, global_ext_data),
};
#undef DUMP_STRUCT
......@@ -394,6 +478,38 @@ struct dump_info dstp_info [] = {
DUMP_FIELD(Enumeration8, timeSource),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT struct wr_servo_state_t /* Horrible typedef */
struct dump_info servo_state_info [] = {
DUMP_FIELD_SIZE(char, if_name, 16),
DUMP_FIELD(int, state),
DUMP_FIELD_SIZE(char, servo_state_name, 32),
DUMP_FIELD(int, next_state),
DUMP_FIELD(TimeInternal, mu), /* half of the RTT */
DUMP_FIELD(Integer64, picos_mu),
DUMP_FIELD(Integer32, delta_tx_m),
DUMP_FIELD(Integer32, delta_rx_m),
DUMP_FIELD(Integer32, delta_tx_s),
DUMP_FIELD(Integer32, delta_rx_s),
DUMP_FIELD(Integer32, cur_setpoint),
DUMP_FIELD(Integer32, delta_ms),
DUMP_FIELD(Integer32, delta_ms_prev),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(UInteger64, last_tics),
DUMP_FIELD(Integer32, fiber_fix_alpha),
DUMP_FIELD(Integer32, clock_period_ps),
DUMP_FIELD(int, missed_iters),
DUMP_FIELD(int, valid),
DUMP_FIELD(UInteger32, update_count),
DUMP_FIELD(int, tracking_enabled),
DUMP_FIELD(Integer64, skew),
DUMP_FIELD(Integer64, offset),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_instance
struct dump_info ppi_info [] = {
......@@ -468,6 +584,7 @@ int dump_ppsi_mem(struct wrs_shm_head *head)
DSCurrent *dsc;
DSParent *dsp;
DSTimeProperties *dstp;
struct wr_servo_state_t *global_ext_data;
int i;
if (head->version != WRS_PPSI_SHMEM_VERSION) {
......@@ -495,6 +612,11 @@ int dump_ppsi_mem(struct wrs_shm_head *head)
printf("time properties data set:\n");
dump_many_fields(dstp, dstp_info, ARRAY_SIZE(dstp_info));
global_ext_data = wrs_shm_follow(head, ppg->global_ext_data);
printf("global external data set:\n");
dump_many_fields(global_ext_data, servo_state_info,
ARRAY_SIZE(servo_state_info));
ppi = wrs_shm_follow(head, ppg->pp_instances);
for (i = 0; i < ppg->nlinks; i++) {
printf("ppsi instance %i:\n", i);
......@@ -538,13 +660,37 @@ dump_f *name_id_to_f[WRS_SHM_N_NAMES] = {
[wrs_shm_rtu] = dump_rtu_mem,
};
void print_info(char *prgname)
{
printf("usage: %s [parameters]\n", prgname);
printf(""
" Dump shmem\n"
" -a Dump all rtu entries. By default only valid\n"
" entries are printed. Note there are 2048 htab\n"
" and 4096 vlan entries!\n"
" -h Show this message\n");
}
int main(int argc, char **argv)
{
struct wrs_shm_head *head;
dump_f *f;
void *m;
int i;
int c;
while ((c = getopt(argc, argv, "ah")) != -1) {
switch (c) {
case 'a':
dump_all_rtu_entries = 1;
break;
case 'h':
default:
print_info(argv[0]);
exit(1);
}
}
for (i = 0; i < WRS_SHM_N_NAMES; i++) {
m = wrs_shm_get(i, "reader", 0);
if (!m) {
......
This diff is collapsed.
......@@ -82,16 +82,4 @@ struct rtu_vlans_t
struct rtu_vlans_t *next;
};
int print_help();
void print_config(struct s_port_vlans *vlans);
int apply_settings(struct s_port_vlans *vlans);
int clear_all();
int set_rtu_vlan(int vid, int fid, int pmask, int drop, int prio, int del, int flags);
void free_rtu_vlans(struct rtu_vlans_t *ptr);
void list_rtu_vlans(void);
void list_ep_vlans(void);
struct rtu_vlans_t* rtu_retrieve_config(void);
struct rtu_vlans_t* rtu_find_vlan(struct rtu_vlans_t *conf, int vid, int fid);
int config_rtud(void);
#endif
......@@ -23,7 +23,7 @@ CFLAGS = -O -g -Wall \
-I$(LINUX)/arch/arm/mach-at91/include
LDFLAGS = -L../libwr -L../mini-rpc \
-lminipc -lm -ldl -lwr
-lm -ldl -lwr -lminipc
all: $(BINARY)
......
......@@ -2,6 +2,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <libwr/wrs-msg.h>
#include <libwr/pps_gen.h> /* for direct access to DMPLL and PPS generator */
......@@ -10,6 +13,7 @@
#include <rt_ipc.h>
#include <minipc.h>
#include <libwr/shmem.h>
#define HAL_EXPORT_STRUCTURES
#include <hal/hal_exports.h> /* for exported structs/function protos */
......@@ -212,11 +216,20 @@ int hal_update_wripc(int ms_timeout)
to prevent from launching multiple HALs simultaneously. */
int hal_check_running()
{
struct minipc_ch *ch;
struct wrs_shm_head *hal_head;
hal_head = wrs_shm_get(wrs_shm_hal, "", WRS_SHM_READ);
if (!hal_head) {
pr_info("Unable to open shm for HAL! Unable to check if there "
"is another HAL instance running. Error: %s\n",
strerror(errno));
exit(-1);
}
ch = minipc_client_create(WRSW_HAL_SERVER_ADDR, 0);
if (!ch)
/* check if pid is 0 (shm not filled) or process with provided
* pid does not exist (probably crashed) */
if ((hal_head->pid == 0) || (kill(hal_head->pid, 0) != 0))
return 0;
minipc_close(ch);
wrs_shm_put(hal_head);
return 1;
}
......@@ -16,6 +16,7 @@
#include <libwr/shw_io.h>
#include <libwr/sfp_lib.h>
#include <libwr/config.h>
#include <libwr/hal_shmem.h>
#include "wrsw_hal.h"
#include <rt_ipc.h>
......@@ -26,6 +27,7 @@
static int daemon_mode = 0;
static hal_cleanup_callback_t cleanup_cb[MAX_CLEANUP_CALLBACKS];
struct hal_shmem_header *hal_shmem;
/* Adds a function to be called during the HAL shutdown. */
int hal_add_cleanup_callback(hal_cleanup_callback_t cb)
......@@ -235,7 +237,8 @@ int main(int argc, char *argv[])
}
hal_port_update_all();
shw_update_fans();
/* update fans and temperatures in shmem */
shw_update_fans(&hal_shmem->temp);
t1 = t2;
}
......
......@@ -33,7 +33,7 @@
#define RTS_POLL_INTERVAL 200 /* ms */
#define SFP_POLL_INTERVAL 1000 /* ms */
static void *hal_port_shmem;
extern struct hal_shmem_header *hal_shmem;
/* Port table: the only item which is not "hal_port_*", as it's much used */
static struct hal_port_state *ports;
......@@ -184,8 +184,7 @@ static int hal_port_init(int index)
int hal_port_init_all()
{
int index;
struct hal_shmem_header *hal_hdr;
struct wrs_shm_head *head;
struct wrs_shm_head *hal_shmem_hdr;
pr_info("Initializing switch ports...\n");
......@@ -202,24 +201,23 @@ int hal_port_init_all()
}
/* Allocate the ports in shared memory, so wr_mon etc can see them
Use lock since some (like rtud) wait for hal to be available */
hal_port_shmem = wrs_shm_get(wrs_shm_hal, "wrsw_hal",
hal_shmem_hdr = wrs_shm_get(wrs_shm_hal, "wrsw_hal",
WRS_SHM_WRITE | WRS_SHM_LOCKED);
if (!hal_port_shmem) {
if (!hal_shmem_hdr) {
fprintf(stderr, "%s: Can't join shmem: %s\n", __func__,
strerror(errno));
return -1;
}
head = hal_port_shmem;
hal_hdr = wrs_shm_alloc(hal_port_shmem, sizeof(*hal_hdr));
ports = wrs_shm_alloc(hal_port_shmem,
hal_shmem = wrs_shm_alloc(hal_shmem_hdr, sizeof(*hal_shmem));
ports = wrs_shm_alloc(hal_shmem_hdr,
sizeof(struct hal_port_state)
* HAL_MAX_PORTS);
if (!hal_hdr || !ports) {
if (!hal_shmem || !ports) {
fprintf(stderr, "%s: can't allocate in shmem\n", __func__);
return -1;
}
hal_hdr->ports = ports;
hal_shmem->ports = ports;
for (index = 0; index < HAL_MAX_PORTS; index++)
if (hal_port_init(index) < 0)
......@@ -230,14 +228,18 @@ int hal_port_init_all()
hal_port_nports);
/* We are done, mark things as valid */
hal_hdr->nports = hal_port_nports;
head->version = HAL_SHMEM_VERSION;
hal_shmem->nports = hal_port_nports;
hal_shmem_hdr->version = HAL_SHMEM_VERSION;
hal_shmem->temp.fpga_thold =
atoi(libwr_cfg_get("SNMP_TEMP_THOLD_FPGA"));
hal_shmem->temp.pll_thold = atoi(libwr_cfg_get("SNMP_TEMP_THOLD_PLL"));
hal_shmem->temp.psl_thold = atoi(libwr_cfg_get("SNMP_TEMP_THOLD_PSL"));
hal_shmem->temp.psr_thold = atoi(libwr_cfg_get("SNMP_TEMP_THOLD_PSR"));
/* Release processes waiting for HAL's to fill shm with correct data
When shm is opened successfully data in shm is still not populated!
Read data with wrs_shm_seqbegin and wrs_shm_seqend!
Especially for nports it is important */
wrs_shm_write(head, WRS_SHM_WRITE_END);
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
/* Create a WRIPC server for HAL public API */
return hal_init_wripc(ports);
......@@ -442,14 +444,19 @@ static void hal_port_insert_sfp(struct hal_port_state * p)
char subname[48];
int err;
if (shw_sfp_read_verify_header(p->hw_index, &shdr) < 0) {
err = shw_sfp_read_verify_header(p->hw_index, &shdr);
if (err == -2) {
pr_error("SFP module not inserted. Failed to read SFP "
"configuration header\n");
return;
} else if (err < 0) {
pr_error("Failed to read SFP configuration header\n");
return;
}
pr_info("SFP Info: Manufacturer: %.16s P/N: %.16s, S/N: %.16s\n",
shdr.vendor_name, shdr.vendor_pn, shdr.vendor_serial);
cdata = shw_sfp_get_cal_data(p->hw_index);
cdata = shw_sfp_get_cal_data(p->hw_index, &shdr);
if (cdata) {
pr_info("SFP Info: (%s) deltaTx %d "
"delta Rx %d alpha %.3f (* 1e6)\n",
......@@ -460,17 +467,23 @@ static void hal_port_insert_sfp(struct hal_port_state * p)
memcpy(&p->calib.sfp, cdata,
sizeof(struct shw_sfp_caldata));
/* Mark SFP as found in data base */
p->calib.sfp.flags |= SFP_FLAG_IN_DB;
} else {
fprintf(stderr, "Unknown SFP \"%.16s\" on port %s\n",
shdr.vendor_pn, p->name);
fprintf(stderr, "Unknown SFP vn=\"%.16s\" pn=\"%.16s\" "
"vs=\"%.16s\" on port %s\n", shdr.vendor_name,
shdr.vendor_pn, shdr.vendor_serial, p->name);
memset(&p->calib.sfp, 0, sizeof(p->calib.sfp));
}
p->state = HAL_PORT_STATE_LINK_DOWN;
shw_sfp_set_tx_disable(p->hw_index, 0);
/* Copy the strings anyways, for informative value in shmem */
strncpy(p->calib.sfp.vendor_name, (void *)shdr.vendor_name, 16);
strncpy(p->calib.sfp.part_num, (void *)shdr.vendor_pn, 16);
strncpy(p->calib.sfp.vendor_serial, (void *)shdr.vendor_serial, 16);
/* check if SFP is 1GbE */
p->calib.sfp.flags |= shdr.br_nom == SFP_SPEED_1Gb ? SFP_FLAG_1GbE : 0;
/*
* Now, we should fix the alpha value according to fiber
......@@ -495,8 +508,10 @@ static void hal_port_insert_sfp(struct hal_port_state * p)
return;
}
fprintf(stderr, "Port %s, SFP \"%.16s\", fiber %i: no alpha known\n",
p->name, p->calib.sfp.part_num, p->fiber_index);
fprintf(stderr, "Port %s, SFP vn=\"%.16s\" pn=\"%.16s\" vs=\"%.16s\", "
"fiber %i: no alpha known\n", p->name,
p->calib.sfp.vendor_name, p->calib.sfp.part_num,
p->calib.sfp.vendor_serial, p->fiber_index);
p->calib.sfp.alpha = 0;
}
......
......@@ -95,6 +95,14 @@ void init_shm(void)
sleep(1);
}
/* check hal's shm version */
if (hal_head->version != HAL_SHMEM_VERSION) {
fprintf(stderr, "rtu_drv: unknown hal's shm version %i "
"(known is %i)\n",
hal_head->version, HAL_SHMEM_VERSION);
exit(-1);
}
/* Even after HAL restart, HAL will place structures at the same
* addresses. No need to re-dereference pointer at each read. */
hal_ports = wrs_shm_follow(hal_head, h->ports);
......
......@@ -97,6 +97,11 @@ static struct rtu_vlan_table_entry *vlan_tab;
*/
static pthread_mutex_t fd_mutex;
/**
* \brief Pointer to shmem, user for write locking.
*/
static struct wrs_shm_head *rtu_port_shmem;
static struct hw_req *tail(struct hw_req *head);
static void clean_list(struct hw_req *head);
static int hw_request(int type, struct rtu_addr addr,
......@@ -120,7 +125,6 @@ int rtu_fd_init(uint16_t poly, unsigned long aging)
{
uint32_t bitmap[RTU_ENTRIES / 32];
int err;
struct wrs_shm_head *rtu_port_shmem;
struct rtu_shmem_header *rtu_hdr;
pr_info("Open rtu shmem.\n");
rtu_port_shmem = wrs_shm_get(wrs_shm_rtu, "wrsw_rtud",
......@@ -221,6 +225,8 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_mask,
struct rtu_addr eaddr;
pthread_mutex_lock(&fd_mutex);
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
// if VLAN is registered (otherwise just ignore request)
if (!vlan_tab[vid].drop) {
// Obtain FID from VLAN database
......@@ -255,6 +261,9 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_mask,
pr_error(
"Hash %03x has no buckets left.\n",
eaddr.hash);
wrs_shm_write(rtu_port_shmem,
WRS_SHM_WRITE_END);
pthread_mutex_unlock(&fd_mutex);
return -ENOMEM;
}
......@@ -280,6 +289,7 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_mask,
}
rtu_fd_commit();
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
pthread_mutex_unlock(&fd_mutex);
return ret;
}
......@@ -330,22 +340,6 @@ void rtu_fd_flush(void)
pthread_mutex_unlock(&fd_mutex);
}
struct rtu_filtering_entry *rtu_fd_lookup_htab_entry(int index)
{
int i, j, n = 0;
for (i = 0; i < RTU_ENTRIES / RTU_BUCKETS; i++) {
for (j = 0; j < RTU_BUCKETS; j++) {
if (rtu_htab[i][j].valid) {
if (n == index)
return &rtu_htab[i][j];
n++;
}
}
}
return NULL;
}
//---------------------------------------------
// Static Methods
//---------------------------------------------
......@@ -417,9 +411,12 @@ static inline int to_mem_addr(struct rtu_addr addr)
*/
static void clean_fd(void)
{
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
memset(rtu_htab, 0, sizeof(*rtu_htab) * HTAB_ENTRIES);
rtu_clean_htab();
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
}
/**
......@@ -429,6 +426,8 @@ static void clean_vd(void)
{
int i;
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
rtu_clean_vlan();
for (i = 1; i < NUM_VLANS; i++) {
vlan_tab[i].drop = 1;
......@@ -444,6 +443,7 @@ static void clean_vd(void)
vlan_tab[0].prio = 0;
rtu_write_vlan_entry(0, &vlan_tab[0]);
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
}
/**
......@@ -466,6 +466,7 @@ static void rtu_fd_age_update(void)
// Update 'last access time' for accessed entries
t = now();
// HTAB
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
for (i = 0; i < RTU_ENTRIES / 32; i++)
for (j = 0; j < 32; j++) {
agr_word = bitmap[i];
......@@ -492,6 +493,8 @@ static void rtu_fd_age_update(void)
rtu_htab[hash][bucket].last_access_t = t;
}
}
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
}
void rtu_fd_clear_entries_for_port(int dest_port)
......@@ -500,6 +503,8 @@ void rtu_fd_clear_entries_for_port(int dest_port)
int j; // bucket loop index
struct rtu_filtering_entry *ent; /* pointer to scan tables */
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
for (i = HTAB_ENTRIES; i-- > 0;) {
for (j = RTU_BUCKETS; j-- > 0;) {
ent = &rtu_htab[i][j];
......@@ -517,6 +522,7 @@ void rtu_fd_clear_entries_for_port(int dest_port)
}
// commit changes
rtu_fd_commit();
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
}
/**
......@@ -531,6 +537,8 @@ static void rtu_fd_age_out(void)
unsigned long t; // (secs)
t = now() - aging_time;
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
// HTAB
for (i = HTAB_ENTRIES; i-- > 0;) {
for (j = RTU_BUCKETS; j-- > 0;) {
......@@ -548,6 +556,7 @@ static void rtu_fd_age_out(void)
}
// commit changes
rtu_fd_commit();
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
}
/**
......@@ -558,6 +567,8 @@ static void delete_htab_entry(struct rtu_addr addr)
{
int i, n_buckets = htab_count_buckets(addr);
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
pr_info("Deleted entry for MAC %s : hash %03x:%d.\n",
mac_to_string(rtu_htab[addr.hash][addr.bucket].mac), addr.hash,
addr.bucket);
......@@ -579,6 +590,7 @@ static void delete_htab_entry(struct rtu_addr addr)
&rtu_htab[a.hash][a.bucket],
(i == n_buckets - 1) ? 1 : 0);
}
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
}
static void rtu_hw_commit(void)
......@@ -642,6 +654,7 @@ void rtu_fd_create_vlan_entry(int vid, uint32_t port_mask, uint8_t fid,
#define rtu_rd(reg) \
_fpga_readl(FPGA_BASE_RTU + offsetof(struct RTU_WB, reg))
int port_num = RTU_PSR_N_PORTS_R(rtu_rd(PSR));
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
/****************************************************************************************/
if (port_mask == 0x0 && drop == 1)
vlan_tab[vid].port_mask = 0x0;
......@@ -654,28 +667,5 @@ void rtu_fd_create_vlan_entry(int vid, uint32_t port_mask, uint8_t fid,
vlan_tab[vid].prio = prio;
rtu_write_vlan_entry(vid, &vlan_tab[vid]);
}
/**
* \brief Creates or updates a filtering entry in the VLAN table.
* @param vid VLAN ID
* @return entry of VLAN table at given VID-address
*/
struct rtu_vlan_table_entry *rtu_vlan_entry_get(int vid)
{
// First entry reserved for untagged packets.
if (vid > NUM_VLANS)
return NULL;
if (vlan_tab[vid].drop == 0)
vlan_entry_rd(vid);
return &vlan_tab[vid];
}
void vlan_entry_rd(int vid)
{
// First entry reserved for untagged packets.
pr_info(
"vlan_entry_vd: vid %d, drop=%d, fid=%d, port_mask 0x%x\n", vid,
vlan_tab[vid].drop, vlan_tab[vid].fid, vlan_tab[vid].port_mask);
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
}
......@@ -62,15 +62,8 @@ void rtu_fd_set_hash_poly(uint16_t poly);
void rtu_fd_flush(void);
void rtu_fd_clear_entries_for_port(int dest_port);
struct rtu_filtering_entry *rtu_fd_lookup_htab_entry(int index);
struct rtu_filtering_entry *rtu_fd_lookup_htab_entry(int index);
void rtu_fd_create_vlan_entry(int vid, uint32_t port_mask, uint8_t fid,
uint8_t prio, int has_prio, int prio_override,
int drop);
void vlan_entry_rd(int vid);
struct rtu_vlan_table_entry *rtu_vlan_entry_get(int vid);
#endif /*__WHITERABBIT_RTU_FD_H*/
......@@ -67,14 +67,17 @@ int read_ports(void){
unsigned retries = 0;
/* read data, with the sequential lock to have all data consistent */
do {
while (1) {
ii = wrs_shm_seqbegin(hal_head);
memcpy(hal_ports_local_copy, hal_ports,
hal_nports_local*sizeof(struct hal_port_state));
retries++;
if (retries > 100)
return -1;
} while (wrs_shm_seqretry(hal_head, ii));
if (!wrs_shm_seqretry(hal_head, ii))
break; /* consistent read */
usleep(1000);
}
return 0;
......
......@@ -47,79 +47,6 @@ static struct minipc_ch *rtud_ch;
if (minipc_export(rtud_ch, &stru) < 0) { \
pr_error("Could not export %s (rtu_ch=%p)\n",stru.name,rtud_ch); }
/* The exported function */
int rtudexp_get_fd_list(const struct minipc_pd *pd, uint32_t * args, void *ret)
{
int i;
rtudexp_fd_list_t *list = ret;
int start_from = args[0];
pr_info("GetFDList start=%d\n", start_from);
for (i = 0; i < 8; i++) {
struct rtu_filtering_entry *ent =
rtu_fd_lookup_htab_entry(start_from + i);
if (!ent)
break;
memcpy(list->list[i].mac, ent->mac, sizeof(ent->mac));
//printf("Ent: %s %x\n", mac_to_string(ent->mac), ent->port_mask_dst);
list->list[i].dpm = ent->port_mask_dst;
list->list[i].spm = ent->port_mask_src;
list->list[i].priority = 0;
list->list[i].dynamic = ent->dynamic;
list->list[i].hash = ent->addr.hash;
list->list[i].bucket = ent->addr.bucket;
list->list[i].age = ent->age;
list->list[i].fid = ent->fid;
}
list->num_rules = i;
list->next = (i < 8 ? 0 : start_from + i);
return 0;
}
/* The exported vlan */
int rtudexp_get_vd_list(const struct minipc_pd *pd, uint32_t * args, void *ret)
{
int i = 0;
rtudexp_vd_list_t *list = ret;
int current = args[0];
pr_info("GetVDList start=%d\n", current);
do {
struct rtu_vlan_table_entry *ent = rtu_vlan_entry_get(current);
if (!ent)
break;
if (ent->drop == 0 || ent->port_mask != 0x0) {
list->list[i].vid = current;
list->list[i].port_mask = ent->port_mask;
list->list[i].drop = ent->drop;
list->list[i].fid = ent->fid;
list->list[i].has_prio = ent->has_prio;
list->list[i].prio_override = ent->prio_override;
list->list[i].prio = ent->prio;
pr_info(
"vlan_entry_vd: vid %d, drop=%d, fid=%d, port_mask 0x%x\n",
list->list[i].vid, list->list[i].drop,
list->list[i].fid, list->list[i].port_mask);
i++;
}
current++;
if (current == NUM_VLANS)
break;
} while (i < 8);
list->num_entries = i;
list->next = (i < 8 ? 0 : current);
return 0;
}
int rtudexp_clear_entries(const struct minipc_pd *pd,
uint32_t * args, void *ret)
{
......@@ -196,8 +123,6 @@ int rtud_init_exports()
if (getenv("RTUD_MINIPC_DEBUG"))
minipc_set_logfile(rtud_ch, stderr);
MINIPC_EXP_FUNC(rtud_export_get_fd_list, rtudexp_get_fd_list);
MINIPC_EXP_FUNC(rtud_export_get_vd_list, rtudexp_get_vd_list);
MINIPC_EXP_FUNC(rtud_export_clear_entries, rtudexp_clear_entries);
MINIPC_EXP_FUNC(rtud_export_add_entry, rtudexp_add_entry);
MINIPC_EXP_FUNC(rtud_export_vlan_entry, rtudexp_vlan_entry);
......
......@@ -31,64 +31,6 @@
#include <stdint.h>
#include <minipc.h>
typedef struct {
uint8_t mac[8];
uint32_t dpm;
uint32_t spm;
uint8_t priority;
int dynamic;
uint16_t hash;
int bucket;
int age;
int fid;
} rtudexp_fd_entry_t;
typedef struct {
rtudexp_fd_entry_t list[8];
int num_rules;
int next;
} rtudexp_fd_list_t;
///// VLAN export
typedef struct {
int vid;
uint32_t port_mask;
uint8_t fid;
uint8_t prio;
int has_prio;
int prio_override;
int drop;
} rtudexp_vd_entry_t;
typedef struct {
rtudexp_vd_entry_t list[8];
int num_entries;
int next;
} rtudexp_vd_list_t;
/* Export this function: it returns a structure */
struct minipc_pd rtud_export_get_fd_list = {
.name = "get_fd_list",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT,
rtudexp_fd_list_t),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
/* Export this function: it returns a structure */
struct minipc_pd rtud_export_get_vd_list = {
.name = "get_vd_list",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT,
rtudexp_vd_list_t),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
/* Export of a function to set remove entry in rtu */
struct minipc_pd rtud_export_clear_entries = {
.name = "clear_entries",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment