Commit 536d37ab authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

Merge branch 'aux-diag' into proposed_master

parents b5e318d8 4348ecd9
......@@ -148,6 +148,14 @@ config SNMP_SET
help
This option enables support for SET requests for Mini SNMP responder
config SNMP_AUX_DIAG
depends on SNMP && AUX_DIAG
default y if AUX_DIAG
default n
boolean "Adds support of auxiliary diagnostics registers to SNMP"
help
This option adds branch wrpcAuxDiag to the SNMP
config SNMP_HW_TYPE
depends on SNMP
default "spec"
......@@ -183,6 +191,13 @@ config FLASH_INIT
default y if EMBEDDED_NODE
default n
config AUX_DIAG
default n
boolean "Add support for auxiliary diagnostics registers"
help
This option adds support for read/write of aux diag registers and
the diag command.
#
# This is a set of configuration options that should not be changed by
# normal users. If the "developer" menu is used, the binary is tainted.
......
......@@ -7,6 +7,7 @@
* Released according to the GNU GPL, version 2 or any later version.
*/
#include "syscon.h"
#include <errno.h>
struct s_i2c_if i2c_if[2] = {
{SYSC_GPSR_FMC_SCL, SYSC_GPSR_FMC_SDA},
......@@ -43,3 +44,63 @@ void timer_delay(uint32_t tics)
while (time_before(timer_get_tics(), t_end))
;
}
static int diag_rw_words, diag_ro_words;
/****************************
* AUX Diagnostics
***************************/
void diag_read_info(uint32_t *id, uint32_t *ver, uint32_t *nrw, uint32_t *nro)
{
diag_rw_words = SYSC_DIAG_NW_RW_R(syscon->DIAG_NW);
diag_ro_words = SYSC_DIAG_NW_RO_R(syscon->DIAG_NW);
if (id)
*id = SYSC_DIAG_INFO_ID_R(syscon->DIAG_INFO);
if (ver)
*ver = SYSC_DIAG_INFO_VER_R(syscon->DIAG_INFO);
if (nrw)
*nrw = diag_rw_words;
if (nro)
*nro = diag_ro_words;
}
int diag_read_word(uint32_t adr, int bank, uint32_t *val)
{
if (!val)
return -EINVAL;
if (diag_rw_words == 0) {
pp_printf("fetching diag_rw_words\n");
diag_rw_words = SYSC_DIAG_NW_RW_R(syscon->DIAG_NW);
}
if (diag_ro_words == 0) {
pp_printf("fetching diag_ro_words\n");
diag_ro_words = SYSC_DIAG_NW_RO_R(syscon->DIAG_NW);
}
if ((bank == DIAG_RW_BANK && adr >= diag_rw_words) ||
(bank == DIAG_RO_BANK && adr >= diag_ro_words)) {
*val = 0;
return -EINVAL;
}
if (bank == DIAG_RO_BANK)
adr += diag_rw_words;
syscon->DIAG_CR = SYSC_DIAG_CR_ADR_W(adr);
*val = syscon->DIAG_DAT;
return 0;
}
int diag_write_word(uint32_t adr, uint32_t val)
{
if (adr >= diag_rw_words)
return -EINVAL;
syscon->DIAG_DAT = val;
syscon->DIAG_CR = SYSC_DIAG_CR_RW | SYSC_DIAG_CR_ADR_W(adr);
return 0;
}
......@@ -3,7 +3,7 @@
* File : wrc_syscon_regs.h
* Author : auto-generated by wbgen2 from wrc_syscon_wb.wb
* Created : Wed Sep 25 14:35:39 2013
* Created : Mon Jul 11 14:59:51 2016
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_syscon_wb.wb
......@@ -135,6 +135,47 @@
#define SYSC_TCR_ENABLE WBGEN2_GEN_MASK(31, 1)
/* definitions for register: Timer Counter Value Register */
/* definitions for register: User Diag: version register */
/* definitions for field: Ver in reg: User Diag: version register */
#define SYSC_DIAG_INFO_VER_MASK WBGEN2_GEN_MASK(0, 16)
#define SYSC_DIAG_INFO_VER_SHIFT 0
#define SYSC_DIAG_INFO_VER_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define SYSC_DIAG_INFO_VER_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: Id in reg: User Diag: version register */
#define SYSC_DIAG_INFO_ID_MASK WBGEN2_GEN_MASK(16, 16)
#define SYSC_DIAG_INFO_ID_SHIFT 16
#define SYSC_DIAG_INFO_ID_W(value) WBGEN2_GEN_WRITE(value, 16, 16)
#define SYSC_DIAG_INFO_ID_R(reg) WBGEN2_GEN_READ(reg, 16, 16)
/* definitions for register: User Diag: number of words */
/* definitions for field: Read/write words in reg: User Diag: number of words */
#define SYSC_DIAG_NW_RW_MASK WBGEN2_GEN_MASK(0, 16)
#define SYSC_DIAG_NW_RW_SHIFT 0
#define SYSC_DIAG_NW_RW_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define SYSC_DIAG_NW_RW_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: Read-only words in reg: User Diag: number of words */
#define SYSC_DIAG_NW_RO_MASK WBGEN2_GEN_MASK(16, 16)
#define SYSC_DIAG_NW_RO_SHIFT 16
#define SYSC_DIAG_NW_RO_W(value) WBGEN2_GEN_WRITE(value, 16, 16)
#define SYSC_DIAG_NW_RO_R(reg) WBGEN2_GEN_READ(reg, 16, 16)
/* definitions for register: User Diag: Control Register */
/* definitions for field: Address in reg: User Diag: Control Register */
#define SYSC_DIAG_CR_ADR_MASK WBGEN2_GEN_MASK(0, 16)
#define SYSC_DIAG_CR_ADR_SHIFT 0
#define SYSC_DIAG_CR_ADR_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define SYSC_DIAG_CR_ADR_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: R/W in reg: User Diag: Control Register */
#define SYSC_DIAG_CR_RW WBGEN2_GEN_MASK(31, 1)
/* definitions for register: User Diag: data to read/write */
/* [0x0]: REG Syscon reset register */
#define SYSC_REG_RSTR 0x00000000
/* [0x4]: REG GPIO Set/Readback Register */
......@@ -147,4 +188,12 @@
#define SYSC_REG_TCR 0x00000010
/* [0x14]: REG Timer Counter Value Register */
#define SYSC_REG_TVR 0x00000014
/* [0x18]: REG User Diag: version register */
#define SYSC_REG_DIAG_INFO 0x00000018
/* [0x1c]: REG User Diag: number of words */
#define SYSC_REG_DIAG_NW 0x0000001c
/* [0x20]: REG User Diag: Control Register */
#define SYSC_REG_DIAG_CR 0x00000020
/* [0x24]: REG User Diag: data to read/write */
#define SYSC_REG_DIAG_DAT 0x00000024
#endif
......@@ -51,6 +51,10 @@ struct SYSCON_WB {
uint32_t HWFR; /*Hardware Feature Register */
uint32_t TCR; /*Timer Control Register */
uint32_t TVR; /*Timer Counter Value Register */
uint32_t DIAG_INFO;
uint32_t DIAG_NW;
uint32_t DIAG_CR;
uint32_t DIAG_DAT;
};
/*GPIO pins*/
......@@ -101,5 +105,11 @@ static inline int sysc_get_memsize(void)
return (SYSC_HWFR_MEMSIZE_R(syscon->HWFR) + 1) * 16;
}
#define DIAG_RW_BANK 0
#define DIAG_RO_BANK 1
void diag_read_info(uint32_t *id, uint32_t *ver, uint32_t *nrw, uint32_t *nro);
int diag_read_word(uint32_t adr, int bank, uint32_t *val);
int diag_write_word(uint32_t adr, uint32_t val);
#endif /* CONFIG_WR_NODE */
#endif
WR-WRPC-AUX-DIAG-MIB DEFINITIONS ::= BEGIN
-- Template for Aux Registers used by WRPC
-- Based on the WR-WRPC-MIB
-- Adam Wujek, BE-CO-HT, CERN
-- IMPORTS: Include definitions from other mibs here
IMPORTS
OBJECT-TYPE, Unsigned32, MODULE-IDENTITY FROM SNMPv2-SMI
wrWrpcMIB FROM WR-WRPC-MIB;
wrpcAuxDiag MODULE-IDENTITY
LAST-UPDATED "201607151000Z"
ORGANIZATION "CERN"
CONTACT-INFO "postal: BE-CO-HT, CERN, Geneva
email: ht-drivers@cern.ch
"
DESCRIPTION "Template of MIB for White Rabbit WRPC aux registers
"
REVISION "201607151000Z"
DESCRIPTION
"First revision."
::= { wrWrpcMIB 2 }
-- put your assigned ID number in the line below
wrpcAuxDiagId1 OBJECT IDENTIFIER ::= { wrpcAuxDiag 1 }
-- put the version number in the line below
wrpcAuxDiagVersion101 OBJECT IDENTIFIER ::= { wrpcAuxDiagId1 1 }
-- ****************************************************************************
wrpcAuxDiag101RoTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrpcAuxDiag101RoEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Table with read only registers"
::= { wrpcAuxDiagVersion101 1 }
wrpcAuxDiag101RoEntry OBJECT-TYPE
SYNTAX WrpcAuxDiag101RoEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry for read only registers"
INDEX { wrpcAuxDiag101RoIndex }
::= { wrpcAuxDiag101RoTable 1 }
WrpcAuxDiag101RoEntry ::=
SEQUENCE {
wrpcAuxDiag101RoIndex Unsigned32,
wrpcAuxDiag101RoRegCount Unsigned32,
wrpcAuxDiag101RoReg1 Unsigned32,
wrpcAuxDiag101RoReg2 Unsigned32
}
wrpcAuxDiag101RoIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrpcAuxDiag101RoTable"
::= { wrpcAuxDiag101RoEntry 1 }
wrpcAuxDiag101RoRegCount OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of registers available in the wrpcAuxDiag101RoTable"
::= { wrpcAuxDiag101RoEntry 2 }
wrpcAuxDiag101RoReg1 OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"First read-only register"
::= { wrpcAuxDiag101RoEntry 3 }
wrpcAuxDiag101RoReg2 OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Second read-only register"
::= { wrpcAuxDiag101RoEntry 4 }
-- ****************************************************************************
wrpcAuxDiag101RwTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrpcAuxDiag101RwEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Table with read-write registers"
::= { wrpcAuxDiagVersion101 2 }
wrpcAuxDiag101RwEntry OBJECT-TYPE
SYNTAX WrpcAuxDiag101RwEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry for read-write registers"
INDEX { wrpcAuxDiag101RwIndex }
::= { wrpcAuxDiag101RwTable 1 }
WrpcAuxDiag101RwEntry ::=
SEQUENCE {
wrpcAuxDiag101RwIndex Unsigned32,
wrpcAuxDiag101RwRegCount Unsigned32,
wrpcAuxDiag101RwReg1 Unsigned32,
wrpcAuxDiag101RwReg2 Unsigned32
}
wrpcAuxDiag101RwIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrpcAuxDiag101RwTable"
::= { wrpcAuxDiag101RwEntry 1 }
wrpcAuxDiag101RwRegCount OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of registers available in the wrpcAuxDiag101RwTable"
::= { wrpcAuxDiag101RwEntry 2 }
wrpcAuxDiag101RwReg1 OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"First read-write register"
::= { wrpcAuxDiag101RwEntry 3 }
wrpcAuxDiag101RwReg2 OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Second read-write register"
::= { wrpcAuxDiag101RwEntry 4 }
-- ****************************************************************************
END
......@@ -37,7 +37,7 @@ cern OBJECT IDENTIFIER ::= { enterprises 96 }
-- Define typical mib nodes
-- we'll prefix everything in this mib with wrpc
wrpcCore OBJECT IDENTIFIER ::= { wrWrpcMIB 1 }
--x wrpcCustom OBJECT IDENTIFIER ::= { wrWrpcMIB 2 }
--wrpcAuxDiag OBJECT IDENTIFIER ::= { wrWrpcMIB 2 }
-- ****************************************************************************
wrpcVersionGroup OBJECT IDENTIFIER ::= { wrpcCore 1 }
......
......@@ -74,6 +74,12 @@
#define SNMP_SET_FUNCTION(X) .set = NULL
#endif
#ifdef CONFIG_SNMP_AUX_DIAG
#define SNMP_AUX_DIAG_ENABLED 1
#else
#define SNMP_AUX_DIAG_ENABLED 0
#endif
#define MASK_SET 0x1
#define MASK_GET 0x2
#define MASK_GET_NEXT 0x4
......@@ -133,6 +139,22 @@
/* Limit the OID length */
#define MAX_OID_LEN 40
/* Index of a byte in the OID corresponding to the ID of the aux diag
* registers */
#define AUX_DIAG_ID_INDEX 8
/* Index of a byte in the OID corresponding to the version of the aux diag
* registers */
#define AUX_DIAG_VER_INDEX 9
#define AUX_DIAG_RO (void *) DIAG_RO_BANK
#define AUX_DIAG_RW (void *) DIAG_RW_BANK
/* add the AUX_DIAG_DATA_COL_SHIFT to the aux diag register's index to get
* column in the table. Columns are following:
* col 1 -- index
* col 2 -- number of registers
* col 3 -- first aux diag register
*/
#define AUX_DIAG_DATA_COL_SHIFT 3
#define OID_FIELD_STRUCT(_oid, _getf, _setf, _asn, _type, _pointer, _field) { \
.oid_match = _oid, \
......@@ -193,6 +215,10 @@ struct snmp_oid_limb {
static struct s_sfpinfo snmp_ptp_config;
static int ptp_config_apply_status;
static int ptp_restart_status;
/* Keep the number of aux diag registers available in the FPGA bitstream */
static uint32_t aux_diag_reg_ro_num;
static uint32_t aux_diag_reg_rw_num;
extern struct pp_instance ppi_static;
static struct wr_servo_state *wr_s_state;
......@@ -218,6 +244,8 @@ static int func_group(uint8_t *buf, uint8_t in_oid_limb_matched_len,
struct snmp_oid *obj, uint8_t flags);
static int func_table(uint8_t *buf, uint8_t in_oid_limb_matched_len,
struct snmp_oid *obj, uint8_t flags);
static int func_aux_diag(uint8_t *buf, uint8_t in_oid_limb_matched_len,
struct snmp_oid *obj, uint8_t flags);
static int get_value(uint8_t *buf, uint8_t asn, void *p);
static int get_pp(uint8_t *buf, struct snmp_oid *obj);
......@@ -229,11 +257,14 @@ static int get_servo(uint8_t *buf, struct snmp_oid *obj);
static int get_port(uint8_t *buf, struct snmp_oid *obj);
static int get_temp(uint8_t *buf, struct snmp_oid *obj);
static int get_sfp(uint8_t *buf, struct snmp_oid *obj);
static int get_aux_diag(uint8_t *buf, struct snmp_oid *obj);
static int set_value(uint8_t *set_buff, struct snmp_oid *obj, void *p);
static int set_pp(uint8_t *buf, struct snmp_oid *obj);
static int set_p(uint8_t *buf, struct snmp_oid *obj);
static int set_ptp_restart(uint8_t *buf, struct snmp_oid *obj);
static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj);
static int set_aux_diag(uint8_t *buf, struct snmp_oid *obj);
static int data_aux_diag(uint8_t *buf, struct snmp_oid *obj, int mode);
static void print_oid_verbose(uint8_t *oid, int len);
static void snmp_fix_size(uint8_t *buf, int size);
......@@ -248,6 +279,10 @@ static uint8_t oid_wrpcPtpConfigGroup[] = {0x2B,6,1,4,1,96,101,1,6};
static uint8_t oid_wrpcPortGroup[] = {0x2B,6,1,4,1,96,101,1,7};
/* Include wrpcSfpEntry into OID */
static uint8_t oid_wrpcSfpTable[] = {0x2B,6,1,4,1,96,101,1,8,1};
/* In below OIDs zeros will be replaced in the snmp_init function by values
* read from FPA */
static uint8_t oid_wrpcAuxRoTable[] = {0x2B,6,1,4,1,96,101,2,0,0,1,1};
static uint8_t oid_wrpcAuxRwTable[] = {0x2B,6,1,4,1,96,101,2,0,0,2,1};
/* wrpcVersionGroup */
static uint8_t oid_wrpcVersionHwType[] = {1,0};
......@@ -408,6 +443,17 @@ static struct snmp_oid oid_array_wrpcSfpTable[] = {
{ 0, }
};
static struct snmp_oid oid_array_wrpcAuxRoTable[] = {
OID_FIELD_VAR(NULL, get_aux_diag, NO_SET, ASN_UNSIGNED, AUX_DIAG_RO),
{ 0, }
};
static struct snmp_oid oid_array_wrpcAuxRwTable[] = {
OID_FIELD_VAR(NULL, get_aux_diag, set_aux_diag, ASN_UNSIGNED, AUX_DIAG_RW),
{ 0, }
};
/* Array of groups and tables */
static struct snmp_oid_limb oid_limb_array[] = {
OID_LIMB_FIELD(oid_wrpcVersionGroup, func_group, oid_array_wrpcVersionGroup),
......@@ -418,17 +464,34 @@ static struct snmp_oid_limb oid_limb_array[] = {
OID_LIMB_FIELD(oid_wrpcPtpConfigGroup, func_group, oid_array_wrpcPtpConfigGroup),
OID_LIMB_FIELD(oid_wrpcPortGroup, func_group, oid_array_wrpcPortGroup),
OID_LIMB_FIELD(oid_wrpcSfpTable, func_table, oid_array_wrpcSfpTable),
#ifdef CONFIG_SNMP_AUX_DIAG
OID_LIMB_FIELD(oid_wrpcAuxRoTable, func_aux_diag, oid_array_wrpcAuxRoTable),
OID_LIMB_FIELD(oid_wrpcAuxRwTable, func_aux_diag, oid_array_wrpcAuxRwTable),
#endif
{ 0, }
};
static void snmp_init(void)
{
uint32_t aux_diag_id;
uint32_t aux_diag_ver;
/* Use UDP engine activated by function arguments */
snmp_socket = ptpd_netif_create_socket(&__static_snmp_socket, NULL,
PTPD_SOCK_UDP, 161 /* snmp */);
/* TODO: check if pointer(s) is initialized already */
wr_s_state =
&((struct wr_data *)ppi_static.ext_data)->servo_state;
if (SNMP_AUX_DIAG_ENABLED) {
/* Fix ID and version of aux diag registers by values read from FPGA */
diag_read_info(&aux_diag_id, &aux_diag_ver, &aux_diag_reg_rw_num,
&aux_diag_reg_ro_num);
snmp_verbose("aux_diag_id %d, aux_diag_ver %d\n",
aux_diag_id, aux_diag_ver);
oid_wrpcAuxRoTable[AUX_DIAG_ID_INDEX] = aux_diag_id;
oid_wrpcAuxRoTable[AUX_DIAG_VER_INDEX] = aux_diag_ver;
oid_wrpcAuxRwTable[AUX_DIAG_ID_INDEX] = aux_diag_id;
oid_wrpcAuxRwTable[AUX_DIAG_VER_INDEX] = aux_diag_ver;
}
}
static int func_group(uint8_t *buf, uint8_t in_oid_limb_matched_len,
......@@ -542,7 +605,6 @@ static int func_group(uint8_t *buf, uint8_t in_oid_limb_matched_len,
return 0;
}
static int func_table(uint8_t *buf, uint8_t in_oid_limb_matched_len,
struct snmp_oid *twigs_array, uint8_t flags)
{
......@@ -683,6 +745,118 @@ static int func_table(uint8_t *buf, uint8_t in_oid_limb_matched_len,
return return_len;
}
static int func_aux_diag(uint8_t *buf, uint8_t in_oid_limb_matched_len,
struct snmp_oid *twigs_array, uint8_t flags)
{
int oid_twig_len = buf[0] - in_oid_limb_matched_len;
uint8_t *in_oid_limb_end = &buf[1 + in_oid_limb_matched_len];
uint8_t oid_twig_matching_len;
struct snmp_oid *oid;
struct snmp_oid leaf_obj;
int return_first = 0;
int i;
int get_next_increase_oid = 0;
int snmp_get_next = 0;
int return_len;
int table_size = 2; /* two */
oid = twigs_array;
if (flags & RETURN_FIRST)
return_first = 1;
snmp_verbose("%s: table wants coordinates:", __func__);
for (i = 0; i < oid_twig_len; i++)
snmp_verbose(" %d", in_oid_limb_end[i]);
snmp_verbose("\n");
if (flags & MASK_GET_NEXT) {
/* By default increase OID for SNMP_GET_NEXT */
get_next_increase_oid = 1;
snmp_get_next = 1;
}
/* Fill packet with valid OID, when OID is shorter than it
* should be */
if (return_first || (snmp_get_next && oid_twig_len < table_size)) {
get_next_increase_oid = 0;
in_oid_limb_end[TABLE_COL] = TABLE_FIRST_COL;
in_oid_limb_end[TABLE_ROW] = TABLE_FIRST_ROW;
oid_twig_len = table_size;
}
/* Decide what is shorter the rest of the OID, or the
* matching part */
oid_twig_matching_len = min(oid_twig_len, table_size);
/* For get and set twig size has to be exact */
if (!snmp_get_next && (oid_twig_len != table_size)) {
snmp_verbose("%s: wrong twig len %d (expected %d)",
__func__, oid_twig_len, table_size);
return 0;
}
/* For get next requested twig part of oid is longer than table size */
if (snmp_get_next && (oid_twig_len > table_size)) {
get_next_increase_oid = 1;
}
/* Copy OID information to the leaf_obj */
leaf_obj.oid_len = table_size;
leaf_obj.oid_match = in_oid_limb_end;
leaf_obj.asn = oid->asn;
leaf_obj.p = oid->p;
if (get_next_increase_oid)
in_oid_limb_end[TABLE_ROW]++;
if (flags & MASK_SET) {
if (!oid->set) {
/* No set function */
snmp_verbose("%s: no set function!", __func__);
return -SNMP_ERR_READONLY;
}
/* Set the value for the leaf */
return_len = oid->set(&in_oid_limb_end[table_size], &leaf_obj);
if (return_len < 0) {
snmp_verbose("%s: SET error %d\n", __func__,
return_len);
return return_len;
}
} else {
/* Get the value for the leaf */
return_len = oid->get(&in_oid_limb_end[table_size], &leaf_obj);
}
if (return_len == 0 && get_next_increase_oid) {
in_oid_limb_end[TABLE_COL]++;
in_oid_limb_end[TABLE_ROW] = TABLE_FIRST_ROW;
/* Get the value for the leaf in the next column, first row */
return_len = oid->get(&in_oid_limb_end[table_size],
&leaf_obj);
/* If no value is available for first row in next column,
* it means previous column was the last one */
if (return_len == 0)
return 0;
}
/* Leaf not found */
if (return_len == 0)
return 0;
if (return_len < 0) /* If error */ {
snmp_verbose("%s: GET error %d\n",
__func__, return_len);
return return_len;
}
return_len += table_size;
if (snmp_get_next || return_first) {
buf[0] = table_size;
}
return return_len;
}
static int get_servo(uint8_t *buf, struct snmp_oid *obj)
{
uint64_t tmp_uint64;
......@@ -928,6 +1102,87 @@ static int get_sfp(uint8_t *buf, struct snmp_oid *obj)
return 0;
}
static int set_aux_diag(uint8_t *buf, struct snmp_oid *obj)
{
return data_aux_diag(buf, obj, SNMP_SET);
}
static int get_aux_diag(uint8_t *buf, struct snmp_oid *obj)
{
return data_aux_diag(buf, obj, SNMP_GET);
}
static int data_aux_diag(uint8_t *buf, struct snmp_oid *obj, int mode)
{
int row;
int col;
int bank; /* RO or RW */
uint32_t val;
int regs_available;
int ret;
bank = (int) obj->p;
snmp_verbose("%s: bank %d\n", __func__, obj->p);
if ((void *)bank == AUX_DIAG_RO) {
regs_available = aux_diag_reg_ro_num;
snmp_verbose("%s: RO bank\n", __func__);
} else if ((void *)bank == AUX_DIAG_RW) {
regs_available = aux_diag_reg_rw_num;
snmp_verbose("%s: RW bank\n", __func__);
} else {
snmp_verbose("%s: wrong AUX bank %d\n", __func__, bank);
return -SNMP_ERR_BADVALUE;
}
row = obj->oid_match[1];
col = obj->oid_match[0];
snmp_verbose("%s: row%d, col%d\n", __func__, row, col);
if (row != 1) {
/* So far we support only one row in this table. */
snmp_verbose("%s: wrong row %d, should be 1\n", __func__, row);
return 0;
}
/* Ignore cols < 2 */
if ((col < 2) || (col >= regs_available + AUX_DIAG_DATA_COL_SHIFT)) {
snmp_verbose("%s: wrong col %d, max %d\n", __func__,
col, regs_available + AUX_DIAG_DATA_COL_SHIFT);
return 0;
}
if (col == 2) {
/* Col 2 is a register containing the number of registers
* available in this bank */
if (mode == SNMP_SET) {
/* Register with the number of registers is read
* only */
return -SNMP_ERR_READONLY;
}
val = regs_available;
} else {
if (mode == SNMP_SET) {
/* write */
ret = set_value(buf, obj, &val);
if (ret <= 0) {
/* Error while checking SET value,
* like wrong ASN */
return ret;
}
ret = diag_write_word(col - AUX_DIAG_DATA_COL_SHIFT,
val);
if (ret < 0) {
/* Something went wrong during the write */
return -SNMP_ERR_GENERR;
}
}
/* Read a word, even if we just set it */
ret = diag_read_word(col - AUX_DIAG_DATA_COL_SHIFT, bank, &val);
if (ret < 0) {
/* Something went wrong during the read */
return -SNMP_ERR_GENERR;
}
}
return get_value(buf, obj->asn, &val);
}
static int set_value(uint8_t *set_buff, struct snmp_oid *obj, void *p)
{
......@@ -1250,6 +1505,10 @@ static int snmp_respond(uint8_t *buf)
set_pp(NULL, NULL);
set_ptp_config(NULL, NULL);
set_ptp_restart(NULL, NULL);
set_aux_diag(NULL, NULL);
func_aux_diag(NULL, 0, NULL, 0);
oid_array_wrpcAuxRwTable[0].oid_len = 0;
oid_array_wrpcAuxRoTable[0].oid_len = 0;
}
for (a_i = 0, h_i = 0; a_i < sizeof(match_array); a_i++, h_i++) {
......
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 CERN (www.cern.ch)
* Author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include "shell.h"
#include <wrc.h>
#include <syscon.h>
#include <string.h>
#include <errno.h>
static int cmd_diag(const char *args[])
{
uint32_t id, ver, nrw, nro;
uint32_t addr, val;
int ret = 0;
if (!args[0]) {
diag_read_info(&id, &ver, &nrw, &nro);
pp_printf("Aux diagnostics info:\n");
pp_printf("id: %d.%d, r/w words: %d, r/o words: %d\n", id, ver,
nrw, nro);
return 0;
}
if (!strcasecmp(args[0], "ro") && args[1]) {
addr = atoi(args[1]);
ret = diag_read_word(addr, DIAG_RO_BANK, &val);
if (!ret)
pp_printf("Word %d is 0x%08x\n", addr, val);
return ret;
}
if (!strcasecmp(args[0], "rw") && args[1]) {
addr = atoi(args[1]);
ret = diag_read_word(addr, DIAG_RW_BANK, &val);
if (!ret)
pp_printf("Word %d is 0x%08x\n", addr, val);
return ret;
}
if (!strcasecmp(args[0], "w") && args[1] && args[2]) {
addr = atoi(args[1]);
val = atoi(args[2]);
ret = diag_write_word(addr, val);
if (!ret)
pp_printf("Value 0x%08x written to the word %d\n",
val, addr);
return ret;
}
return -EINVAL;
}
DEFINE_WRC_COMMAND(diag) = {
.name = "diag",
.exec = cmd_diag,
};
......@@ -18,6 +18,7 @@ obj-$(CONFIG_EMBEDDED_NODE) += \
shell/cmd_sdb.o \
shell/cmd_ptrack.o \
obj-$(CONFIG_IP) += shell/cmd_ip.o
obj-$(CONFIG_PPSI) += shell/cmd_verbose.o
obj-$(CONFIG_CMD_CONFIG) += shell/cmd_config.o
......@@ -25,3 +26,4 @@ obj-$(CONFIG_CMD_SLEEP) += shell/cmd_sleep.o
obj-$(CONFIG_CMD_LL) += shell/cmd_ll.o
obj-$(CONFIG_FLASH_INIT) += shell/cmd_init.o
obj-$(CONFIG_VLAN) += shell/cmd_vlan.o
obj-$(CONFIG_AUX_DIAG) += shell/cmd_diag.o
......@@ -14,3 +14,7 @@ bats/libexec/bats:
test: prepare
bats/libexec/bats snmp_tests_*.bats
aux_diag: prepare
bats/libexec/bats snmp_test_aux_diag_*.bats
load snmp_test_config
load snmp_test_helpers
@test "Get index of a table 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1, check if correct returned" {
helper_snmpget_oidfound 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get number of aux RO registers of a table 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1, check if correct returned" {
helper_snmpget_oidfound 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1.2, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1.2
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1.2.1, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1.2.1
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1.2.1.1, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1.2.1.1
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1.2.1.1.3, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1.2.1.1.3
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1.2.1.1.3.0, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1.2.1.1.3.0
}
@test "Get number of aux RO registers of a table 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1, check if correct returned" {
helper_snmpget_oidfound 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1.2.1.1.3.2, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1.2.1.1.3.2
}
@test "Get invalid OID 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1.1, check if correct returned" {
helper_snmpget_oidnotfound 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1.1
}
# get next
@test "Get next object after 1.3.6.1.4.1.96.101.2, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.2, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1.2 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1, check if other returned" {
result="$(snmpgetnext $SNMP_OPTIONS $TARGET_IP 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1 | grep 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1 | wc -l)"
[ "$result" -eq 0 ]
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1 1.3.6.1.4.1.96.101.2.1.2.1.1.4.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.2.0, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1.2.0 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.2.0.1, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1.2.0.1 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1.0, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1.0 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1
}
@test "Get next object after 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1.1, check if correct returned" {
helper_snmpgetnext 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1.1 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1
}
# sets
@test "Set read-only object 1.3.6.1.4.1.96.101.2.1.2.1.1.1.1" {
helper_snmpset_failed_u 1.3.6.1.4.1.96.101.2.1.2.1.1.1.1 99
}
@test "Set read-only object 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1" {
helper_snmpset_failed_u 1.3.6.1.4.1.96.101.2.1.2.1.1.2.1 99
}
@test "Set read-only object 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1" {
helper_snmpset_failed_u 1.3.6.1.4.1.96.101.2.1.2.1.1.3.1 99
}
@test "Set read-only object 1.3.6.1.4.1.96.101.2.1.2.2.1.1.1" {
helper_snmpset_failed_u 1.3.6.1.4.1.96.101.2.1.2.2.1.1.1 99
}
@test "Set read-only object 1.3.6.1.4.1.96.101.2.1.2.2.1.2.1" {
helper_snmpset_failed_u 1.3.6.1.4.1.96.101.2.1.2.2.1.2.1 99
}
@test "Set read-write object 1.3.6.1.4.1.96.101.2.1.2.2.1.3.1, check if correct set" {
helper_snmpset_u 1.3.6.1.4.1.96.101.2.1.2.2.1.3.1 99
}
@test "Get read-write object 1.3.6.1.4.1.96.101.2.1.2.2.1.3.1" {
helper_snmpget 1.3.6.1.4.1.96.101.2.1.2.2.1.3.1 99
}
......@@ -4,12 +4,12 @@ helper_snmpget() {
}
helper_snmpget_oidnotfound() {
run snmpget $SNMP_OPTIONS $TARGET_IP $1
run snmpget $SNMP_OPTIONS_NO_M $TARGET_IP $1
[ "$status" -eq 2 ]
}
helper_snmpget_oidfound() {
result="$(snmpget $SNMP_OPTIONS $TARGET_IP $1 | grep "$1" | wc -l)"
result="$(snmpget $SNMP_OPTIONS_NO_M $TARGET_IP $1 | grep "$1" | wc -l)"
[ "$result" -eq 1 ]
}
......@@ -24,6 +24,17 @@ helper_snmpset() {
[ "$result" -eq 1 ]
}
helper_snmpset_u() {
result="$(snmpset $SNMP_OPTIONS $TARGET_IP $1 u "$2" | grep "$2" | wc -l)"
[ "$result" -eq 1 ]
}
helper_snmpset_failed_u() {
run snmpset $SNMP_OPTIONS $TARGET_IP $1 u "$2"
[ "$status" -eq 2 ]
}
helper_erase_sfp_database() {
result="$(snmpset $SNMP_OPTIONS $TARGET_IP wrpcPtpConfigApply.0 = eraseFlash | grep applySuccessful | wc -l)"
[ "$result" -eq 1 ]
......
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