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