mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
netutils: Add plcatool
Add plcatool - simple tool for managing PLCA configuration in 10BASE-T1S PHYs. Signed-off-by: michal matias <mich4l.matias@gmail.com>
This commit is contained in:
parent
479d206dff
commit
a85121b168
6 changed files with 900 additions and 0 deletions
33
netutils/plcatool/CMakeLists.txt
Normal file
33
netutils/plcatool/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# ##############################################################################
|
||||
# apps/netutils/plcatool/CMakeLists.txt
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
# license agreements. See the NOTICE file distributed with this work for
|
||||
# additional information regarding copyright ownership. The ASF licenses this
|
||||
# file to you under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy of
|
||||
# the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
#
|
||||
# ##############################################################################
|
||||
|
||||
if(CONFIG_NETUTILS_PLCATOOL)
|
||||
nuttx_add_application(
|
||||
NAME
|
||||
plcatool
|
||||
STACKSIZE
|
||||
${CONFIG_DEFAULT_TASK_STACKSIZE}
|
||||
MODULE
|
||||
${CONFIG_NETUTILS_PLCATOOL}
|
||||
SRCS
|
||||
plcatool.c)
|
||||
endif()
|
||||
12
netutils/plcatool/Kconfig
Normal file
12
netutils/plcatool/Kconfig
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config NETUTILS_PLCATOOL
|
||||
bool "plcatool support"
|
||||
default n
|
||||
---help---
|
||||
Build in support for the plcatool command. This command allows configuring
|
||||
the PLCA access method in 10BASE-T1S network adapters supporting PLCA.
|
||||
Syntax of the plcatool is inspired by the corresponding syntax used by the ethtool.
|
||||
25
netutils/plcatool/Make.defs
Normal file
25
netutils/plcatool/Make.defs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
############################################################################
|
||||
# apps/netutils/plcatool/Make.defs
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifneq ($(CONFIG_NETUTILS_PLCATOOL),)
|
||||
CONFIGURED_APPS += $(APPDIR)/netutils/plcatool
|
||||
endif
|
||||
32
netutils/plcatool/Makefile
Normal file
32
netutils/plcatool/Makefile
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
############################################################################
|
||||
# apps/netutils/plcatool/Makefile
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
MAINSRC = plcatool.c
|
||||
|
||||
PROGNAME = plcatool
|
||||
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
|
||||
MODULE = $(CONFIG_NETUTILS_PLCATOOL)
|
||||
|
||||
include $(APPDIR)/Application.mk
|
||||
85
netutils/plcatool/oa_tc14.h
Normal file
85
netutils/plcatool/oa_tc14.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/****************************************************************************
|
||||
* apps/netutils/plcatool/oa_tc14.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APPS_NETUTILS_PLCATOOL_OA_TC14_H
|
||||
#define __APPS_NETUTILS_PLCATOOL_OA_TC14_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/bits.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define OA_TC14_PLCA_MMD 31
|
||||
|
||||
#define OA_TC14_IDVER_ADDR 0xCA00
|
||||
#define OA_TC14_IDVER_IDM_MASK GENMASK(15, 8)
|
||||
#define OA_TC14_IDVER_IDM_POS 8
|
||||
#define OA_TC14_IDVER_VER_MASK GENMASK(7, 0)
|
||||
#define OA_TC14_IDVER_VER_POS 0
|
||||
#define OA_TC14_IDVER_VAL 0x0A10
|
||||
|
||||
#define OA_TC14_CTRL0_ADDR 0xCA01
|
||||
#define OA_TC14_CTRL0_EN_MASK BIT(15)
|
||||
#define OA_TC14_CTRL0_EN_POS 15
|
||||
#define OA_TC14_CTRL0_RST_MASK BIT(14)
|
||||
#define OA_TC14_CTRL0_RST_POS 14
|
||||
|
||||
#define OA_TC14_CTRL1_ADDR 0xCA02
|
||||
#define OA_TC14_CTRL1_NCNT_MASK GENMASK(15, 8)
|
||||
#define OA_TC14_CTRL1_NCNT_POS 8
|
||||
#define OA_TC14_CTRL1_ID_MASK GENMASK(7, 0)
|
||||
#define OA_TC14_CTRL1_ID_POS 0
|
||||
|
||||
#define OA_TC14_STATUS_ADDR 0xCA03
|
||||
#define OA_TC14_STATUS_PST_MASK BIT(15)
|
||||
#define OA_TC14_STATUS_PST_POS 15
|
||||
|
||||
#define OA_TC14_TOTMR_ADDR 0xCA04
|
||||
#define OA_TC14_TOTMR_TOT_MASK GENMASK(7, 0)
|
||||
#define OA_TC14_TOTMR_TOT_POS 0
|
||||
|
||||
#define OA_TC14_BURST_ADDR 0xCA05
|
||||
#define OA_TC14_BURST_MAXBC_MASK GENMASK(15, 8)
|
||||
#define OA_TC14_BURST_MAXBC_POS 8
|
||||
#define OA_TC14_BURST_BTMR_MASK GENMASK(7, 0)
|
||||
#define OA_TC14_BURST_BTMR_POS 0
|
||||
|
||||
#define OA_TC14_DIAG_ADDR 0xCA06
|
||||
#define OA_TC14_DIAG_RXINTO_MASK BIT(2)
|
||||
#define OA_TC14_DIAG_RXINTO_POS 2
|
||||
#define OA_TC14_DIAG_UNEXPB_MASK BIT(1)
|
||||
#define OA_TC14_DIAG_UNEXPB_POS 1
|
||||
#define OA_TC14_DIAG_BCNBFTO_MASK BIT(0)
|
||||
#define OA_TC14_DIAG_BCNBFTO_POS 0
|
||||
|
||||
#define oa_tc14_get_field(r, fieldname) \
|
||||
(((r) & OA_TC14_##fieldname##_MASK) >> OA_TC14_##fieldname##_POS)
|
||||
|
||||
#define oa_tc14_field(val, fieldname) \
|
||||
((val << OA_TC14_##fieldname##_POS) & OA_TC14_##fieldname##_MASK)
|
||||
|
||||
#endif /* __APPS_NETUTILS_PLCATOOL_OA_TC14_H */
|
||||
713
netutils/plcatool/plcatool.c
Normal file
713
netutils/plcatool/plcatool.c
Normal file
|
|
@ -0,0 +1,713 @@
|
|||
/****************************************************************************
|
||||
* apps/netutils/plcatool/plcatool.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "oa_tc14.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ARGS_REMAIN(argc, pos) ((argc) - (pos))
|
||||
|
||||
#define PLCATOOL_CFG_SET_BIT 0x8000
|
||||
#define PLCATOOL_CFG_SET(cfg, field, val) \
|
||||
do {(cfg)->field = PLCATOOL_CFG_SET_BIT | ((val) & 0xff);} while (0)
|
||||
|
||||
#define PLCATOOL_CFG_VAL(cfg, field) ((cfg)->field & 0xff)
|
||||
|
||||
#define NODE_ID_MIN 0
|
||||
#define NODE_ID_MAX 255
|
||||
|
||||
#define NODE_CNT_MIN 1
|
||||
#define NODE_CNT_MAX 255
|
||||
|
||||
#define TO_TMR_MIN 0
|
||||
#define TO_TMR_MAX 255
|
||||
|
||||
#define BURST_CNT_MIN 0
|
||||
#define BURST_CNT_MAX 255
|
||||
|
||||
#define BURST_TMR_MIN 0
|
||||
#define BURST_TMR_MAX 255
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
enum plcatool_cmd_e
|
||||
{
|
||||
PLCA_CMD_SET,
|
||||
PLCA_CMD_GET,
|
||||
PLCA_CMD_STATUS,
|
||||
PLCA_CMD_HELP
|
||||
};
|
||||
|
||||
/* Lower 8 bits are value, the most significant bit indicates whether set */
|
||||
|
||||
struct plcatool_cfg_s
|
||||
{
|
||||
enum plcatool_cmd_e cmd;
|
||||
|
||||
FAR char *ifname;
|
||||
|
||||
uint8_t phy;
|
||||
|
||||
uint16_t enable;
|
||||
uint16_t node_cnt;
|
||||
uint16_t node_id;
|
||||
uint16_t to_tmr;
|
||||
uint16_t burst_cnt;
|
||||
uint16_t burst_tmr;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int get_num(FAR const char *str, FAR int *result);
|
||||
static int parse_args(int argc, FAR char *argv[],
|
||||
FAR struct plcatool_cfg_s *cfg);
|
||||
static int write_plca_mmd(FAR const char *ifname, int phy,
|
||||
uint16_t address, uint16_t data);
|
||||
static int read_plca_mmd(FAR const char *ifname, int phy,
|
||||
uint16_t address, FAR uint16_t *data);
|
||||
static int verify_support(FAR struct plcatool_cfg_s *cfg,
|
||||
FAR bool *supported);
|
||||
static int plcatool_set(FAR struct plcatool_cfg_s *cfg);
|
||||
static int plcatool_get(FAR struct plcatool_cfg_s *cfg);
|
||||
static int plcatool_status(FAR struct plcatool_cfg_s *cfg);
|
||||
static void plcatool_usage(bool err);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int get_num(FAR const char *str, FAR int *result)
|
||||
{
|
||||
FAR char *endptr;
|
||||
*result = (int)strtol(str, &endptr, 0);
|
||||
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int parse_args(int argc, FAR char *argv[],
|
||||
FAR struct plcatool_cfg_s *cfg)
|
||||
{
|
||||
FAR const char *cmd;
|
||||
int argpos = 1;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (strcmp(argv[argpos++], "--phy") == 0)
|
||||
{
|
||||
int phynum;
|
||||
|
||||
if (ARGS_REMAIN(argc, argpos) < 3) /* at least phynum, cmd, intf */
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (get_num(argv[argpos++], &phynum))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (0 <= phynum && phynum <= 31)
|
||||
{
|
||||
cfg->phy = phynum;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argpos = 1;
|
||||
cfg->phy = 0;
|
||||
}
|
||||
|
||||
cmd = argv[argpos++];
|
||||
|
||||
if (strcmp(cmd, "set") == 0)
|
||||
{
|
||||
cfg->cmd = PLCA_CMD_SET;
|
||||
|
||||
if (ARGS_REMAIN(argc, argpos) < 3) /* name, at least one param-value */
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
cfg->ifname = argv[argpos++];
|
||||
|
||||
while (ARGS_REMAIN(argc, argpos) >= 2) /* at least one param-value */
|
||||
{
|
||||
FAR const char *param = argv[argpos++];
|
||||
FAR const char *value = argv[argpos++];
|
||||
|
||||
if (strcmp(param, "enable") == 0)
|
||||
{
|
||||
if (cfg->enable)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (strcmp(value, "on") == 0)
|
||||
{
|
||||
PLCATOOL_CFG_SET(cfg, enable, 1);
|
||||
}
|
||||
else if (strcmp(value, "off") == 0)
|
||||
{
|
||||
PLCATOOL_CFG_SET(cfg, enable, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(param, "node-id") == 0)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (cfg->node_id)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (get_num(value, &n))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (NODE_ID_MIN <= n && n <= NODE_ID_MAX)
|
||||
{
|
||||
PLCATOOL_CFG_SET(cfg, node_id, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "node-id out of range\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(param, "node-cnt") == 0)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (cfg->node_cnt)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (get_num(value, &n))
|
||||
{
|
||||
fprintf(stderr, "Not a valid integer\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (NODE_CNT_MIN <= n && n <= NODE_CNT_MAX)
|
||||
{
|
||||
PLCATOOL_CFG_SET(cfg, node_cnt, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "node-cnt out of range\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(param, "to-tmr") == 0)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (cfg->to_tmr)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (get_num(value, &n))
|
||||
{
|
||||
fprintf(stderr, "Not a valid integer\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (TO_TMR_MIN <= n && n <= TO_TMR_MAX)
|
||||
{
|
||||
PLCATOOL_CFG_SET(cfg, to_tmr, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "to_tmr out of range\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(param, "burst-cnt") == 0)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (cfg->burst_cnt)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (get_num(value, &n))
|
||||
{
|
||||
fprintf(stderr, "Not a valid integer\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (BURST_CNT_MIN <= n && n <= BURST_CNT_MAX)
|
||||
{
|
||||
PLCATOOL_CFG_SET(cfg, burst_cnt, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "burst-cnt out of range\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(param, "burst-tmr") == 0)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (cfg->burst_tmr)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (get_num(value, &n))
|
||||
{
|
||||
fprintf(stderr, "Not a valid integer\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (BURST_TMR_MIN <= n && n <= BURST_TMR_MAX)
|
||||
{
|
||||
PLCATOOL_CFG_SET(cfg, burst_tmr, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "burst-tmr out of range\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGS_REMAIN(argc, argpos) != 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(cmd, "get") == 0)
|
||||
{
|
||||
cfg->cmd = PLCA_CMD_GET;
|
||||
|
||||
if (ARGS_REMAIN(argc, argpos) != 1) /* ifname */
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
cfg->ifname = argv[argpos++];
|
||||
if (strlen(cfg->ifname) > IFNAMSIZ)
|
||||
{
|
||||
fprintf(stderr, "No such interface\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(cmd, "status") == 0)
|
||||
{
|
||||
cfg->cmd = PLCA_CMD_STATUS;
|
||||
|
||||
if (ARGS_REMAIN(argc, argpos) != 1) /* ifname */
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
cfg->ifname = argv[argpos++];
|
||||
if (strlen(cfg->ifname) > IFNAMSIZ)
|
||||
{
|
||||
fprintf(stderr, "No such interface\n");
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (strcmp(cmd, "-h") == 0)
|
||||
{
|
||||
cfg->cmd = PLCA_CMD_HELP;
|
||||
|
||||
if (ARGS_REMAIN(argc, argpos) != 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int write_plca_mmd(FAR const char *ifname, int phy,
|
||||
uint16_t address, uint16_t data)
|
||||
{
|
||||
struct ifreq req;
|
||||
int retval;
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
strcpy(req.ifr_name, ifname);
|
||||
req.ifr_ifru.ifru_mii_data.phy_id = mdio_phy_id_c45(OA_TC14_PLCA_MMD, phy);
|
||||
req.ifr_ifru.ifru_mii_data.reg_num = address;
|
||||
req.ifr_ifru.ifru_mii_data.val_in = data;
|
||||
retval = ioctl(sockfd, SIOCSMIIREG, (unsigned long)(&req));
|
||||
if (retval)
|
||||
{
|
||||
close(sockfd);
|
||||
fprintf(stderr, "Write unsuccessful\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int read_plca_mmd(FAR const char *ifname, int phy,
|
||||
uint16_t address, FAR uint16_t *data)
|
||||
{
|
||||
struct ifreq req;
|
||||
int retval;
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
strcpy(req.ifr_name, ifname);
|
||||
req.ifr_ifru.ifru_mii_data.phy_id = mdio_phy_id_c45(OA_TC14_PLCA_MMD, phy);
|
||||
req.ifr_ifru.ifru_mii_data.reg_num = address;
|
||||
|
||||
retval = ioctl(sockfd, SIOCGMIIREG, (unsigned long)(&req));
|
||||
if (retval)
|
||||
{
|
||||
close(sockfd);
|
||||
fprintf(stderr, "Read unsuccessful\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
*data = req.ifr_ifru.ifru_mii_data.val_out;
|
||||
|
||||
close(sockfd);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int verify_support(FAR struct plcatool_cfg_s *cfg,
|
||||
FAR bool *supported)
|
||||
{
|
||||
uint16_t reg;
|
||||
if (read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_IDVER_ADDR, ®))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
*supported = reg == OA_TC14_IDVER_VAL ? true : false;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int plcatool_set(FAR struct plcatool_cfg_s *cfg)
|
||||
{
|
||||
uint16_t reg;
|
||||
bool supported;
|
||||
|
||||
/* Verify the correct address map code */
|
||||
|
||||
if (verify_support(cfg, &supported))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
fprintf(stderr, "Device not supported\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* node-cnt, node-id */
|
||||
|
||||
if (cfg->node_cnt || cfg->node_id)
|
||||
{
|
||||
if (read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_CTRL1_ADDR, ®))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if (cfg->node_cnt)
|
||||
{
|
||||
int val = PLCATOOL_CFG_VAL(cfg, node_cnt);
|
||||
reg &= ~OA_TC14_CTRL1_NCNT_MASK;
|
||||
reg |= oa_tc14_field(val, CTRL1_NCNT);
|
||||
}
|
||||
|
||||
if (cfg->node_id)
|
||||
{
|
||||
int val = PLCATOOL_CFG_VAL(cfg, node_id);
|
||||
reg &= ~OA_TC14_CTRL1_ID_MASK;
|
||||
reg |= oa_tc14_field(val, CTRL1_ID);
|
||||
}
|
||||
|
||||
if (write_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_CTRL1_ADDR, reg))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
|
||||
/* to-tmr */
|
||||
|
||||
if (cfg->to_tmr)
|
||||
{
|
||||
int val = PLCATOOL_CFG_VAL(cfg, to_tmr);
|
||||
reg = oa_tc14_field(val, TOTMR_TOT);
|
||||
|
||||
if (write_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_TOTMR_ADDR, reg))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
|
||||
/* burst-cnt, burst-tmr */
|
||||
|
||||
if (cfg->burst_cnt || cfg->burst_tmr)
|
||||
{
|
||||
if (read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_BURST_ADDR, ®))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if (cfg->burst_cnt)
|
||||
{
|
||||
int val = PLCATOOL_CFG_VAL(cfg, burst_cnt);
|
||||
reg &= ~OA_TC14_BURST_MAXBC_MASK;
|
||||
reg |= oa_tc14_field(val, BURST_MAXBC);
|
||||
}
|
||||
|
||||
if (cfg->burst_tmr)
|
||||
{
|
||||
int val = PLCATOOL_CFG_VAL(cfg, burst_tmr);
|
||||
reg &= ~OA_TC14_BURST_BTMR_MASK;
|
||||
reg |= oa_tc14_field(val, BURST_BTMR);
|
||||
}
|
||||
|
||||
if (write_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_BURST_ADDR, reg))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
|
||||
/* enable */
|
||||
|
||||
if (cfg->enable)
|
||||
{
|
||||
int val;
|
||||
if (read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_CTRL0_ADDR, ®))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
val = PLCATOOL_CFG_VAL(cfg, enable);
|
||||
reg &= ~OA_TC14_CTRL0_EN_MASK;
|
||||
reg |= oa_tc14_field(val, CTRL0_EN);
|
||||
|
||||
if (write_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_CTRL0_ADDR, reg))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_CTRL0_ADDR, ®);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int plcatool_get(FAR struct plcatool_cfg_s *cfg)
|
||||
{
|
||||
uint16_t ctrl0;
|
||||
uint16_t ctrl1;
|
||||
uint16_t totmr;
|
||||
uint16_t burst;
|
||||
bool supported;
|
||||
|
||||
/* Verify the correct address map code */
|
||||
|
||||
if (verify_support(cfg, &supported))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
fprintf(stderr, "Device not supported\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_CTRL0_ADDR, &ctrl0) ||
|
||||
read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_CTRL1_ADDR, &ctrl1) ||
|
||||
read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_TOTMR_ADDR, &totmr) ||
|
||||
read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_BURST_ADDR, &burst))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
cfg->enable = oa_tc14_get_field(ctrl0, CTRL0_EN);
|
||||
cfg->node_id = oa_tc14_get_field(ctrl1, CTRL1_ID);
|
||||
cfg->node_cnt = oa_tc14_get_field(ctrl1, CTRL1_NCNT);
|
||||
cfg->to_tmr = oa_tc14_get_field(totmr, TOTMR_TOT);
|
||||
cfg->burst_cnt = oa_tc14_get_field(burst, BURST_MAXBC);
|
||||
cfg->burst_tmr = oa_tc14_get_field(burst, BURST_BTMR);
|
||||
|
||||
printf("PLCA settings for %s\n", cfg->ifname);
|
||||
printf("\tEnabled: %s\n", cfg->enable ? "Yes" : "No");
|
||||
printf("\tlocal node ID: %d (%s)\n", cfg->node_id,
|
||||
cfg->node_id == 0 ? "coordinator" :
|
||||
(cfg->node_id == 255 ? "unconfigured" : "follower"));
|
||||
printf("\tNode count: %d%s\n", cfg->node_cnt,
|
||||
cfg->node_id ? " (ignored)" : "");
|
||||
printf("\tTO timer: %d BT\n", cfg->to_tmr);
|
||||
printf("\tBurst count: %d (%s)\n", cfg->burst_cnt,
|
||||
cfg->burst_cnt > 0 ? "enabled" : "disabled");
|
||||
printf("\tBurst timer: %d BT\n", cfg->burst_tmr);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int plcatool_status(FAR struct plcatool_cfg_s *cfg)
|
||||
{
|
||||
uint16_t status;
|
||||
bool supported;
|
||||
|
||||
/* Verify the correct address map code */
|
||||
|
||||
if (verify_support(cfg, &supported))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
fprintf(stderr, "Device not supported\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (read_plca_mmd(cfg->ifname, cfg->phy, OA_TC14_STATUS_ADDR, &status))
|
||||
{
|
||||
return EIO;
|
||||
}
|
||||
|
||||
printf("PLCA status of %s\n", cfg->ifname);
|
||||
printf("\tStatus: %s\n",
|
||||
oa_tc14_get_field(status, STATUS_PST) ? "on" : "off");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void plcatool_usage(bool err)
|
||||
{
|
||||
FAR FILE *out = err ? stderr : stdout;
|
||||
|
||||
fprintf(out, "Usage:\n");
|
||||
fprintf(out, " plcatool [--phy N] status <ifname>\n");
|
||||
fprintf(out, " plcatool [--phy N] get <ifname>\n");
|
||||
fprintf(out, " plcatool [--phy N] set <ifname> <param> <value> "
|
||||
"[<param> <value>] ...\n");
|
||||
fprintf(out, " Accepted <param> <value> pairs:\n");
|
||||
fprintf(out, " enable on | off\n");
|
||||
fprintf(out, " node-id N in [%d .. %d]\n",
|
||||
NODE_ID_MIN, NODE_ID_MAX);
|
||||
fprintf(out, " node-cnt N in [%d .. %d]\n",
|
||||
NODE_CNT_MIN, NODE_CNT_MAX);
|
||||
fprintf(out, " to-tmr N in [%d .. %d]\n",
|
||||
TO_TMR_MIN, TO_TMR_MAX);
|
||||
fprintf(out, " burst-cnt N in [%d .. %d]\n",
|
||||
BURST_CNT_MIN, BURST_CNT_MAX);
|
||||
fprintf(out, " burst-tmr N in [%d .. %d]\n",
|
||||
BURST_TMR_MIN, BURST_TMR_MAX);
|
||||
fprintf(out, " plcatool -h\n");
|
||||
fprintf(out, " --phy N defaults to 0\n");
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
struct plcatool_cfg_s cfg;
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
int err = parse_args(argc, argv, &cfg);
|
||||
if (err)
|
||||
{
|
||||
plcatool_usage(err);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
switch (cfg.cmd)
|
||||
{
|
||||
case PLCA_CMD_SET:
|
||||
return plcatool_set(&cfg);
|
||||
|
||||
case PLCA_CMD_GET:
|
||||
return plcatool_get(&cfg);
|
||||
|
||||
case PLCA_CMD_STATUS:
|
||||
return plcatool_status(&cfg);
|
||||
|
||||
case PLCA_CMD_HELP:
|
||||
plcatool_usage(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue