Commit fb9f2499 authored by Adam Wujek's avatar Adam Wujek 💬

[Feature: 1055] userspace/tools: add learning command to rtu_stat

Add "learning" command to enable/disable learning of RTU to the rtu_stat
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent a8c03bba
......@@ -68,6 +68,15 @@ int rtudexp_remove_entry(const char *mac, int port_mask, int type)
return (ret < 0) ? ret : val;
}
int rtudexp_learning_process(int operation, int enable, int port_mask)
{
int val, ret;
ret = minipc_call(rtud_ch, MINIPC_TIMEOUT,
&rtud_export_learning_process, &val, operation,
enable, port_mask);
return (ret < 0) ? ret : val;
}
int rtudexp_vlan_entry(int vid, int fid, const char *ch_mask, int drop,
int prio, int has_prio, int prio_override)
{
......@@ -135,6 +144,12 @@ void show_help(char *prgname)
" MAC address and multiple ports with\n"
" an optional type (default %d-static)\n",
RTU_ENTRY_TYPE_STATIC);
fprintf(stderr, " learning: Read status of learning process in RTU\n");
fprintf(stderr, " learning <enable|disable> [<port>]: Enable/disable learning process in RTU\n"
" for optional port, otherwise for all\n"
" ports\n");
fprintf(stderr, " learning <enable|disable> mask <port_mask>: Enable/disable learning process\n"
" in RTU for ports given as a mask\n");
fprintf(stderr, " vlan <vid> <fid> <port_mask> [<drop>, <prio>, <has_prio>, <prio_override>]:\n"
" Add VLAN entry with vid, fid, mask and drop flag;\n"
" write mask=0x0 and drop=1 to remove the VLAN\n");
......@@ -363,6 +378,8 @@ int main(int argc, char **argv)
int n_wait = 0;
int ret;
int type;
int enable;
uint32_t mask;
nports = get_nports_from_hal();
......@@ -537,6 +554,107 @@ int main(int argc, char **argv)
exit(1);
}
isok = 1;
/* ****************** learning <enable|disable> mask <port_mask> *********** */
} else if (argc >= 5
&& strcmp(argv[1], "learning") == 0
&& strcmp(argv[3], "mask") == 0) {
if (!strcmp(argv[2], "enable"))
enable = RTU_LEARNING_ENABLE;
else if (!strcmp(argv[2], "disable"))
enable = RTU_LEARNING_DISABLE;
else {
fprintf(stderr, "rtu_stat: expected \"enable\""
" or \"disable\"\n");
exit(1);
}
mask = 0;
if (!strcmp(argv[4], "ALL")
|| !strcmp(argv[4], "all")) {
mask = (1 << (nports + 1)) - 1;
} else {
i = strtol(argv[4], NULL, 0);
/* interface number 1..18 */
if (0 < i && i <= ((1 << nports) - 1)) {
mask = i;
}
}
/* interface number 1..18, CPU is 19 */
if (mask == 0) {
printf("Wrong port mask 0x%s\n", argv[4]);
exit(1);
}
ret = rtudexp_learning_process(
RTU_SET_LEARNING, /* oper */
enable, /* enable */
mask /* port_mask */
);
if (ret > 0)
printf("Update of learning state change successful\n");
if (ret < 0) {
printf("Could not change learning state 0x%x\n", ret);
exit(1);
}
/* Don't do anything more */
return 0;
/* ****************** learning <enable|disable> [<port>] ******************* */
} else if (argc >= 3
&& strcmp(argv[1], "learning") == 0) {
if (!strcmp(argv[2], "enable"))
enable = RTU_LEARNING_ENABLE;
else if (!strcmp(argv[2], "disable"))
enable = RTU_LEARNING_DISABLE;
else {
fprintf(stderr, "rtu_stat: expected \"enable\""
" or \"disable\"\n");
exit(1);
}
if (argc >= 4) { /* port defined */
i = strtol(argv[3], NULL, 0);
/* interface number 1..18*/
if (1 > i || i > nports) { /* 18 ports */
printf("Wrong port %s\n", argv[3]);
exit(1);
}
mask = 1 << (i - 1);
} else { /* port undefined, use as all */
mask = (1 << (nports)) - 1;
}
ret = rtudexp_learning_process(
RTU_SET_LEARNING, /* oper */
enable, /* enable */
mask /* port_mask */
);
if (ret > 0)
printf("Update of learning state change successful\n");
if (ret < 0) {
printf("Could not change learning state 0x%x\n", ret);
exit(1);
}
/* Don't do anything more */
return 0;
/* ****************** learning ********************************************* */
} else if (argc >= 2
&& strcmp(argv[1], "learning") == 0) {
ret = rtudexp_learning_process(
RTU_GET_LEARNING, /* oper */
0, /* enable */
(1 << nports) - 1 /* port_mask */
);
if (ret < 0) {
printf("Could not read learning state 0x%x\n", ret);
exit(1);
}
printf("-------------\n");
printf("Port | Learning\n");
printf("-------------\n");
for (i = 0; i < nports; i++) {
printf(" %2d %s\n", i + 1,
(ret & 1) ? "enabled" : "disabled");
ret >>= 1;
}
/* Don't do anything more */
return 0;
/* ****************** vlan <vid> <fid> <port_mask>
* [<drop>, <prio>, <has_prio>, <prio_override>] *** */
} else if (argc >= 5
......
......@@ -531,6 +531,19 @@ int rtu_learn_enable_on_port(int port, int flag)
return 0;
}
/**
* \brief Gets the LEARN_EN flag on indicated port.
* @param port port number (0 to 9)
* @return flag status
*/
int rtu_learn_read_on_port(int port)
{
if ((port < MIN_PORT) || (port > MAX_PORT))
return -EINVAL;
return read_pcr(port) & RTU_PCR_LEARN_EN ? 1 : 0;
}
/**
* \brief Sets the PASS_BPDU flag on indicated port.
* @param port port number (0 to 9)
......
......@@ -81,6 +81,7 @@ int rtu_unset_fixed_prio_on_port(int port)
__attribute__ ((warn_unused_result));
int rtu_learn_enable_on_port(int port, int flag)
__attribute__ ((warn_unused_result));
int rtu_learn_read_on_port(int port);
int rtu_pass_bpdu_on_port(int port, int flag)
__attribute__ ((warn_unused_result));
int rtu_pass_all_on_port(int port, int pass_all)
......
......@@ -36,6 +36,7 @@
#include "minipc.h"
#include "rtu.h"
#include "rtu_fd.h"
#include "rtu_drv.h"
#include "rtud_exports.h"
#include <libwr/mac.h>
......@@ -151,6 +152,68 @@ int rtudexp_remove_entry(const struct minipc_pd *pd, uint32_t * args, void *ret)
return *p_ret;
}
int rtudexp_learning_process(const struct minipc_pd *pd, uint32_t * args,
void *ret)
{
int oper;
int enable;
uint32_t port_mask;
int *p_ret = (int *)ret; /*force pointed to int type */
uint32_t learning_mask = 0;
int i;
int local_ret;
oper = (int)args[0];
enable = (int)args[1];
port_mask = (int)args[2];
*p_ret = 0;
pr_debug("Request for learning process state\n");
if (1 > port_mask || port_mask > 0x3ffff) { /* 18 ports */
pr_error("Wrong port mask 0x%x\n", port_mask);
*p_ret = -1;
return *p_ret;
}
switch (oper) {
case RTU_GET_LEARNING:
for (i = 0; i < 18; i++) {
if ((port_mask >> i) & 1) {
local_ret = rtu_learn_read_on_port(i);
if (local_ret < 0) {
*p_ret = local_ret;
return *p_ret;
}
learning_mask |= local_ret << i;
}
}
*p_ret = learning_mask;
pr_debug("Learning state mask 0x%x\n", learning_mask);
break;
case RTU_SET_LEARNING:
for (i = 0; i < 18; i++) {
if ((port_mask >> i) & 1) {
pr_debug("Request to change learning process "
"state for port %d (wri%d)\n",
i + 1, i + 1);
local_ret = rtu_learn_enable_on_port(i,
enable);
if (local_ret < 0) {
*p_ret = local_ret;
return *p_ret;
}
(*p_ret)++;
}
}
break;
default:
pr_error("Wrong operation for learning process %d\n", oper);
*p_ret = -1;
return *p_ret;
}
return *p_ret;
}
int rtudexp_vlan_entry(const struct minipc_pd *pd, uint32_t * args, void *ret)
{
int vid, fid, mask, drop, prio, has_prio, prio_override;
......@@ -184,6 +247,7 @@ int rtud_init_exports()
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_remove_entry, rtudexp_remove_entry);
MINIPC_EXP_FUNC(rtud_export_learning_process, rtudexp_learning_process);
MINIPC_EXP_FUNC(rtud_export_vlan_entry, rtudexp_vlan_entry);
return 0;
......
......@@ -31,6 +31,11 @@
#include <stdint.h>
#include <minipc.h>
#define RTU_LEARNING_ENABLE 1
#define RTU_LEARNING_DISABLE 0
#define RTU_SET_LEARNING 1
#define RTU_GET_LEARNING 2
/* Export of a function to set remove entry in rtu */
struct minipc_pd rtud_export_clear_entries = {
.name = "clear_entries",
......@@ -65,6 +70,20 @@ struct minipc_pd rtud_export_remove_entry = {
},
};
/* Export of a function to get status or enable/disable of learning process in
* rtu */
struct minipc_pd rtud_export_learning_process = {
.name = "learning_process",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* operation */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* enable/disable */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* port mask */
MINIPC_ARG_END,
},
};
/* Export of a function to add vlan entry in rtu */
struct minipc_pd rtud_export_vlan_entry = {
.name = "vlan_entry",
......
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