1/*-
2 * Copyright (c) 2002-2007 Neterion, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 */
28
29#include "xge_info.h"
30
31int
32main( int argc, char *argv[] )
33{
34	int status = EXIT_FAILURE;
35
36	if(argc >= 4) {
37	    if(!((strcmp(argv[2], "getregister")         == 0) ||
38	        (strcmp(argv[2],  "setregister")          == 0) ||
39	        (strcmp(argv[2],  "setbufmode")  == 0))) {
40	        goto out;
41	    }
42	}
43	else {
44	    if(argc != 3) {
45	        goto out;
46	    }
47	    else {
48	        if(!((strcmp(argv[2], "hwstats")       == 0) ||
49	            (strcmp(argv[2],  "pciconf")       == 0) ||
50	            (strcmp(argv[2],  "devconf")       == 0) ||
51	            (strcmp(argv[2],  "registers")     == 0) ||
52	            (strcmp(argv[2],  "version")       == 0) ||
53	            (strcmp(argv[2],  "swstats")       == 0) ||
54	            (strcmp(argv[2],  "drvstats")      == 0) ||
55	            (strcmp(argv[2],  "getbufmode")    == 0) ||
56	            (strcmp(argv[2],  "devstats")      == 0))) {
57	                goto out;
58	            }
59	    }
60	}
61
62	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
63	    printf("Creating socket failed\n");
64	    goto _exit;
65	}
66
67	ifreqp.ifr_addr.sa_family = AF_INET;
68	strcpy(ifreqp.ifr_name, argv[1]);
69
70	if (strcmp(argv[2], "pciconf") == 0)
71	    status = xge_get_pciconf();
72	else if(strcmp(argv[2], "devconf") == 0)
73	    status = xge_get_devconf();
74	else if(strcmp(argv[2], "hwstats") == 0)
75	    status = xge_get_hwstats();
76	else if(strcmp(argv[2], "registers") == 0)
77	    status = xge_get_registers();
78	else if(strcmp(argv[2], "devstats") == 0)
79	    status = xge_get_devstats();
80	else if(strcmp(argv[2], "swstats") == 0)
81	    status = xge_get_swstats();
82	else if(strcmp(argv[2], "drvstats") == 0)
83	    status = xge_get_drvstats();
84	else if(strcmp(argv[2], "version") == 0)
85	    status = xge_get_drv_version();
86	else if(strcmp(argv[2], "getbufmode") == 0)
87	    status = xge_get_buffer_mode();
88	else if(strcmp(argv[2], "getregister") == 0)
89	    status = xge_get_register(argv[3]);
90	else if(strcmp(argv[2], "setregister") == 0)
91	    status = xge_set_register(argv[3], argv[4]);
92	else if(strcmp(argv[2], "setbufmode") == 0)
93	    status = xge_change_buffer_mode(argv[3]);
94	goto _exit;
95
96out:
97	printf("Usage: ");
98	printf("getinfo <INTERFACE> [hwstats] [swstats] [devstats] ");
99	printf("[drvstats] [version] [registers] [getregister offset] ");
100	printf("[setregister offset value] [pciconf] [devconf] [getbufmode] ");
101	printf("[setbufmode]\n");
102	printf("\tINTERFACE   : Interface (nxge0, nxge1, nxge2, ..)   \n");
103	printf("\thwstats     : Prints hardware statistics            \n");
104	printf("\tswstats     : Prints software statistics            \n");
105	printf("\tdevstats    : Prints device statistics              \n");
106	printf("\tdrvstats    : Prints driver statistics              \n");
107	printf("\tversion     : Prints driver version                 \n");
108	printf("\tregisters   : Prints register values                \n");
109	printf("\tgetregister : Read a register                       \n");
110	printf("\tsetregister : Write to a register                   \n");
111	printf("\tpciconf     : Prints PCI configuration space        \n");
112	printf("\tdevconf     : Prints device configuration           \n");
113	printf("\tgetbufmode  : Prints Buffer Mode                    \n");
114	printf("\tsetbufmode  : Changes buffer mode                   \n");
115
116_exit:
117	return status;
118}
119
120/**
121 * xge_get_hwstats
122 * Gets hardware statistics
123 *
124 * Returns EXIT_SUCCESS or EXIT_FAILURE
125 */
126int
127xge_get_hwstats(void)
128{
129	char *hw_stats = NULL, *pci_cfg = NULL;
130	unsigned short device_id;
131	int index    = 0;
132	int status = EXIT_FAILURE;
133
134	buffer_size = GET_OFFSET_STATS(XGE_COUNT_STATS - 1) + 8;
135
136	hw_stats = (char *)malloc(buffer_size);
137	if(!hw_stats) {
138	    printf("Allocating memory for hardware statistics failed\n");
139	    goto _exit;
140	}
141	*hw_stats = XGE_QUERY_STATS;
142	ifreqp.ifr_data = (caddr_t) hw_stats;
143
144	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
145	    printf("Getting hardware statistics failed\n");
146	    goto _exit1;
147	}
148
149	buffer_size = GET_OFFSET_PCICONF(XGE_COUNT_PCICONF - 1) + 8;
150	pci_cfg = (void *)malloc(buffer_size);
151	if(!pci_cfg) {
152	    printf("Allocating memory for PCI configuration failed\n");
153	    goto _exit1;
154	}
155
156	*pci_cfg = XGE_QUERY_PCICONF;
157	ifreqp.ifr_data = (caddr_t)pci_cfg;
158
159	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
160	    printf("Getting pci configuration space failed\n");
161	    goto _exit2;
162	}
163	device_id = *((u16 *)((unsigned char *)pci_cfg +
164	    GET_OFFSET_PCICONF(index)));
165
166	xge_print_hwstats(hw_stats,device_id);
167	status = EXIT_SUCCESS;
168
169_exit2:
170	free(pci_cfg);
171
172_exit1:
173	free(hw_stats);
174
175_exit:
176	return status;
177}
178
179/**
180 * xge_get_pciconf
181 * Gets PCI configuration space
182 *
183 * Returns EXIT_SUCCESS or EXIT_FAILURE
184 */
185int
186xge_get_pciconf(void)
187{
188	char *pci_cfg = NULL;
189	int status = EXIT_FAILURE;
190
191	buffer_size = GET_OFFSET_PCICONF(XGE_COUNT_PCICONF - 1) + 8;
192
193	pci_cfg = (char *)malloc(buffer_size);
194	if(!pci_cfg) {
195	    printf("Allocating memory for PCI configuration failed\n");
196	    goto _exit;
197	}
198
199	*pci_cfg = XGE_QUERY_PCICONF;
200	ifreqp.ifr_data = (caddr_t)pci_cfg;
201
202	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
203	    printf("Getting PCI configuration space failed\n");
204	    goto _exit1;
205	}
206
207	xge_print_pciconf( pci_cfg );
208	status = EXIT_SUCCESS;
209
210_exit1:
211	free(pci_cfg);
212
213_exit:
214	return status;
215}
216
217/**
218 * xge_get_devconf
219 * Gets device configuration
220 *
221 * Returns EXIT_SUCCESS or EXIT_FAILURE
222 */
223int
224xge_get_devconf(void)
225{
226	char *device_cfg = NULL;
227	int status = EXIT_FAILURE;
228
229	buffer_size = XGE_COUNT_DEVCONF * sizeof(int);
230
231	device_cfg = (char *)malloc(buffer_size);
232	if(!device_cfg) {
233	    printf("Allocating memory for device configuration failed\n");
234	    goto _exit;
235	}
236
237	*device_cfg = XGE_QUERY_DEVCONF;
238	ifreqp.ifr_data = (caddr_t)device_cfg;
239
240	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
241	    printf("Getting Device Configuration failed\n");
242	    goto _exit1;
243	}
244
245	xge_print_devconf( device_cfg );
246	status = EXIT_SUCCESS;
247
248_exit1:
249	free(device_cfg);
250
251_exit:
252	return status;
253}
254
255/**
256 * xge_get_buffer_mode
257 * Get current Rx buffer mode
258 *
259 * Return EXIT_SUCCESS or EXIT_FAILURE
260 */
261int
262xge_get_buffer_mode(void)
263{
264	char *buf_mode = NULL;
265	int status = EXIT_FAILURE;
266
267	buf_mode = (char *)malloc(sizeof(int));
268	if(!buf_mode) {
269	    printf("Allocating memory for buffer mode failed\n");
270	    goto _exit;
271	}
272
273	*buf_mode = XGE_QUERY_BUFFER_MODE;
274	ifreqp.ifr_data = (void *)buf_mode;
275
276	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
277	    printf("Getting Buffer Mode failed\n");
278	    goto _exit1;
279	}
280	printf("Rx Buffer Mode: %d\n", *ifreqp.ifr_data);
281	status = EXIT_SUCCESS;
282
283_exit1:
284	free(buf_mode);
285
286_exit:
287	return status;
288}
289
290/**
291 * xge_change_buffer_mode
292 * Change Rx buffer mode
293 *
294 * Returns EXIT_SUCCESS or EXIT_FAILURE
295 */
296int
297xge_change_buffer_mode(char *bufmode)
298{
299	char *print_msg = NULL;
300	int status = EXIT_FAILURE;
301
302	print_msg = (char *)malloc(sizeof(char));
303	if(print_msg == NULL) {
304	    printf("Allocation of memory for message failed\n");
305	    goto _exit;
306	}
307
308	if     (*bufmode == '1') *print_msg = XGE_SET_BUFFER_MODE_1;
309	else if(*bufmode == '2') *print_msg = XGE_SET_BUFFER_MODE_2;
310	else if(*bufmode == '5') *print_msg = XGE_SET_BUFFER_MODE_5;
311	else {
312	     printf("Invalid Buffer mode\n");
313	     goto _exit1;
314	}
315
316	ifreqp.ifr_data = (char *)print_msg;
317	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
318	    printf("Changing buffer mode failed\n");
319	    goto _exit1;
320	}
321
322	if(*print_msg == 'Y') {
323	    printf("Requested buffer mode was already enabled\n");
324	}
325	else if(*print_msg == 'N') {
326	    printf("Requested buffer mode is not implemented OR\n");
327	    printf("Dynamic buffer changing is not supported in this driver\n");
328	}
329	else if(*print_msg == 'C') {
330	    printf("Buffer mode changed to %c\n", *bufmode);
331	}
332	status = EXIT_SUCCESS;
333
334_exit1:
335	free(print_msg);
336
337_exit:
338	return status;
339}
340
341
342/**
343 * xge_get_registers
344 * Gets register values
345 *
346 * Returns EXIT_SUCCESS or EXIT_FAILURE
347 */
348int
349xge_get_registers(void)
350{
351	void *registers = NULL;
352	int status = EXIT_FAILURE;
353
354	buffer_size = regInfo[XGE_COUNT_REGS - 1].offset + 8;
355
356	registers = (void *)malloc(buffer_size);
357	if(!registers) {
358	    printf("Allocating memory for register dump failed\n");
359	    goto _exit;
360	}
361
362	ifreqp.ifr_data = (caddr_t)registers;
363	if(ioctl(sockfd, SIOCGPRIVATE_1, &ifreqp) < 0) {
364	    printf("Getting register values failed\n");
365	    goto _exit1;
366	}
367
368	xge_print_registers(registers);
369	status = EXIT_SUCCESS;
370
371_exit1:
372	free(registers);
373
374_exit:
375	return status;
376}
377
378/**
379 * xge_get_register
380 * Reads a register specified offset
381 *
382 * @offset Offset of register from base address
383 *
384 * Returns EXIT_SUCCESS or EXIT_FAILURE
385 */
386int
387xge_get_register(char *offset)
388{
389	xge_register_info_t *register_info = NULL;
390	int status = EXIT_FAILURE;
391
392	register_info =
393	    (xge_register_info_t *)malloc(sizeof(xge_register_info_t));
394	if(!register_info) {
395	    printf("Allocating memory for register info failed\n");
396	    goto _exit;
397	}
398
399	strcpy(register_info->option, "-r");
400	sscanf(offset, "%x", &register_info->offset);
401	ifreqp.ifr_data = (caddr_t)register_info;
402
403	if(ioctl(sockfd, SIOCGPRIVATE_1, &ifreqp) < 0) {
404	    printf("Reading register failed\n");
405	    goto _exit1;
406	}
407
408	xge_print_register(register_info->offset, register_info->value);
409	status = EXIT_SUCCESS;
410
411_exit1:
412	free(register_info);
413
414_exit:
415	return status;
416}
417
418/**
419 * xge_set_register
420 * Writes to a register specified offset
421 *
422 * @offset Offset of register from base address
423 * @value Value to write to
424 *
425 * Returns EXIT_SUCCESS or EXIT_FAILURE
426 */
427int
428xge_set_register(char *offset, char *value)
429{
430	xge_register_info_t *register_info = NULL;
431	int status = EXIT_FAILURE;
432
433	register_info =
434	    (xge_register_info_t *)malloc(sizeof(xge_register_info_t));
435	if(!register_info) {
436	    printf("Allocating memory for register info failed\n");
437	    goto _exit;
438	}
439
440	strcpy(register_info->option, "-w");
441	sscanf(offset, "%x", &register_info->offset);
442	sscanf(value, "%llx", &register_info->value);
443
444	ifreqp.ifr_data = (caddr_t)register_info;
445	if(ioctl(sockfd, SIOCGPRIVATE_1, &ifreqp) < 0) {
446	    printf("Writing register failed\n");
447	    goto _exit1;
448	}
449	status = EXIT_SUCCESS;
450
451_exit1:
452	free(register_info);
453
454_exit:
455	return status;
456}
457
458/**
459 * xge_get_devstats
460 * Gets device statistics
461 *
462 * Returns EXIT_SUCCESS or EXIT_FAILURE
463 */
464int
465xge_get_devstats(void)
466{
467	char *dev_stats = NULL;
468	int status = EXIT_FAILURE;
469
470	buffer_size = XGE_COUNT_INTRSTAT * sizeof(u32);
471
472	dev_stats = (char *)malloc(buffer_size);
473	if(!dev_stats) {
474	    printf("Allocating memory for device statistics failed\n");
475	    goto _exit;
476	}
477
478	*dev_stats = XGE_QUERY_DEVSTATS;
479	ifreqp.ifr_data = (caddr_t)dev_stats;
480
481	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
482	    printf("Getting device statistics failed\n");
483	    goto _exit1;
484	}
485
486	xge_print_devstats(dev_stats);
487	status = EXIT_SUCCESS;
488
489_exit1:
490	free(dev_stats);
491
492_exit:
493	return status;
494}
495
496/**
497 * xge_get_swstats
498 * Gets software statistics
499 *
500 * Returns EXIT_SUCCESS or EXIT_FAILURE
501 */
502int
503xge_get_swstats(void)
504{
505	char *sw_stats = NULL;
506	int status = EXIT_FAILURE;
507
508	buffer_size = XGE_COUNT_SWSTAT * sizeof(u32);
509
510	sw_stats = (char *) malloc(buffer_size);
511	if(!sw_stats) {
512	    printf("Allocating memory for software statistics failed\n");
513	    goto _exit;
514	}
515
516	*sw_stats = XGE_QUERY_SWSTATS;
517	ifreqp.ifr_data = (caddr_t)sw_stats;
518
519	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
520	    printf("Getting software statistics failed\n");
521	    goto _exit1;
522	}
523
524	xge_print_swstats(sw_stats);
525	status = EXIT_SUCCESS;
526
527_exit1:
528	free(sw_stats);
529
530_exit:
531	return status;
532}
533
534/**
535 * xge_get_drv_version
536 * Gets driver version
537 *
538 * Returns EXIT_SUCCESS or EXIT_FAILURE
539 */
540int
541xge_get_drv_version(void)
542{
543	char  *version = NULL;
544	int status = EXIT_FAILURE;
545
546	buffer_size = 20;
547	version = (char *)malloc(buffer_size);
548	if(!version) {
549	    printf("Allocating memory for driver version failed\n");
550	    goto _exit;
551	}
552
553	*version = XGE_READ_VERSION;
554	ifreqp.ifr_data = ( caddr_t )version;
555
556	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
557	    printf("Getting driver version failed\n");
558	    goto _exit1;
559	}
560	xge_print_drv_version(version);
561	status = EXIT_SUCCESS;
562
563_exit1:
564	free(version);
565
566_exit:
567	return status;
568}
569
570/**
571 * xge_get_drvstats
572 * Gets driver statistics
573 *
574 * Returns EXIT_SUCCESS or EXIT_FAILURE
575 */
576int
577xge_get_drvstats(void)
578{
579	char *driver_stats = NULL;
580	int status = EXIT_FAILURE;
581
582	buffer_size = XGE_COUNT_DRIVERSTATS * sizeof(u64);
583
584	driver_stats = (char *)malloc(buffer_size);
585	if(!driver_stats) {
586	    printf("Allocating memory for driver statistics failed\n");
587	    goto _exit;
588	}
589
590	*driver_stats = XGE_QUERY_DRIVERSTATS;
591	ifreqp.ifr_data = (caddr_t)driver_stats;
592
593	if(ioctl(sockfd, SIOCGPRIVATE_0, &ifreqp) < 0) {
594	    printf("Getting Driver Statistics failed\n");
595	    goto _exit1;
596	}
597
598	xge_print_drvstats(driver_stats);
599	status = EXIT_SUCCESS;
600
601_exit1:
602	free(driver_stats);
603
604_exit:
605	return status;
606}
607