1/* 2 * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 * 18 */ 19 20#include <stdio.h> 21#include <sys/types.h> 22#include <sys/socket.h> 23#include <getopt.h> 24#include <errno.h> 25#include <err.h> 26#include <sys/ioctl.h> 27#include <unistd.h> 28#include <stdlib.h> 29#include <string.h> 30#include <net/if.h> 31#include <fcntl.h> 32#include "busybox.h" 33#include "athrs_ctrl.h" 34#define MAX_SIZ 10 35 36struct eth_cfg_params { 37 int cmd; 38 char ad_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ 39 uint16_t vlanid; 40 uint16_t portnum; 41 uint32_t phy_reg; 42 uint32_t tos; 43 uint32_t val; 44 uint8_t duplex; 45 uint8_t mac_addr[6]; 46 struct rx_stats rxcntr; 47 struct tx_stats txcntr; 48 struct tx_mac_stats txmac; 49 struct rx_mac_stats rxmac; 50 phystats phy_st; 51 52}; 53 54struct ifreq ifr; 55struct eth_cfg_params etd; 56int s,opt_force = 0,duplex = 1; 57const char *progname; 58static void rx_stats(void) 59{ 60 //printf ("\n\n%s\n", __func__); 61 printf ("\t%d\t port%d :Rx bcast cntr\n", etd.rxcntr.rx_broad, etd.portnum); 62 printf ("\t%d\t port%d :Rx pause cntr\n", etd.rxcntr.rx_pause, etd.portnum); 63 printf ("\t%d\t port%d :Rx multi frames rcvd\n", etd.rxcntr.rx_multi, etd.portnum); 64 printf ("\t%d\t port%d :Rx fcs err cntr\n", etd.rxcntr.rx_fcserr, etd.portnum); 65 printf ("\t%d\t port%d :Rx allign err cntr\n", etd.rxcntr.rx_allignerr, etd.portnum); 66 printf ("\t%d\t port%d :Rx runt cntr \n", etd.rxcntr.rx_runt, etd.portnum); 67 printf ("\t%d\t port%d :Rx fragment cntr\n", etd.rxcntr.rx_frag, etd.portnum); 68 printf ("\t%d\t port%d :Rx 64b byte cntr\n", etd.rxcntr.rx_64b, etd.portnum); 69 printf ("\t%d\t port%d :Rx 128b byte cntr\n", etd.rxcntr.rx_128b, etd.portnum); 70 printf ("\t%d\t port%d :Rx 256b byte cntr\n", etd.rxcntr.rx_256b, etd.portnum); 71 printf ("\t%d\t port%d :Rx 512b byte cntr\n", etd.rxcntr.rx_512b, etd.portnum); 72 printf ("\t%d\t port%d :Rx 1024b byte cntr\n", etd.rxcntr.rx_1024b, etd.portnum); 73 printf ("\t%d\t port%d :Rx 1518b byte cntr\n ", etd.rxcntr.rx_1518b, etd.portnum); 74 printf ("\t%d\t port%d :Rx total pkt rcvd\n", (etd.rxcntr.rx_64b + etd.rxcntr.rx_128b + etd.rxcntr.rx_256b + 75 etd.rxcntr.rx_512b + etd.rxcntr.rx_1024b + etd.rxcntr.rx_1518b), etd.portnum); 76 printf ("\t%d\t port%d :Rx maxb cntr\n", etd.rxcntr.rx_maxb, etd.portnum); 77 printf ("\t%d\t port%d :Rx too long cntr\n", etd.rxcntr.rx_tool, etd.portnum); 78 printf ("\t%d\t port%d :Rx byte_l\n", etd.rxcntr.rx_goodbl, etd.portnum); 79 printf ("\t%d\t port%d :Rx byte_h\n", etd.rxcntr.rx_goodbh, etd.portnum); 80 printf ("\t%d\t port%d :Rx overflow cntr\n", etd.rxcntr.rx_overflow, etd.portnum); 81 printf ("\t%d\t port%d :Rx bad byte_l cntr\n", etd.rxcntr.rx_badbl, etd.portnum); 82 printf ("\t%d\t port%d :Rx bad byte_u cntr\n", etd.rxcntr.rx_badbu, etd.portnum); 83} 84 85static void tx_stats(void) 86{ 87 printf ("\n\n%s\n", __func__); 88 printf ("\t%d\t port%d : Tx bcast cntr \n", etd.txcntr.tx_broad, etd.portnum); 89 printf ("\t%d\t port%d : Tx pause cntr\n", etd.txcntr.tx_pause, etd.portnum); 90 printf ("\t%d\t port%d : Tx multi cntr\n", etd.txcntr.tx_multi, etd.portnum); 91 printf ("\t%d\t port%d : Tx under run cntr\n", etd.txcntr.tx_underrun, etd.portnum); 92 printf ("\t%d\t port%d : Tx 64b byte cntr\n", etd.txcntr.tx_64b, etd.portnum); 93 printf ("\t%d\t port%d : Tx 128b byte cntr\n", etd.txcntr.tx_128b, etd.portnum); 94 printf ("\t%d\t port%d : Tx 256b byte cntr\n", etd.txcntr.tx_256b, etd.portnum); 95 printf ("\t%d\t port%d : Tx 512b byte cntr\n", etd.txcntr.tx_512b, etd.portnum); 96 printf ("\t%d\t port%d : Tx 1024b byte cntr\n", etd.txcntr.tx_1024b, etd.portnum); 97 printf ("\t%d\t port%d : Tx 1518b byte cntr\n", etd.txcntr.tx_1518b, etd.portnum); 98 printf ("\t%d\t port%d : Tx total pkt txmtd cntr\n", (etd.txcntr.tx_64b + etd.txcntr.tx_128b 99 + etd.txcntr.tx_256b+ etd.txcntr.tx_512b + etd.txcntr.tx_1024b 100 + etd.txcntr.tx_1518b), etd.portnum); 101 printf ("\t%d\t port%d : Tx max byte cntr\n", etd.txcntr.tx_maxb, etd.portnum); 102 printf ("\t%d\t port%d : Tx oversize \n", etd.txcntr.tx_oversiz, etd.portnum); 103 printf ("\t%d\t port%d : Tx byte _l \n", etd.txcntr.tx_bytel, etd.portnum); 104 printf ("\t%d\t port%d : Tx byte _h \n", etd.txcntr.tx_byteh, etd.portnum); 105 printf ("\t%d\t port%d : Tx collision err cntr\n", etd.txcntr.tx_collision, etd.portnum); 106 printf ("\t%d\t port%d : Tx abort collision err cntr\n", etd.txcntr.tx_abortcol, etd.portnum); 107 printf ("\t%d\t port%d : Tx multi collision err cntr\n", etd.txcntr.tx_multicol, etd.portnum); 108 printf ("\t%d\t port%d : Tx single collision err cntr\n", etd.txcntr.tx_singalcol, etd.portnum); 109 printf ("\t%d\t port%d : Tx exec deffer err cntr\n", etd.txcntr.tx_execdefer, etd.portnum); 110 printf ("\t%d\t port%d : Tx defer err cntr\n", etd.txcntr.tx_defer, etd.portnum); 111 printf ("\t%d\t port%d : Tx late collision err cntr\n", etd.txcntr.tx_latecol, etd.portnum); 112 113} 114static void tx_mac_stats(void) 115{ 116 printf ("\n\n%s\n", __func__); 117 printf ("\t%d\t : Tx pkt cntr\n", etd.txmac.pkt_cntr); 118 printf ("\t%d\t : Tx byte cntr\n", etd.txmac.byte_cntr); 119 printf ("\t%d\t : Tx mcast pkt cntr\n", etd.txmac.mcast_cntr); 120 printf ("\t%d\t : Tx bcast pkt cntr\n", etd.txmac.bcast_cntr); 121 printf ("\t%d\t : Tx pause frame pkt cntr\n", etd.txmac.pctrlframe_cntr); 122 printf ("\t%d\t : Tx deferal pkt cntr\n", etd.txmac.deferal_cntr); 123 printf ("\t%d\t : Tx excessive deferal pkt cntr\n", etd.txmac.excess_deferal_cntr); 124 printf ("\t%d\t : Tx single collision pkt cntr\n", etd.txmac.single_col_cntr); 125 printf ("\t%d\t : Tx multiple collision pkt cntr\n", etd.txmac.multi_col_cntr); 126 printf ("\t%d\t : Tx late collision pkt cntr\n", etd.txmac.late_col_cntr); 127 printf ("\t%d\t : Tx excessive collison pkt cntr\n", etd.txmac.excess_col_cntr); 128 printf ("\t%d\t : Tx total collison pkt cntr\n", etd.txmac.total_col_cntr); 129 printf ("\t%d\t : Tx drop frame cntr\n", etd.txmac.dropframe_cntr); 130 printf ("\t%d\t : Tx jabber frame cntr\n", etd.txmac.jabberframe_cntr); 131 printf ("\t%d\t : Tx fcs err cntr\n", etd.txmac.fcserr_cntr); 132 printf ("\t%d\t : Tx control frame cntr\n", etd.txmac.ctrlframe_cntr); 133 printf ("\t%d\t : Tx oversize frame cntr\n", etd.txmac.oz_frame_cntr); 134 printf ("\t%d\t : Tx undersize frame cntr\n", etd.txmac.us_frame_cntr); 135 printf ("\t%d\t : Tx fragments frame cntr\n", etd.txmac.frag_frame_cntr); 136 137} 138static void rx_mac_stats (void) 139{ 140 printf ("\n\n%s\n", __func__); 141 printf ("\t%d\t: Rx byte cntr\n", etd.rxmac.byte_cntr); 142 printf ("\t%d\t: Rx pkt cntr\n", etd.rxmac.pkt_cntr); 143 printf ("\t%d\t: Rx fcs err cntr\n", etd.rxmac.fcserr_cntr); 144 printf ("\t%d\t: Rx mcast pkt cntr\n", etd.rxmac.mcast_cntr); 145 printf ("\t%d\t: Rx bcast pkt cntr\n", etd.rxmac.bcast_cntr); 146 printf ("\t%d\t: Rx ctrl frame cntr\n", etd.rxmac.ctrlframe_cntr); 147 printf ("\t%d\t: Rx pause frame pkt cntr\n", etd.rxmac.pausefr_cntr); 148 printf ("\t%d\t: Rx unknown opcode cntr\n", etd.rxmac.unknownop_cntr); 149 printf ("\t%d\t: Rx alignment err cntr\n", etd.rxmac.allignerr_cntr); 150 printf ("\t%d\t: Rx frame length err cntr\n", etd.rxmac.framelerr_cntr); 151 printf ("\t%d\t: Rx code err cntr\n", etd.rxmac.codeerr_cntr); 152 printf ("\t%d\t: Rx carrier sense err cntr\n", etd.rxmac.carriersenseerr_cntr); 153 printf ("\t%d\t: Rx under sz pkt cntr\n", etd.rxmac.underszpkt_cntr); 154 printf ("\t%d\t: Rx over sz pkt cntr\n", etd.rxmac.ozpkt_cntr); 155 printf ("\t%d\t: Rx fragment cntr\n", etd.rxmac.fragment_cntr); 156 printf ("\t%d\t: Rx jabber cntr\n", etd.rxmac.jabber_cntr); 157 printf ("\t%d\t: RX drop cntr\n",etd.rxmac.rcvdrop_cntr); 158 printf ("\t%u\t: Rx overfl cntr\n",etd.rxmac.rxoverfl); 159 160} 161 162 163 164u_int32_t 165regread(u_int32_t phy_reg,u_int16_t portno) 166{ 167 168 etd.phy_reg = phy_reg; 169 etd.cmd = ATHR_PHY_RD; 170 etd.portnum = portno; 171 if (ioctl(s,ATHR_PHY_CTRL_IOC, &ifr) < 0) 172 err(1, etd.ad_name); 173 return etd.val; 174} 175static void athr_en_jumboframe(int value) 176{ 177 etd.cmd = ATHR_JUMBO_FRAME; 178 etd.val=value; 179 if (ioctl(s,ATHR_GMAC_CTRL_IOC, &ifr) < 0) 180 err(1,etd.ad_name); 181} 182static void athr_set_framesize(int sz) 183{ 184 etd.cmd = ATHR_FRAME_SIZE_CTL; 185 etd.val = sz; 186 if (ioctl(s,ATHR_GMAC_CTRL_IOC, &ifr) < 0) 187 err(1,etd.ad_name); 188 189} 190static void athr_commit_acl_rules(void) 191{ 192 etd.cmd = ATHR_ACL_COMMIT; 193 if (ioctl(s,ATHR_HW_ACL_IOC,&ifr) < 0) 194 err(1,etd.ad_name); 195 196} 197static void athr_flush_acl_rules(void) 198{ 199 etd.cmd = ATHR_ACL_FLUSH; 200 if (ioctl(s,ATHR_HW_ACL_IOC,&ifr) < 0) 201 err(1,etd.ad_name); 202} 203static void athr_flow_link (int portno, int val) 204{ 205 etd.cmd = ATHR_FLOW_LINK_EN; 206 etd.val = val; 207 etd.portnum = portno; 208 if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0) 209 err(1,etd.ad_name); 210} 211static void athr_txflctrl (int portno, int val) 212{ 213 if (portno == 0x3f) { 214 etd.val = val; 215 etd.cmd = ATHR_GMAC_TX_FLOW_CTRL; 216 if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0) 217 printf("%s ioctl error\n",__func__); 218 219 } else { 220 etd.cmd = ATHR_PHY_TXFCTL; 221 etd.portnum = portno; 222 etd.val = val; 223 if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0) 224 printf("%s ioctl error\n",__func__); 225 226 } 227 228 229} 230static void athr_gmac_flow_ctrl(int val) 231{ 232 etd.val = val; 233 etd.cmd = ATHR_GMAC_FLOW_CTRL; 234 if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0) 235 printf("%s ioctl error\n",__func__); 236 237} 238static void athr_phy_flow_ctrl(int val, int portno) 239{ 240 etd.val = val; 241 etd.cmd = ATHR_PHY_FLOW_CTRL; 242 etd.portnum = portno; 243 if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0) 244 printf("%s ioctl error\n",__func__); 245} 246static void athr_rxflctrl (int portno, int val) 247{ 248 if (portno == 0x3f) { 249 etd.val = val; 250 etd.cmd = ATHR_GMAC_RX_FLOW_CTRL; 251 if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0) 252 printf("%s ioctl error\n",__func__); 253 254 } else { 255 etd.cmd = ATHR_PHY_RXFCTL; 256 etd.portnum = portno; 257 etd.val = val; 258 if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0) 259 printf("%s ioctl error\n",__func__); 260 261 } 262 263 264} 265static void athr_set_mib(int val) 266{ 267 etd.cmd = ATHR_PHY_MIB; 268 etd.portnum = 0x3f; 269 etd.val = val; 270 if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0) 271 err(1, etd.ad_name); 272} 273static void athr_disp_stats(int portno) 274{ 275 if (portno == 0x3f) { 276 etd.cmd = ATHR_GMAC_STATS; 277 if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0){ 278 err(1, etd.ad_name); 279 } else { 280 rx_mac_stats (); 281 tx_mac_stats (); 282 283 } 284 285 } else { 286 etd.cmd = ATHR_PHY_STATS; 287 etd.portnum = portno; 288 if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0) 289 err(1, etd.ad_name); 290 else{ 291 rx_stats (); 292 tx_stats (); 293 294 } 295 } 296 297} 298static void athr_dma_check(int val) 299{ 300 etd.cmd = ATHR_GMAC_DMA_CHECK; 301 etd.val = val; 302 if (ioctl (s, ATHR_GMAC_CTRL_IOC, &ifr) < 0) 303 err(1, etd.ad_name); 304 305} 306 307static void athr_set_qos(int val) 308{ 309 etd.cmd = ATHR_QOS_ETH_SOFT_CLASS; 310 etd.val = val; 311 if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0) 312 err (1, etd.ad_name); 313} 314static void athr_set_port_pri(int portno, int val) 315{ 316 etd.cmd = ATHR_QOS_ETH_PORT; 317 etd.portnum = portno; 318 etd.val = val; 319 if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0) 320 err (1, etd.ad_name); 321 322} 323static void athr_ip_qos (int tos, int val) 324{ 325 etd.cmd = ATHR_QOS_ETH_IP; 326 etd.val = val; 327 etd.tos = tos; 328 if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0) 329 err (1, etd.ad_name); 330 331} 332static void athr_vlan_qos (int vlan_id, int val) 333{ 334 etd.cmd = ATHR_QOS_ETH_VLAN; 335 etd.val = val; 336 etd.vlanid = vlan_id; 337 if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0) 338 err (1, etd.ad_name); 339 340} 341static void athr_mac_qos(int portno, int val, char *mac_addr) 342{ 343 etd.cmd = ATHR_QOS_ETH_DA; 344 etd.val = val; 345 etd.portnum = portno; 346 sscanf (mac_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", 347 &etd.mac_addr[0], &etd.mac_addr[1], 348 &etd.mac_addr[2], &etd.mac_addr[3], 349 &etd.mac_addr[4], &etd.mac_addr[5]); 350 if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0) 351 err (1, etd.ad_name); 352 353} 354 355static int athr_port_st(int portno) 356{ 357 char str[][MAX_SIZ] = {"10Mbps","100Mbps","1000Mbps"}; 358 359 etd.cmd = ATHR_PORT_STATS; 360 etd.portnum = portno; 361 if (etd.portnum > 5){ 362 printf ("port usage <0-5>"); 363 return -EINVAL; 364 } 365 if (ioctl (s, ATHR_PHY_CTRL_IOC, &ifr) < 0) 366 err (1, etd.ad_name); 367 printf("\t\t\t____phy%d stats____\n",etd.portnum); 368 printf("Link:\t\t%s\n",etd.phy_st.link ? "alive":"Not alive"); 369 printf("Speed:\t\t%s\n",str[etd.phy_st.speed]); 370 printf("Duplex:\t\t%s\n",etd.phy_st.duplex ? "Full duplex":"Half-duplex"); 371 printf("Rx flowctrl:\t%s\n",etd.phy_st.rxflctrl ? "Enabled": "Disabled"); 372 printf("Tx flowctrl:\t%s\n",etd.phy_st.txflctrl ? "Enabled": "Disabled"); 373 return 0; 374 375} 376static void athr_process_egress(int portno, int val) 377{ 378 etd.cmd = ATHR_QOS_PORT_ELIMIT; 379 etd.val = val; 380 etd. portnum = portno; 381 if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0) 382 err (1, etd.ad_name); 383 384} 385static void athr_process_igress(int portno, int val) 386{ 387 etd.cmd = ATHR_QOS_PORT_ILIMIT; 388 etd.val = val; 389 etd. portnum = portno; 390 if (ioctl (s, ATHR_GMAC_QOS_CTRL_IOC, &ifr) < 0) 391 err (1, etd.ad_name); 392 393} 394 395 396static void regwrite(u_int32_t phy_reg,u_int32_t val,u_int16_t portno) 397{ 398 399 etd.val = val; 400 etd.phy_reg = phy_reg; 401 etd.portnum = portno; 402 if(opt_force) { 403 etd.duplex = duplex; 404 etd.cmd = ATHR_PHY_FORCE; 405 if (ioctl(s,ATHR_PHY_CTRL_IOC, &ifr) < 0) 406 err(1, etd.ad_name); 407 opt_force = 0; 408 } 409 else { 410 etd.cmd = ATHR_PHY_WR; 411 if (ioctl(s,ATHR_PHY_CTRL_IOC, &ifr) < 0) 412 err(1, etd.ad_name); 413 } 414} 415 416static void usage(void) 417{ 418 fprintf(stderr, "usage: %s [-i ifname] [-p portnum] offset[=value]\n", progname); 419 fprintf(stderr, "usage: %s [-f] -p portnum =10/100/0 [-d duplex]\n", progname); 420 fprintf(stderr, "usage: %s [-i ifname][-x]\n", progname); 421 fprintf(stderr, "usage: %s [-i ifname][-c]\n", progname); 422 fprintf(stderr, "usage: %s [-i ifname][-s value]\n", progname); 423 fprintf(stderr, "usage: %s [-i ifname][-j 0|1]\n", progname); 424 fprintf(stderr, "usage: %s [--txfctl] [-i ifname] -v [0|1]\n", progname); 425 fprintf(stderr, "usage: %s [--txfctl] [-i ifname] -v [0|1] -p <portno>\n", progname); 426 fprintf(stderr, "usage: %s [--rxfctl] [-i ifname] -v [0|1]\n",progname); 427 fprintf(stderr, "usage: %s [--rxfctl] [-i ifname] -v [0|1] -p <portno>\n", progname); 428 fprintf(stderr, "usage: %s [--macfl] [-i ifname] -v [0|1]\n", progname); 429 fprintf(stderr, "usage: %s [--swfl] [-i ifname] -v [0|1]\n", progname); 430 fprintf(stderr, "usage: %s [--dma] [-i ifname] -v [0|1]\n", progname); 431 fprintf(stderr, "usage: %s [--f_link] [-i ifname] -v [0|1]\n", progname); 432 fprintf(stderr, "usage: %s [--mib] [-i ifname] -v [0|1]\n", progname); 433 fprintf(stderr, "usage: %s [--stats] [-i ifname]\n", progname); 434 fprintf(stderr, "usage: %s [--stats] [-i ifname] -p <portno>\n", progname); 435 fprintf(stderr, "usage: %s [--qos] [-i ifname] -v [0|1]\n", progname); 436 fprintf(stderr, "usage: %s [--ipqos] [-i ifname] -t <tos> -v <val>\n", progname); 437 fprintf(stderr, "usage: %s [--vqos] [-i ifname] -l <vlanid> -v <val>\n", progname); 438 fprintf(stderr, "usage: %s [--mqos [-i ifname] -v <val> -p <portnum> -m <macaddr>\n", progname); 439 fprintf(stderr, "usage: %s [--p_st] [-i ifname] -p <portno>\n", progname); 440 fprintf(stderr, "usage: %s [--igrl] [-i ifname] -p <portno> -v <val>\n", progname); 441 fprintf(stderr, "usage: %s [--egrl] [-i ifname] -p <portno> -v <val>\n", progname); 442 fprintf(stderr, "usage: %s [-i ifname][-s value]\n",progname); 443 fprintf(stderr, "usage: %s [-i ifname][-j 0|1]\n",progname); 444 exit(-1); 445} 446 447 448int 449ethreg_main(int argc, char *argv[]) 450{ 451 const char *ifname = "eth0"; 452 int c,portnum = 0x3f,cmd = 0,value = -1; 453 int optionindex = 0; 454 int vlanid = 0; 455 char *mac = NULL; 456 int tos = -1; 457 char *opt = "xfhci:d:s:j:v:t:p:m:l:"; 458 459 s = socket(AF_INET, SOCK_DGRAM, 0); 460 if (s < 0) 461 err(1, "socket"); 462 463 opt_force = 0; 464 progname = argv[0]; 465 466 467 struct option long_options[] = 468 { 469 { "f_link", no_argument, 0, ATHR_FLOW_LINK_EN}, 470 { "txfctl", no_argument, 0, ATHR_PHY_TXFCTL}, 471 { "rxfctl", no_argument, 0, ATHR_PHY_RXFCTL}, 472 { "stats" , no_argument, 0, ATHR_GMAC_STATS}, 473 { "mib" , no_argument, 0, ATHR_PHY_MIB}, 474 { "dma" , no_argument, 0, ATHR_GMAC_DMA_CHECK}, 475 { "qos" , no_argument, 0, ATHR_QOS_ETH_SOFT_CLASS}, 476 { "ppri" , no_argument, 0, ATHR_QOS_ETH_PORT}, 477 { "ipqos" , no_argument, 0, ATHR_QOS_ETH_IP}, 478 { "vqos" , no_argument, 0, ATHR_QOS_ETH_VLAN}, 479 { "mqos" , no_argument, 0, ATHR_QOS_ETH_DA}, 480 { "igrl" , no_argument, 0, ATHR_QOS_PORT_ELIMIT}, 481 { "egrl" , no_argument, 0, ATHR_QOS_PORT_ILIMIT}, 482 { "p_st" , no_argument, 0, ATHR_PORT_STATS}, 483 { "macfl" , no_argument, 0, ATHR_GMAC_FLOW_CTRL}, 484 { "swfl" , no_argument, 0, ATHR_PHY_FLOW_CTRL}, 485 { 0,0,0,0} 486 }; 487 488 489 while ((c = getopt_long(argc, argv, 490 opt, long_options, &optionindex)) != -1) { 491 switch (c) { 492 case ATHR_FLOW_LINK_EN: 493 cmd = ATHR_FLOW_LINK_EN; 494 break; 495 case ATHR_PHY_TXFCTL: 496 cmd = ATHR_PHY_TXFCTL; 497 break; 498 case ATHR_PHY_RXFCTL: 499 cmd = ATHR_PHY_RXFCTL; 500 break; 501 case ATHR_PHY_MIB: 502 cmd = ATHR_PHY_MIB; 503 break; 504 case ATHR_GMAC_STATS: 505 cmd = ATHR_GMAC_STATS; 506 break; 507 case ATHR_GMAC_DMA_CHECK: 508 cmd = ATHR_GMAC_DMA_CHECK; 509 break; 510 case ATHR_QOS_ETH_SOFT_CLASS: 511 cmd = ATHR_QOS_ETH_SOFT_CLASS; 512 break; 513 case ATHR_QOS_ETH_PORT: 514 cmd = ATHR_QOS_ETH_PORT; 515 break; 516 case ATHR_QOS_ETH_VLAN: 517 cmd = ATHR_QOS_ETH_VLAN; 518 break; 519 case ATHR_QOS_ETH_IP: 520 cmd = ATHR_QOS_ETH_IP; 521 break; 522 case ATHR_QOS_ETH_DA: 523 cmd = ATHR_QOS_ETH_DA; 524 break; 525 case ATHR_PORT_STATS: 526 cmd = ATHR_PORT_STATS; 527 break; 528 case ATHR_QOS_PORT_ELIMIT: 529 cmd = ATHR_QOS_PORT_ELIMIT; 530 break; 531 case ATHR_QOS_PORT_ILIMIT: 532 cmd = ATHR_QOS_PORT_ILIMIT; 533 break; 534 case ATHR_GMAC_FLOW_CTRL: 535 cmd = ATHR_GMAC_FLOW_CTRL; 536 break; 537 case ATHR_PHY_FLOW_CTRL: 538 cmd = ATHR_PHY_FLOW_CTRL; 539 break; 540 case 'm': 541 mac = optarg; 542 break; 543 case 'v': 544 value = strtoul(optarg, 0, 0); 545 break; 546 case 'i': 547 ifname = optarg; 548 break; 549 case 't': 550 tos = strtoul(optarg, 0, 0); 551 break; 552 case 'p': 553 portnum = strtoul(optarg, 0, 0); 554 break; 555 case 'f': 556 opt_force = 1; 557 break; 558 case 'd': 559 duplex = strtoul(optarg, 0, 0); 560 break; 561 case 'c': 562 cmd = ATHR_ACL_COMMIT; 563 break; 564 case 'x': 565 cmd = ATHR_ACL_FLUSH; 566 break; 567 case 's': 568 cmd = ATHR_FRAME_SIZE_CTL; 569 value = strtoul(optarg, 0, 0); 570 break; 571 case 'j': 572 cmd = ATHR_JUMBO_FRAME; 573 value = strtoul(optarg, 0, 0); 574 break; 575 case 'l': 576 vlanid = strtoul (optarg, 0, 0); 577 break; 578 case 'h': 579 usage(); 580 break; 581 default: 582 usage(); 583 /*NOTREACHED*/ 584 } 585 586 } 587 588 argc -= optind; 589 argv += optind; 590 strncpy(etd.ad_name, ifname, sizeof (etd.ad_name)); 591 strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 592 ifr.ifr_data = (void *) &etd; 593 594 if (cmd == ATHR_ACL_COMMIT) { 595 athr_commit_acl_rules(); 596 return 0; 597 } 598 else if (cmd == ATHR_ACL_FLUSH) { 599 athr_flush_acl_rules(); 600 return 0; 601 } 602 else if(cmd == ATHR_FRAME_SIZE_CTL) { 603 if (value == -1) { 604 printf ("usage:ethreg -i <if_name> -s <val>\n"); 605 return -1; 606 } else { 607 athr_set_framesize(value); 608 } 609 return 0; 610 } 611 else if (cmd == ATHR_JUMBO_FRAME) { 612 if (value == -1) { 613 printf ("usage: ethreg -i <if_name> -j <0|1>\n"); 614 return -1; 615 } else { 616 athr_en_jumboframe(value); 617 } 618 return 0; 619 } 620 else if (cmd == ATHR_FLOW_LINK_EN) { 621 if (value == -1 || portnum == 0x3f) { 622 printf ("usage: ethreg --f_link -i <ifname> -p <portnum> -v 1\n"); 623 return -1; 624 } else { 625 athr_flow_link(portnum, value); 626 } 627 return 0; 628 } 629 else if (cmd == ATHR_PHY_RXFCTL) { 630 if (value == -1) { 631 printf ("usage: ethreg --rxfctl -i <ifname> -p <portnum> -v [0|1]\n"); 632 printf ("usage: ethreg --rxfctl -i <ifname> -v [0|1]\n"); 633 return -1; 634 } else { 635 athr_rxflctrl(portnum, value); 636 } 637 return 0; 638 } 639 else if (cmd == ATHR_PHY_TXFCTL) { 640 if (value == -1) { 641 printf ("usage: ethreg --txfctl -i <ifname> -p <portnum> -v [0|1]\n"); 642 printf ("usage: ethreg --txfctl -i <ifname> -v [0|1]\n"); 643 return -1; 644 } else { 645 athr_txflctrl(portnum, value); 646 } 647 return 0; 648 } 649 else if (cmd == ATHR_PHY_MIB) { 650 if (value == -1) { 651 printf ("usage: ethreg --mib -i <ifname> -v 1\n"); 652 return -1; 653 } else { 654 athr_set_mib(value); 655 } 656 return 0; 657 } 658 else if (cmd == ATHR_GMAC_STATS) { 659 athr_disp_stats(portnum); 660 return 0; 661 } 662 else if (cmd == ATHR_GMAC_DMA_CHECK) { 663 if (value == -1) { 664 printf ("usage: ethreg --dma -i <ifname> -v [0|1]\n"); 665 return -1; 666 } else { 667 athr_dma_check(value); 668 } 669 return 0; 670 } 671 else if (cmd == ATHR_QOS_ETH_SOFT_CLASS) { 672 if (value == -1) { 673 printf ("usage: ethreg --qos -i <ifname> -v [0|1]\n"); 674 return -1; 675 } else { 676 athr_set_qos(value); 677 } 678 return 0; 679 680 } 681 else if (cmd == ATHR_QOS_ETH_PORT) { 682 if (value == -1) { 683 printf("usage: ethreg --ppri -i <ifname> -p <portno> -v <val>\n"); 684 return -1; 685 } else { 686 athr_set_port_pri(portnum, value); 687 } 688 return 0; 689 } 690 else if (cmd == ATHR_QOS_ETH_IP) { 691 if (tos == -1 || value == -1) { 692 printf ("usage: ethreg --ipqos -i <ifname> -v <val> -t <tos>\n"); 693 return -1; 694 } else { 695 athr_ip_qos(tos, value); 696 } 697 return 0; 698 } 699 else if (cmd == ATHR_QOS_ETH_VLAN) { 700 if (value == -1 || vlanid == -1) { 701 printf ("usage: ethreg --vqos -i <ifname> -v <val> -l <vlanid>\n"); 702 return -1; 703 } else { 704 athr_vlan_qos(vlanid, value); 705 706 } 707 return 0; 708 } 709 else if (cmd == ATHR_QOS_ETH_DA) { 710 if (portnum == 0x3f || value == -1 || mac == NULL) { 711 printf ("usage: ethreg --mqos -i <ifname> -v <val> -p <portnum> -m <macaddr>\n"); 712 return -1; 713 } else { 714 athr_mac_qos(portnum, value, mac); 715 } 716 return 0; 717 } 718 else if (cmd == ATHR_PORT_STATS) { 719 if (portnum == 0x3f) { 720 printf ("usage: ethreg --port_st -i <ifname> -p <portno>\n"); 721 return -1; 722 } else { 723 athr_port_st(portnum); 724 } 725 return 0; 726 } 727 else if (cmd == ATHR_QOS_PORT_ELIMIT) { 728 if (portnum == 0x3f || value == -1 ) { 729 printf("usage: ethreg --egrl -i <ifname> -p <portnum> -v <val>\n"); 730 return -1; 731 } else { 732 athr_process_egress(portnum, value); 733 } 734 return 0; 735 } 736 else if (cmd == ATHR_QOS_PORT_ILIMIT) { 737 if (portnum == 0x3f || value == -1 ) { 738 printf("usage: ethreg --igrl -i <ifname> -p <portnum> -v <val>\n"); 739 return -1; 740 } else { 741 athr_process_igress(portnum, value); 742 } 743 return 0; 744 } 745 else if (cmd == ATHR_GMAC_FLOW_CTRL){ 746 athr_gmac_flow_ctrl(value); 747 return 0; 748 } 749 else if (cmd == ATHR_PHY_FLOW_CTRL){ 750 athr_phy_flow_ctrl(value, portnum); 751 return 0; 752 } 753 754 for (; argc > 0; argc--, argv++) { 755 u_int32_t off; 756 u_int32_t val, oval; 757 char *cp; 758 759 cp = strchr(argv[0], '='); 760 761 if (cp != NULL) 762 *cp = '\0'; 763 764 off = (u_int) strtoul(argv[0], 0, 0); 765 766 if (off == 0 && errno == EINVAL) 767 errx(1, "%s: invalid reg offset %s", 768 progname, argv[0]); 769 770 if (cp == NULL) { 771 val = regread(off,portnum); 772 printf("Read Reg: 0x%08x = 0x%08x\n",off, val); 773 return 0; 774 } else { 775 val = (u_int32_t) strtoul(cp+1, 0, 0); 776 if (val == 0 && errno == EINVAL) { 777 errx(1, "%s: invalid reg value %s", 778 progname, cp+1); 779 } 780 else { 781 oval = regread(off,portnum); 782 if(opt_force == 0) { 783 printf("Write Reg: 0x%08x: Oldval = 0x%08x Newval = 0x%08x\n", off, oval, val); 784 785 } else if(opt_force == 1 && portnum == 0x3f) { 786 fprintf(stderr, "usage: %s [-f] -p portnum =10/100/0 [-d duplex]\n", progname); 787 return -1; 788 } 789 regwrite(off,val,portnum); 790 } 791 } 792 } 793 return 0; 794} 795 796