blob: fbfea7261d32935f3ab2f0e3cd64f056500c4e5f [file] [log] [blame]
/*
* Copyright (c) 2013 Qualcomm Atheros, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <getopt.h>
#include <errno.h>
#include <err.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
#include <fcntl.h>
#include "athrs_ctrl.h"
#include <stdint.h>
#define MAX_SIZ 10
struct eth_cfg_params {
int cmd;
char ad_name[IFNAMSIZ]; /* if name, e.g. "lan0" */
uint16_t vlanid;
uint16_t portnum;
uint32_t phy_reg;
uint32_t tos;
uint32_t val;
uint8_t duplex;
uint8_t mac_addr[6];
struct rx_stats rxcntr;
struct tx_stats txcntr;
struct tx_mac_stats txmac;
struct rx_mac_stats rxmac;
phystats phy_st;
};
struct ifreq ifr;
struct eth_cfg_params etd;
int s,opt_force = 0,duplex = 1;
const char *progname;
static void rx_stats(void)
{
//printf ("\n\n%s\n", __func__);
printf ("\t%d\t port%d :Rx bcast cntr\n", etd.rxcntr.rx_broad, etd.portnum);
printf ("\t%d\t port%d :Rx pause cntr\n", etd.rxcntr.rx_pause, etd.portnum);
printf ("\t%d\t port%d :Rx multi frames rcvd\n", etd.rxcntr.rx_multi, etd.portnum);
printf ("\t%d\t port%d :Rx fcs err cntr\n", etd.rxcntr.rx_fcserr, etd.portnum);
printf ("\t%d\t port%d :Rx allign err cntr\n", etd.rxcntr.rx_allignerr, etd.portnum);
printf ("\t%d\t port%d :Rx runt cntr \n", etd.rxcntr.rx_runt, etd.portnum);
printf ("\t%d\t port%d :Rx fragment cntr\n", etd.rxcntr.rx_frag, etd.portnum);
printf ("\t%d\t port%d :Rx 64b byte cntr\n", etd.rxcntr.rx_64b, etd.portnum);
printf ("\t%d\t port%d :Rx 128b byte cntr\n", etd.rxcntr.rx_128b, etd.portnum);
printf ("\t%d\t port%d :Rx 256b byte cntr\n", etd.rxcntr.rx_256b, etd.portnum);
printf ("\t%d\t port%d :Rx 512b byte cntr\n", etd.rxcntr.rx_512b, etd.portnum);
printf ("\t%d\t port%d :Rx 1024b byte cntr\n", etd.rxcntr.rx_1024b, etd.portnum);
printf ("\t%d\t port%d :Rx 1518b byte cntr\n ", etd.rxcntr.rx_1518b, etd.portnum);
printf ("\t%d\t port%d :Rx total pkt rcvd\n", (etd.rxcntr.rx_64b + etd.rxcntr.rx_128b + etd.rxcntr.rx_256b +
etd.rxcntr.rx_512b + etd.rxcntr.rx_1024b + etd.rxcntr.rx_1518b), etd.portnum);
printf ("\t%d\t port%d :Rx maxb cntr\n", etd.rxcntr.rx_maxb, etd.portnum);
printf ("\t%d\t port%d :Rx too long cntr\n", etd.rxcntr.rx_tool, etd.portnum);
printf ("\t%d\t port%d :Rx byte_l\n", etd.rxcntr.rx_goodbl, etd.portnum);
printf ("\t%d\t port%d :Rx byte_h\n", etd.rxcntr.rx_goodbh, etd.portnum);
printf ("\t%d\t port%d :Rx overflow cntr\n", etd.rxcntr.rx_overflow, etd.portnum);
printf ("\t%d\t port%d :Rx bad byte_l cntr\n", etd.rxcntr.rx_badbl, etd.portnum);
printf ("\t%d\t port%d :Rx bad byte_u cntr\n", etd.rxcntr.rx_badbu, etd.portnum);
}
static void tx_stats(void)
{
printf ("\n\n%s\n", __func__);
printf ("\t%d\t port%d : Tx bcast cntr \n", etd.txcntr.tx_broad, etd.portnum);
printf ("\t%d\t port%d : Tx pause cntr\n", etd.txcntr.tx_pause, etd.portnum);
printf ("\t%d\t port%d : Tx multi cntr\n", etd.txcntr.tx_multi, etd.portnum);
printf ("\t%d\t port%d : Tx under run cntr\n", etd.txcntr.tx_underrun, etd.portnum);
printf ("\t%d\t port%d : Tx 64b byte cntr\n", etd.txcntr.tx_64b, etd.portnum);
printf ("\t%d\t port%d : Tx 128b byte cntr\n", etd.txcntr.tx_128b, etd.portnum);
printf ("\t%d\t port%d : Tx 256b byte cntr\n", etd.txcntr.tx_256b, etd.portnum);
printf ("\t%d\t port%d : Tx 512b byte cntr\n", etd.txcntr.tx_512b, etd.portnum);
printf ("\t%d\t port%d : Tx 1024b byte cntr\n", etd.txcntr.tx_1024b, etd.portnum);
printf ("\t%d\t port%d : Tx 1518b byte cntr\n", etd.txcntr.tx_1518b, etd.portnum);
printf ("\t%d\t port%d : Tx total pkt txmtd cntr\n", (etd.txcntr.tx_64b + etd.txcntr.tx_128b
+ etd.txcntr.tx_256b+ etd.txcntr.tx_512b + etd.txcntr.tx_1024b
+ etd.txcntr.tx_1518b), etd.portnum);
printf ("\t%d\t port%d : Tx max byte cntr\n", etd.txcntr.tx_maxb, etd.portnum);
printf ("\t%d\t port%d : Tx oversize \n", etd.txcntr.tx_oversiz, etd.portnum);
printf ("\t%d\t port%d : Tx byte _l \n", etd.txcntr.tx_bytel, etd.portnum);
printf ("\t%d\t port%d : Tx byte _h \n", etd.txcntr.tx_byteh, etd.portnum);
printf ("\t%d\t port%d : Tx collision err cntr\n", etd.txcntr.tx_collision, etd.portnum);
printf ("\t%d\t port%d : Tx abort collision err cntr\n", etd.txcntr.tx_abortcol, etd.portnum);
printf ("\t%d\t port%d : Tx multi collision err cntr\n", etd.txcntr.tx_multicol, etd.portnum);
printf ("\t%d\t port%d : Tx single collision err cntr\n", etd.txcntr.tx_singalcol, etd.portnum);
printf ("\t%d\t port%d : Tx exec deffer err cntr\n", etd.txcntr.tx_execdefer, etd.portnum);
printf ("\t%d\t port%d : Tx defer err cntr\n", etd.txcntr.tx_defer, etd.portnum);
printf ("\t%d\t port%d : Tx late collision err cntr\n", etd.txcntr.tx_latecol, etd.portnum);
}
static void tx_mac_stats(void)
{
printf ("\n\n%s\n", __func__);
printf ("\t%d\t : Tx pkt cntr\n", etd.txmac.pkt_cntr);
printf ("\t%d\t : Tx byte cntr\n", etd.txmac.byte_cntr);
printf ("\t%d\t : Tx mcast pkt cntr\n", etd.txmac.mcast_cntr);
printf ("\t%d\t : Tx bcast pkt cntr\n", etd.txmac.bcast_cntr);
printf ("\t%d\t : Tx pause frame pkt cntr\n", etd.txmac.pctrlframe_cntr);
printf ("\t%d\t : Tx deferal pkt cntr\n", etd.txmac.deferal_cntr);
printf ("\t%d\t : Tx excessive deferal pkt cntr\n", etd.txmac.excess_deferal_cntr);
printf ("\t%d\t : Tx single collision pkt cntr\n", etd.txmac.single_col_cntr);
printf ("\t%d\t : Tx multiple collision pkt cntr\n", etd.txmac.multi_col_cntr);
printf ("\t%d\t : Tx late collision pkt cntr\n", etd.txmac.late_col_cntr);
printf ("\t%d\t : Tx excessive collison pkt cntr\n", etd.txmac.excess_col_cntr);
printf ("\t%d\t : Tx total collison pkt cntr\n", etd.txmac.total_col_cntr);
printf ("\t%d\t : Tx drop frame cntr\n", etd.txmac.dropframe_cntr);
printf ("\t%d\t : Tx jabber frame cntr\n", etd.txmac.jabberframe_cntr);
printf ("\t%d\t : Tx fcs err cntr\n", etd.txmac.fcserr_cntr);
printf ("\t%d\t : Tx control frame cntr\n", etd.txmac.ctrlframe_cntr);
printf ("\t%d\t : Tx oversize frame cntr\n", etd.txmac.oz_frame_cntr);
printf ("\t%d\t : Tx undersize frame cntr\n", etd.txmac.us_frame_cntr);
printf ("\t%d\t : Tx fragments frame cntr\n", etd.txmac.frag_frame_cntr);
}
static void rx_mac_stats (void)
{
printf ("\n\n%s\n", __func__);
printf ("\t%d\t: Rx byte cntr\n", etd.rxmac.byte_cntr);
printf ("\t%d\t: Rx pkt cntr\n", etd.rxmac.pkt_cntr);
printf ("\t%d\t: Rx fcs err cntr\n", etd.rxmac.fcserr_cntr);
printf ("\t%d\t: Rx mcast pkt cntr\n", etd.rxmac.mcast_cntr);
printf ("\t%d\t: Rx bcast pkt cntr\n", etd.rxmac.bcast_cntr);
printf ("\t%d\t: Rx ctrl frame cntr\n", etd.rxmac.ctrlframe_cntr);
printf ("\t%d\t: Rx pause frame pkt cntr\n", etd.rxmac.pausefr_cntr);
printf ("\t%d\t: Rx unknown opcode cntr\n", etd.rxmac.unknownop_cntr);
printf ("\t%d\t: Rx alignment err cntr\n", etd.rxmac.allignerr_cntr);
printf ("\t%d\t: Rx frame length err cntr\n", etd.rxmac.framelerr_cntr);
printf ("\t%d\t: Rx code err cntr\n", etd.rxmac.codeerr_cntr);
printf ("\t%d\t: Rx carrier sense err cntr\n", etd.rxmac.carriersenseerr_cntr);
printf ("\t%d\t: Rx under sz pkt cntr\n", etd.rxmac.underszpkt_cntr);
printf ("\t%d\t: Rx over sz pkt cntr\n", etd.rxmac.ozpkt_cntr);
printf ("\t%d\t: Rx fragment cntr\n", etd.rxmac.fragment_cntr);
printf ("\t%d\t: Rx jabber cntr\n", etd.rxmac.jabber_cntr);
printf ("\t%d\t: RX drop cntr\n",etd.rxmac.rcvdrop_cntr);
printf ("\t%u\t: Rx overfl cntr\n",etd.rxmac.rxoverfl);
}
u_int32_t
regread(u_int32_t phy_reg,u_int16_t portno)
{
etd.phy_reg = phy_reg;
etd.cmd = ATHR_PHY_RD;
etd.portnum = portno;
if (ioctl(s,ATHR_PHY_CTRL_IOC, &ifr) < 0)
err(1, etd.ad_name);
return etd.val;
}
static void athr_en_jumboframe(int value)
{
etd.cmd = ATHR_JUMBO_FRAME;
etd.val=value;
if (ioctl(s,ATHR_GMAC_CTRL_IOC, &ifr) < 0)
err(1,etd.ad_name);
}
static void athr_set_framesize(int sz)
{
etd.cmd = ATHR_FRAME_SIZE_CTL;
etd.val = sz;
if (ioctl(s,ATHR_GMAC_CTRL_IOC, &ifr) < 0)
err(1,etd.ad_name);
}
static void athr_commit_acl_rules(void)
{
etd.cmd = ATHR_ACL_COMMIT;
if (ioctl(s,ATHR_HW_ACL_IOC,&ifr) < 0)
err(1,etd.ad_name);
}
static void athr_flush_acl_rules(void)
{
etd.cmd = ATHR_ACL_FLUSH;
if (ioctl(s,ATHR_HW_ACL_IOC,&ifr) < 0)
err(1,etd.ad_name);
}
static void athr_flow_link (int portno, int val)
{
etd.cmd = ATHR_FLOW_LINK_EN;
etd.val = val;
etd.portnum = portno;
if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0)
err(1,etd.ad_name);
}
static void athr_txflctrl (int portno, int val)
{
if (portno == 0x3f) {
etd.val = val;
etd.cmd = ATHR_GMAC_TX_FLOW_CTRL;
if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0)
printf("%s ioctl error\n",__func__);
} else {
etd.cmd = ATHR_PHY_TXFCTL;
etd.portnum = portno;
etd.val = val;
if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0)
printf("%s ioctl error\n",__func__);
}
}
static void athr_gmac_flow_ctrl(int val)
{
etd.val = val;
etd.cmd = ATHR_GMAC_FLOW_CTRL;
if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0)
printf("%s ioctl error\n",__func__);
}
static void athr_phy_flow_ctrl(int val, int portno)
{
etd.val = val;
etd.cmd = ATHR_PHY_FLOW_CTRL;
etd.portnum = portno;
if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0)
printf("%s ioctl error\n",__func__);
}
static void athr_rxflctrl (int portno, int val)
{
if (portno == 0x3f) {
etd.val = val;
etd.cmd = ATHR_GMAC_RX_FLOW_CTRL;
if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0)
printf("%s ioctl error\n",__func__);
} else {
etd.cmd = ATHR_PHY_RXFCTL;
etd.portnum = portno;
etd.val = val;
if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0)
printf("%s ioctl error\n",__func__);
}
}
static void athr_set_mib(int val)
{
etd.cmd = ATHR_PHY_MIB;
etd.portnum = 0x3f;
etd.val = val;
if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0)
err(1, etd.ad_name);
}
static void athr_disp_stats(int portno)
{
if (portno == 0x3f) {
etd.cmd = ATHR_GMAC_STATS;
if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0){
err(1, etd.ad_name);
} else {
rx_mac_stats ();
tx_mac_stats ();
}
} else {
etd.cmd = ATHR_PHY_STATS;
etd.portnum = portno;
if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0)
err(1, etd.ad_name);
else{
rx_stats ();
tx_stats ();
}
}
}
static void athr_dma_check(int val)
{
etd.cmd = ATHR_GMAC_DMA_CHECK;
etd.val = val;
if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0)
err(1, etd.ad_name);
}
static void athr_set_qos(int val)
{
etd.cmd = ATHR_QOS_ETH_SOFT_CLASS;
etd.val = val;
if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
}
static void athr_set_port_pri(int portno, int val)
{
etd.cmd = ATHR_QOS_ETH_PORT;
etd.portnum = portno;
etd.val = val;
if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
}
static void athr_ip_qos (int tos, int val)
{
etd.cmd = ATHR_QOS_ETH_IP;
etd.val = val;
etd.tos = tos;
if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
}
static void athr_vlan_qos (int vlan_id, int val)
{
etd.cmd = ATHR_QOS_ETH_VLAN;
etd.val = val;
etd.vlanid = vlan_id;
if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
}
static void athr_mac_qos(int portno, int val, char *mac_addr)
{
etd.cmd = ATHR_QOS_ETH_DA;
etd.val = val;
etd.portnum = portno;
sscanf (mac_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&etd.mac_addr[0], &etd.mac_addr[1],
&etd.mac_addr[2], &etd.mac_addr[3],
&etd.mac_addr[4], &etd.mac_addr[5]);
if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
}
static int athr_port_st(int portno)
{
char str[][MAX_SIZ] = {"10Mbps","100Mbps","1000Mbps"};
etd.cmd = ATHR_PORT_STATS;
etd.portnum = portno;
if (etd.portnum > 5){
printf ("port usage <0-5>");
return -EINVAL;
}
if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
printf("\t\t\t____phy%d stats____\n",etd.portnum);
printf("Link:\t\t%s\n",etd.phy_st.link ? "alive":"Not alive");
printf("Speed:\t\t%s\n",str[etd.phy_st.speed]);
printf("Duplex:\t\t%s\n",etd.phy_st.duplex ? "Full duplex":"Half-duplex");
printf("Rx flowctrl:\t%s\n",etd.phy_st.rxflctrl ? "Enabled": "Disabled");
printf("Tx flowctrl:\t%s\n",etd.phy_st.txflctrl ? "Enabled": "Disabled");
return 0;
}
static void athr_process_egress(int portno, int val)
{
etd.cmd = ATHR_QOS_PORT_ELIMIT;
etd.val = val;
etd. portnum = portno;
if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
}
static void athr_process_igress(int portno, int val)
{
etd.cmd = ATHR_QOS_PORT_ILIMIT;
etd.val = val;
etd. portnum = portno;
if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0)
err (1, etd.ad_name);
}
void regwrite(u_int32_t phy_reg,u_int32_t val,u_int16_t portno)
{
etd.val = val;
etd.phy_reg = phy_reg;
etd.portnum = portno;
if(opt_force) {
etd.duplex = duplex;
etd.cmd = ATHR_PHY_FORCE;
if (ioctl(s,ATHR_PHY_CTRL_IOC, &ifr) < 0)
err(1, etd.ad_name);
opt_force = 0;
}
else {
etd.cmd = ATHR_PHY_WR;
if (ioctl(s,ATHR_PHY_CTRL_IOC, &ifr) < 0)
err(1, etd.ad_name);
}
}
static void usage(void)
{
fprintf(stderr, "usage: %s [-i ifname] [-p portnum] offset[=value]\n", progname);
fprintf(stderr, "usage: %s [-f] -p portnum =10/100/0 [-d duplex]\n", progname);
fprintf(stderr, "usage: %s [-i ifname][-x]\n", progname);
fprintf(stderr, "usage: %s [-i ifname][-c]\n", progname);
fprintf(stderr, "usage: %s [-i ifname][-s value]\n", progname);
fprintf(stderr, "usage: %s [-i ifname][-j 0|1]\n", progname);
fprintf(stderr, "usage: %s [--txfctl] [-i ifname] -v [0|1]\n", progname);
fprintf(stderr, "usage: %s [--txfctl] [-i ifname] -v [0|1] -p <portno>\n", progname);
fprintf(stderr, "usage: %s [--rxfctl] [-i ifname] -v [0|1]\n",progname);
fprintf(stderr, "usage: %s [--rxfctl] [-i ifname] -v [0|1] -p <portno>\n", progname);
fprintf(stderr, "usage: %s [--macfl] [-i ifname] -v [0|1]\n", progname);
fprintf(stderr, "usage: %s [--swfl] [-i ifname] -v [0|1]\n", progname);
fprintf(stderr, "usage: %s [--dma] [-i ifname] -v [0|1]\n", progname);
fprintf(stderr, "usage: %s [--f_link] [-i ifname] -v [0|1]\n", progname);
fprintf(stderr, "usage: %s [--mib] [-i ifname] -v [0|1]\n", progname);
fprintf(stderr, "usage: %s [--stats] [-i ifname]\n", progname);
fprintf(stderr, "usage: %s [--stats] [-i ifname] -p <portno>\n", progname);
fprintf(stderr, "usage: %s [--qos] [-i ifname] -v [0|1]\n", progname);
fprintf(stderr, "usage: %s [--ipqos] [-i ifname] -t <tos> -v <val>\n", progname);
fprintf(stderr, "usage: %s [--vqos] [-i ifname] -l <vlanid> -v <val>\n", progname);
fprintf(stderr, "usage: %s [--mqos [-i ifname] -v <val> -p <portnum> -m <macaddr>\n", progname);
fprintf(stderr, "usage: %s [--p_st] [-i ifname] -p <portno>\n", progname);
fprintf(stderr, "usage: %s [--igrl] [-i ifname] -p <portno> -v <val>\n", progname);
fprintf(stderr, "usage: %s [--egrl] [-i ifname] -p <portno> -v <val>\n", progname);
fprintf(stderr, "usage: %s [-i ifname][-s value]\n",progname);
fprintf(stderr, "usage: %s [-i ifname][-j 0|1]\n",progname);
exit(-1);
}
int
ethreg_main(int argc, char *argv[])
{
const char *ifname = "lan0";
int c,portnum = 0x3f,cmd = 0,value = -1;
int optionindex = 0;
int vlanid = 0;
char *mac = NULL;
int tos = -1;
char *opt = "xfhci:d:s:j:v:t:p:m:l:";
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
err(1, "socket");
opt_force = 0;
progname = argv[0];
struct option long_options[] =
{
{ "f_link", no_argument, 0, ATHR_FLOW_LINK_EN},
{ "txfctl", no_argument, 0, ATHR_PHY_TXFCTL},
{ "rxfctl", no_argument, 0, ATHR_PHY_RXFCTL},
{ "stats" , no_argument, 0, ATHR_GMAC_STATS},
{ "mib" , no_argument, 0, ATHR_PHY_MIB},
{ "dma" , no_argument, 0, ATHR_GMAC_DMA_CHECK},
{ "qos" , no_argument, 0, ATHR_QOS_ETH_SOFT_CLASS},
{ "ppri" , no_argument, 0, ATHR_QOS_ETH_PORT},
{ "ipqos" , no_argument, 0, ATHR_QOS_ETH_IP},
{ "vqos" , no_argument, 0, ATHR_QOS_ETH_VLAN},
{ "mqos" , no_argument, 0, ATHR_QOS_ETH_DA},
{ "igrl" , no_argument, 0, ATHR_QOS_PORT_ELIMIT},
{ "egrl" , no_argument, 0, ATHR_QOS_PORT_ILIMIT},
{ "p_st" , no_argument, 0, ATHR_PORT_STATS},
{ "macfl" , no_argument, 0, ATHR_GMAC_FLOW_CTRL},
{ "swfl" , no_argument, 0, ATHR_PHY_FLOW_CTRL},
{ 0,0,0,0}
};
while ((c = getopt_long(argc, argv,
opt, long_options, &optionindex)) != -1) {
switch (c) {
case ATHR_FLOW_LINK_EN:
cmd = ATHR_FLOW_LINK_EN;
break;
case ATHR_PHY_TXFCTL:
cmd = ATHR_PHY_TXFCTL;
break;
case ATHR_PHY_RXFCTL:
cmd = ATHR_PHY_RXFCTL;
break;
case ATHR_PHY_MIB:
cmd = ATHR_PHY_MIB;
break;
case ATHR_GMAC_STATS:
cmd = ATHR_GMAC_STATS;
break;
case ATHR_GMAC_DMA_CHECK:
cmd = ATHR_GMAC_DMA_CHECK;
break;
case ATHR_QOS_ETH_SOFT_CLASS:
cmd = ATHR_QOS_ETH_SOFT_CLASS;
break;
case ATHR_QOS_ETH_PORT:
cmd = ATHR_QOS_ETH_PORT;
break;
case ATHR_QOS_ETH_VLAN:
cmd = ATHR_QOS_ETH_VLAN;
break;
case ATHR_QOS_ETH_IP:
cmd = ATHR_QOS_ETH_IP;
break;
case ATHR_QOS_ETH_DA:
cmd = ATHR_QOS_ETH_DA;
break;
case ATHR_PORT_STATS:
cmd = ATHR_PORT_STATS;
break;
case ATHR_QOS_PORT_ELIMIT:
cmd = ATHR_QOS_PORT_ELIMIT;
break;
case ATHR_QOS_PORT_ILIMIT:
cmd = ATHR_QOS_PORT_ILIMIT;
break;
case ATHR_GMAC_FLOW_CTRL:
cmd = ATHR_GMAC_FLOW_CTRL;
break;
case ATHR_PHY_FLOW_CTRL:
cmd = ATHR_PHY_FLOW_CTRL;
break;
case 'm':
mac = optarg;
break;
case 'v':
value = strtoul(optarg, 0, 0);
break;
case 'i':
ifname = optarg;
break;
case 't':
tos = strtoul(optarg, 0, 0);
break;
case 'p':
portnum = strtoul(optarg, 0, 0);
break;
case 'f':
opt_force = 1;
break;
case 'd':
duplex = strtoul(optarg, 0, 0);
break;
case 'c':
cmd = ATHR_ACL_COMMIT;
break;
case 'x':
cmd = ATHR_ACL_FLUSH;
break;
case 's':
cmd = ATHR_FRAME_SIZE_CTL;
value = strtoul(optarg, 0, 0);
break;
case 'j':
cmd = ATHR_JUMBO_FRAME;
value = strtoul(optarg, 0, 0);
break;
case 'l':
vlanid = strtoul (optarg, 0, 0);
break;
case 'h':
usage();
break;
default:
usage();
/*NOTREACHED*/
}
}
argc -= optind;
argv += optind;
strncpy(etd.ad_name, ifname, sizeof (etd.ad_name));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_data = (void *) &etd;
if (cmd == ATHR_ACL_COMMIT) {
athr_commit_acl_rules();
return 0;
}
else if (cmd == ATHR_ACL_FLUSH) {
athr_flush_acl_rules();
return 0;
}
else if(cmd == ATHR_FRAME_SIZE_CTL) {
if (value == -1) {
printf ("usage:ethreg -i <if_name> -s <val>\n");
return -1;
} else {
athr_set_framesize(value);
}
return 0;
}
else if (cmd == ATHR_JUMBO_FRAME) {
if (value == -1) {
printf ("usage: ethreg -i <if_name> -j <0|1>\n");
return -1;
} else {
athr_en_jumboframe(value);
}
return 0;
}
else if (cmd == ATHR_FLOW_LINK_EN) {
if (value == -1 || portnum == 0x3f) {
printf ("usage: ethreg --f_link -i <ifname> -p <portnum> -v 1\n");
return -1;
} else {
athr_flow_link(portnum, value);
}
return 0;
}
else if (cmd == ATHR_PHY_RXFCTL) {
if (value == -1) {
printf ("usage: ethreg --rxfctl -i <ifname> -p <portnum> -v [0|1]\n");
printf ("usage: ethreg --rxfctl -i <ifname> -v [0|1]\n");
return -1;
} else {
athr_rxflctrl(portnum, value);
}
return 0;
}
else if (cmd == ATHR_PHY_TXFCTL) {
if (value == -1) {
printf ("usage: ethreg --txfctl -i <ifname> -p <portnum> -v [0|1]\n");
printf ("usage: ethreg --txfctl -i <ifname> -v [0|1]\n");
return -1;
} else {
athr_txflctrl(portnum, value);
}
return 0;
}
else if (cmd == ATHR_PHY_MIB) {
if (value == -1) {
printf ("usage: ethreg --mib -i <ifname> -v 1\n");
return -1;
} else {
athr_set_mib(value);
}
return 0;
}
else if (cmd == ATHR_GMAC_STATS) {
athr_disp_stats(portnum);
return 0;
}
else if (cmd == ATHR_GMAC_DMA_CHECK) {
if (value == -1) {
printf ("usage: ethreg --dma -i <ifname> -v [0|1]\n");
return -1;
} else {
athr_dma_check(value);
}
return 0;
}
else if (cmd == ATHR_QOS_ETH_SOFT_CLASS) {
if (value == -1) {
printf ("usage: ethreg --qos -i <ifname> -v [0|1]\n");
return -1;
} else {
athr_set_qos(value);
}
return 0;
}
else if (cmd == ATHR_QOS_ETH_PORT) {
if (value == -1) {
printf("usage: ethreg --ppri -i <ifname> -p <portno> -v <val>\n");
return -1;
} else {
athr_set_port_pri(portnum, value);
}
return 0;
}
else if (cmd == ATHR_QOS_ETH_IP) {
if (tos == -1 || value == -1) {
printf ("usage: ethreg --ipqos -i <ifname> -v <val> -t <tos>\n");
return -1;
} else {
athr_ip_qos(tos, value);
}
return 0;
}
else if (cmd == ATHR_QOS_ETH_VLAN) {
if (value == -1 || vlanid == -1) {
printf ("usage: ethreg --vqos -i <ifname> -v <val> -l <vlanid>\n");
return -1;
} else {
athr_vlan_qos(vlanid, value);
}
return 0;
}
else if (cmd == ATHR_QOS_ETH_DA) {
if (portnum == 0x3f || value == -1 || mac == NULL) {
printf ("usage: ethreg --mqos -i <ifname> -v <val> -p <portnum> -m <macaddr>\n");
return -1;
} else {
athr_mac_qos(portnum, value, mac);
}
return 0;
}
else if (cmd == ATHR_PORT_STATS) {
if (portnum == 0x3f) {
printf ("usage: ethreg --port_st -i <ifname> -p <portno>\n");
return -1;
} else {
athr_port_st(portnum);
}
return 0;
}
else if (cmd == ATHR_QOS_PORT_ELIMIT) {
if (portnum == 0x3f || value == -1 ) {
printf("usage: ethreg --egrl -i <ifname> -p <portnum> -v <val>\n");
return -1;
} else {
athr_process_egress(portnum, value);
}
return 0;
}
else if (cmd == ATHR_QOS_PORT_ILIMIT) {
if (portnum == 0x3f || value == -1 ) {
printf("usage: ethreg --igrl -i <ifname> -p <portnum> -v <val>\n");
return -1;
} else {
athr_process_igress(portnum, value);
}
return 0;
}
else if (cmd == ATHR_GMAC_FLOW_CTRL){
athr_gmac_flow_ctrl(value);
return 0;
}
else if (cmd == ATHR_PHY_FLOW_CTRL){
athr_phy_flow_ctrl(value, portnum);
return 0;
}
for (; argc > 0; argc--, argv++) {
u_int32_t off;
u_int32_t val, oval;
char *cp;
cp = strchr(argv[0], '=');
if (cp != NULL)
*cp = '\0';
off = (u_int) strtoul(argv[0], 0, 0);
if (off == 0 && errno == EINVAL)
errx(1, "%s: invalid reg offset %s",
progname, argv[0]);
if (cp == NULL) {
val = regread(off,portnum);
printf("Read Reg: 0x%08x = 0x%08x\n",off, val);
return 0;
} else {
val = (u_int32_t) strtoul(cp+1, 0, 0);
if (val == 0 && errno == EINVAL) {
errx(1, "%s: invalid reg value %s",
progname, cp+1);
}
else {
oval = regread(off,portnum);
if(opt_force == 0) {
printf("Write Reg: 0x%08x: Oldval = 0x%08x Newval = 0x%08x\n", off, oval, val);
} else if(opt_force == 1 && portnum == 0x3f) {
fprintf(stderr, "usage: %s [-f] -p portnum =10/100/0 [-d duplex]\n", progname);
return -1;
}
regwrite(off,val,portnum);
}
}
}
return 0;
}