oce_sysctl.c revision 273377
1/*-
2 * Copyright (C) 2013 Emulex
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 are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 *    this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the Emulex Corporation nor the names of its
16 *    contributors may be used to endorse or promote products derived from
17 *    this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Contact Information:
32 * freebsd-drivers@emulex.com
33 *
34 * Emulex
35 * 3333 Susan Street
36 * Costa Mesa, CA 92626
37 */
38
39/* $FreeBSD: head/sys/dev/oce/oce_sysctl.c 273377 2014-10-21 07:31:21Z hselasky $ */
40
41#include "oce_if.h"
42
43static void copy_stats_to_sc_xe201(POCE_SOFTC sc);
44static void copy_stats_to_sc_be3(POCE_SOFTC sc);
45static void copy_stats_to_sc_be2(POCE_SOFTC sc);
46static int  oce_sysctl_loopback(SYSCTL_HANDLER_ARGS);
47static int  oce_sys_aic_enable(SYSCTL_HANDLER_ARGS);
48static int  oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
49static int oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
50static int  oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS);
51static int  oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
52static int oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS);
53static boolean_t oce_phy_flashing_required(POCE_SOFTC sc);
54static boolean_t oce_img_flashing_required(POCE_SOFTC sc, const char *p,
55				int img_optype, uint32_t img_offset,
56				uint32_t img_size, uint32_t hdrs_size);
57static void oce_add_stats_sysctls_be3(POCE_SOFTC sc,
58				struct sysctl_ctx_list *ctx,
59				struct sysctl_oid *stats_node);
60static void oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
61				struct sysctl_ctx_list *ctx,
62				struct sysctl_oid *stats_node);
63
64
65extern char component_revision[32];
66uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
67
68struct flash_img_attri {
69	int img_offset;
70	int img_size;
71	int img_type;
72	bool skip_image;
73	int optype;
74};
75
76void
77oce_add_sysctls(POCE_SOFTC sc)
78{
79
80	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
81	struct sysctl_oid *tree = device_get_sysctl_tree(sc->dev);
82	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
83	struct sysctl_oid *stats_node;
84
85	SYSCTL_ADD_STRING(ctx, child,
86			OID_AUTO, "component_revision",
87			CTLFLAG_RD,
88			component_revision,
89			sizeof(component_revision),
90			"EMULEX One-Connect device driver revision");
91
92	SYSCTL_ADD_STRING(ctx, child,
93			OID_AUTO, "firmware_version",
94			CTLFLAG_RD,
95			sc->fw_version,
96			sizeof(sc->fw_version),
97			"EMULEX One-Connect Firmware Version");
98
99	SYSCTL_ADD_INT(ctx, child,
100			OID_AUTO, "max_rsp_handled",
101			CTLFLAG_RW,
102			&oce_max_rsp_handled,
103			sizeof(oce_max_rsp_handled),
104			"Maximum receive frames handled per interupt");
105
106	if ((sc->function_mode & FNM_FLEX10_MODE) ||
107	    (sc->function_mode & FNM_UMC_MODE))
108		SYSCTL_ADD_UINT(ctx, child,
109				OID_AUTO, "speed",
110				CTLFLAG_RD,
111				&sc->qos_link_speed,
112				0,"QOS Speed");
113	else
114		SYSCTL_ADD_UINT(ctx, child,
115				OID_AUTO, "speed",
116				CTLFLAG_RD,
117				&sc->speed,
118				0,"Link Speed");
119
120	if (sc->function_mode & FNM_UMC_MODE)
121		SYSCTL_ADD_UINT(ctx, child,
122				OID_AUTO, "pvid",
123				CTLFLAG_RD,
124				&sc->pvid,
125				0,"PVID");
126
127	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "loop_back",
128		CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
129		oce_sysctl_loopback, "I", "Loop Back Tests");
130
131	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_upgrade",
132		CTLTYPE_STRING | CTLFLAG_RW, (void *)sc, 0,
133		oce_sys_fwupgrade, "A", "Firmware ufi file");
134
135	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "aic_enable",
136		CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 1,
137		oce_sys_aic_enable, "I", "aic flags");
138
139        /*
140         *  Dumps Transceiver data
141	 *  "sysctl dev.oce.0.sfp_vpd_dump=0"
142         *  "sysctl -x dev.oce.0.sfp_vpd_dump_buffer" for hex dump
143         *  "sysctl -b dev.oce.0.sfp_vpd_dump_buffer > sfp.bin" for binary dump
144         */
145	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "sfp_vpd_dump",
146			CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, oce_sysctl_sfp_vpd_dump,
147			"I", "Initiate a sfp_vpd_dump operation");
148	SYSCTL_ADD_OPAQUE(ctx, child, OID_AUTO, "sfp_vpd_dump_buffer",
149			CTLFLAG_RD, sfp_vpd_dump_buffer,
150			TRANSCEIVER_DATA_SIZE, "IU", "Access sfp_vpd_dump buffer");
151
152	stats_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
153				CTLFLAG_RD, NULL, "Ethernet Statistics");
154
155	if (IS_BE(sc) || IS_SH(sc))
156		oce_add_stats_sysctls_be3(sc, ctx, stats_node);
157	else
158		oce_add_stats_sysctls_xe201(sc, ctx, stats_node);
159
160
161}
162
163
164static uint32_t
165oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type)
166{
167	uint32_t status = 0;
168
169	oce_mbox_cmd_set_loopback(sc, sc->port_id, loopback_type, 1);
170	status = oce_mbox_cmd_test_loopback(sc, sc->port_id, loopback_type,
171				1500, 2, 0xabc);
172	oce_mbox_cmd_set_loopback(sc, sc->port_id, OCE_NO_LOOPBACK, 1);
173
174	return status;
175}
176
177static int
178oce_sys_aic_enable(SYSCTL_HANDLER_ARGS)
179{
180	int value = 0;
181	uint32_t status, vector;
182	POCE_SOFTC sc = (struct oce_softc *)arg1;
183	struct oce_aic_obj *aic;
184
185	status = sysctl_handle_int(oidp, &value, 0, req);
186	if (status || !req->newptr)
187		return status;
188
189	for (vector = 0; vector < sc->intr_count; vector++) {
190		aic = &sc->aic_obj[vector];
191
192		if (value == 0){
193			aic->max_eqd = aic->min_eqd = aic->et_eqd = 0;
194			aic->enable = 0;
195		}
196		else {
197			aic->max_eqd = OCE_MAX_EQD;
198			aic->min_eqd = OCE_MIN_EQD;
199			aic->et_eqd = OCE_MIN_EQD;
200			aic->enable = TRUE;
201		}
202	}
203	return 0;
204}
205
206static int
207oce_sysctl_loopback(SYSCTL_HANDLER_ARGS)
208{
209	int value = 0;
210	uint32_t status;
211	struct oce_softc *sc  = (struct oce_softc *)arg1;
212
213	status = sysctl_handle_int(oidp, &value, 0, req);
214	if (status || !req->newptr)
215		return status;
216
217	if (value != 1) {
218		device_printf(sc->dev,
219			"Not a Valid value. Set to loop_back=1 to run tests\n");
220		return 0;
221	}
222
223	if ((status = oce_loopback_test(sc, OCE_MAC_LOOPBACK))) {
224		device_printf(sc->dev,
225			"MAC Loopback Test = Failed (Error status = %d)\n",
226			 status);
227	} else
228		device_printf(sc->dev, "MAC Loopback Test = Success\n");
229
230	if ((status = oce_loopback_test(sc, OCE_PHY_LOOPBACK))) {
231		device_printf(sc->dev,
232			"PHY Loopback Test = Failed (Error status = %d)\n",
233			 status);
234	} else
235		device_printf(sc->dev, "PHY Loopback Test = Success\n");
236
237	if ((status = oce_loopback_test(sc, OCE_ONE_PORT_EXT_LOOPBACK))) {
238		device_printf(sc->dev,
239			"EXT Loopback Test = Failed (Error status = %d)\n",
240			 status);
241	} else
242		device_printf(sc->dev, "EXT Loopback Test = Success\n");
243
244	return 0;
245}
246
247
248static int
249oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
250{
251	char ufiname[256] = {0};
252	uint32_t status = 1;
253	struct oce_softc *sc  = (struct oce_softc *)arg1;
254	const struct firmware *fw;
255
256	status = sysctl_handle_string(oidp, ufiname, sizeof(ufiname), req);
257	if (status || !req->newptr)
258		return status;
259
260	fw = firmware_get(ufiname);
261	if (fw == NULL) {
262		device_printf(sc->dev, "Unable to get Firmware. "
263			"Make sure %s is copied to /boot/modules\n", ufiname);
264		return ENOENT;
265	}
266
267	if (IS_BE(sc)) {
268		if ((sc->flags & OCE_FLAGS_BE2)) {
269			device_printf(sc->dev,
270				"Flashing not supported for BE2 yet.\n");
271			status = 1;
272			goto done;
273		}
274		status = oce_be3_fwupgrade(sc, fw);
275	} else if (IS_SH(sc)) {
276		status = oce_skyhawk_fwupgrade(sc,fw);
277	} else
278		status = oce_lancer_fwupgrade(sc, fw);
279done:
280	if (status) {
281		device_printf(sc->dev, "Firmware Upgrade failed\n");
282	} else {
283		device_printf(sc->dev, "Firmware Flashed successfully\n");
284	}
285
286	/* Release Firmware*/
287	firmware_put(fw, FIRMWARE_UNLOAD);
288
289	return status;
290}
291
292static void oce_fill_flash_img_data(POCE_SOFTC sc, const struct flash_sec_info * fsec,
293				struct flash_img_attri *pimg, int i,
294				const struct firmware *fw, int bin_offset)
295{
296	if (IS_SH(sc)) {
297		pimg->img_offset = HOST_32(fsec->fsec_entry[i].offset);
298		pimg->img_size   = HOST_32(fsec->fsec_entry[i].pad_size);
299	}
300
301	pimg->img_type = HOST_32(fsec->fsec_entry[i].type);
302	pimg->skip_image = FALSE;
303	switch (pimg->img_type) {
304		case IMG_ISCSI:
305			pimg->optype = 0;
306			if (IS_BE3(sc)) {
307				pimg->img_offset = 2097152;
308				pimg->img_size   = 2097152;
309			}
310			break;
311		case IMG_REDBOOT:
312			pimg->optype = 1;
313			if (IS_BE3(sc)) {
314				pimg->img_offset = 262144;
315				pimg->img_size   = 1048576;
316			}
317			if (!oce_img_flashing_required(sc, fw->data,
318						pimg->optype,
319						pimg->img_offset,
320						pimg->img_size,
321						bin_offset))
322				pimg->skip_image = TRUE;
323			break;
324		case IMG_BIOS:
325			pimg->optype = 2;
326			if (IS_BE3(sc)) {
327				pimg->img_offset = 12582912;
328				pimg->img_size   = 524288;
329			}
330			break;
331		case IMG_PXEBIOS:
332			pimg->optype = 3;
333			if (IS_BE3(sc)) {
334				pimg->img_offset =  13107200;;
335				pimg->img_size   = 524288;
336			}
337			break;
338		case IMG_FCOEBIOS:
339			pimg->optype = 8;
340			if (IS_BE3(sc)) {
341				pimg->img_offset = 13631488;
342				pimg->img_size   = 524288;
343			}
344			break;
345		case IMG_ISCSI_BAK:
346			pimg->optype = 9;
347			if (IS_BE3(sc)) {
348				pimg->img_offset = 4194304;
349				pimg->img_size   = 2097152;
350			}
351			break;
352		case IMG_FCOE:
353			pimg->optype = 10;
354			if (IS_BE3(sc)) {
355				pimg->img_offset = 6291456;
356				pimg->img_size   = 2097152;
357			}
358			break;
359		case IMG_FCOE_BAK:
360			pimg->optype = 11;
361			if (IS_BE3(sc)) {
362				pimg->img_offset = 8388608;
363				pimg->img_size   = 2097152;
364			}
365			break;
366		case IMG_NCSI:
367			pimg->optype = 13;
368			if (IS_BE3(sc)) {
369				pimg->img_offset = 15990784;
370				pimg->img_size   = 262144;
371			}
372			break;
373		case IMG_PHY:
374			pimg->optype = 99;
375			if (IS_BE3(sc)) {
376				pimg->img_offset = 1310720;
377				pimg->img_size   = 262144;
378			}
379			if (!oce_phy_flashing_required(sc))
380				pimg->skip_image = TRUE;
381			break;
382		default:
383			pimg->skip_image = TRUE;
384			break;
385	}
386
387}
388
389static int
390oce_sh_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int32_t num_imgs)
391{
392	char cookie[2][16] =    {"*** SE FLAS", "H DIRECTORY *** "};
393	const char *p = (const char *)fw->data;
394	const struct flash_sec_info *fsec = NULL;
395	struct mbx_common_read_write_flashrom *req;
396	int rc = 0, i, bin_offset = 0, opcode, num_bytes;
397	OCE_DMA_MEM dma_mem;
398	struct flash_img_attri imgatt;
399
400	/* Validate Cookie */
401	bin_offset = (sizeof(struct flash_file_hdr) +
402			(num_imgs * sizeof(struct image_hdr)));
403	p += bin_offset;
404	while (p < ((const char *)fw->data + fw->datasize)) {
405		fsec = (const struct flash_sec_info *)p;
406		if (!memcmp(cookie, fsec->cookie, sizeof(cookie)))
407			break;
408		fsec = NULL;
409		p += 32;
410	}
411
412	if (!fsec) {
413		device_printf(sc->dev,
414				"Invalid Cookie. Firmware image corrupted ?\n");
415		return EINVAL;
416	}
417
418	rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom),
419				&dma_mem, 0);
420	if (rc) {
421		device_printf(sc->dev,
422				"Memory allocation failure while flashing\n");
423		return ENOMEM;
424	}
425	req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom);
426
427	if (IS_SH(sc))
428		num_imgs = HOST_32(fsec->fsec_hdr.num_images);
429	else if (IS_BE3(sc))
430		num_imgs = MAX_FLASH_COMP;
431
432	for (i = 0; i < num_imgs; i++) {
433
434		bzero(&imgatt, sizeof(struct flash_img_attri));
435
436		oce_fill_flash_img_data(sc, fsec, &imgatt, i, fw, bin_offset);
437
438		if (imgatt.skip_image)
439			continue;
440
441		p = fw->data;
442		p = p + bin_offset + imgatt.img_offset;
443
444		if ((p + imgatt.img_size) > ((const char *)fw->data + fw->datasize)) {
445			rc = 1;
446			goto ret;
447		}
448
449		while (imgatt.img_size) {
450
451			if (imgatt.img_size > 32*1024)
452				num_bytes = 32*1024;
453			else
454				num_bytes = imgatt.img_size;
455			imgatt.img_size -= num_bytes;
456
457			if (!imgatt.img_size)
458				opcode = FLASHROM_OPER_FLASH;
459			else
460				opcode = FLASHROM_OPER_SAVE;
461
462			memcpy(req->data_buffer, p, num_bytes);
463			p += num_bytes;
464
465			rc = oce_mbox_write_flashrom(sc, imgatt.optype, opcode,
466					&dma_mem, num_bytes);
467			if (rc) {
468				device_printf(sc->dev,
469						"cmd to write to flash rom failed.\n");
470				rc = EIO;
471				goto ret;
472			}
473			/* Leave the CPU for others for some time */
474			pause("yield", 10);
475
476		}
477
478	}
479
480ret:
481	oce_dma_free(sc, &dma_mem);
482	return rc;
483}
484
485#define UFI_TYPE2		2
486#define UFI_TYPE3		3
487#define UFI_TYPE3R		10
488#define UFI_TYPE4		4
489#define UFI_TYPE4R		11
490static int oce_get_ufi_type(POCE_SOFTC sc,
491			    const struct flash_file_hdr *fhdr)
492{
493	if (fhdr == NULL)
494		goto be_get_ufi_exit;
495
496	if (IS_SH(sc) && fhdr->build[0] == '4') {
497		if (fhdr->asic_type_rev >= 0x10)
498			return UFI_TYPE4R;
499		else
500			return UFI_TYPE4;
501	} else if (IS_BE3(sc) && fhdr->build[0] == '3') {
502		if (fhdr->asic_type_rev == 0x10)
503			return UFI_TYPE3R;
504		else
505			return UFI_TYPE3;
506	} else if (IS_BE2(sc) && fhdr->build[0] == '2')
507		return UFI_TYPE2;
508
509be_get_ufi_exit:
510	device_printf(sc->dev,
511		"UFI and Interface are not compatible for flashing\n");
512	return -1;
513}
514
515
516static int
517oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
518{
519	int rc = 0, num_imgs = 0, i = 0, ufi_type;
520	const struct flash_file_hdr *fhdr;
521	const struct image_hdr *img_ptr;
522
523	fhdr = (const struct flash_file_hdr *)fw->data;
524
525	ufi_type = oce_get_ufi_type(sc, fhdr);
526
527	/* Display flash version */
528	device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]);
529
530	num_imgs = fhdr->num_imgs;
531	for (i = 0; i < num_imgs; i++) {
532		img_ptr = (const struct image_hdr *)((const char *)fw->data +
533				sizeof(struct flash_file_hdr) +
534				(i * sizeof(struct image_hdr)));
535
536		if (img_ptr->imageid != 1)
537			continue;
538
539		switch (ufi_type) {
540			case UFI_TYPE4R:
541				rc = oce_sh_be3_flashdata(sc, fw,
542						num_imgs);
543				break;
544			case UFI_TYPE4:
545				if (sc->asic_revision < 0x10)
546					rc = oce_sh_be3_flashdata(sc, fw,
547								   num_imgs);
548				else {
549					rc = -1;
550					device_printf(sc->dev,
551						"Cant load SH A0 UFI on B0\n");
552				}
553				break;
554			default:
555				rc = -1;
556				break;
557
558		}
559	}
560
561	return rc;
562}
563
564static int
565oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
566{
567	int rc = 0, num_imgs = 0, i = 0;
568	const struct flash_file_hdr *fhdr;
569	const struct image_hdr *img_ptr;
570
571	fhdr = (const struct flash_file_hdr *)fw->data;
572	if (fhdr->build[0] != '3') {
573		device_printf(sc->dev, "Invalid BE3 firmware image\n");
574		return EINVAL;
575	}
576	/* Display flash version */
577	device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]);
578
579	num_imgs = fhdr->num_imgs;
580	for (i = 0; i < num_imgs; i++) {
581		img_ptr = (const struct image_hdr *)((const char *)fw->data +
582				sizeof(struct flash_file_hdr) +
583				(i * sizeof(struct image_hdr)));
584		if (img_ptr->imageid == 1) {
585			rc = oce_sh_be3_flashdata(sc, fw, num_imgs);
586
587			break;
588		}
589	}
590
591	return rc;
592}
593
594
595static boolean_t
596oce_phy_flashing_required(POCE_SOFTC sc)
597{
598	int status = 0;
599	struct oce_phy_info phy_info;
600
601	status = oce_mbox_get_phy_info(sc, &phy_info);
602	if (status)
603		return FALSE;
604
605	if ((phy_info.phy_type == TN_8022) &&
606		(phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
607		return TRUE;
608	}
609
610	return FALSE;
611}
612
613
614static boolean_t
615oce_img_flashing_required(POCE_SOFTC sc, const char *p,
616				int img_optype, uint32_t img_offset,
617				uint32_t img_size, uint32_t hdrs_size)
618{
619	uint32_t crc_offset;
620	uint8_t flashed_crc[4];
621	int status;
622
623	crc_offset = hdrs_size + img_offset + img_size - 4;
624
625	p += crc_offset;
626
627	status = oce_mbox_get_flashrom_crc(sc, flashed_crc,
628			(img_size - 4), img_optype);
629	if (status)
630		return TRUE; /* Some thing worng. ReFlash */
631
632	/*update redboot only if crc does not match*/
633	if (bcmp(flashed_crc, p, 4))
634		return TRUE;
635	else
636		return FALSE;
637}
638
639
640static int
641oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
642{
643
644	int rc = 0;
645	OCE_DMA_MEM dma_mem;
646	const uint8_t *data = NULL;
647	uint8_t *dest_image_ptr = NULL;
648	size_t size = 0;
649	uint32_t data_written = 0, chunk_size = 0;
650	uint32_t offset = 0, add_status = 0;
651
652	if (!IS_ALIGNED(fw->datasize, sizeof(uint32_t))) {
653		device_printf(sc->dev,
654			"Lancer FW image is not 4 byte aligned.");
655		return EINVAL;
656	}
657
658	rc = oce_dma_alloc(sc, 32*1024, &dma_mem, 0);
659	if (rc) {
660		device_printf(sc->dev,
661			"Memory allocation failure while flashing Lancer\n");
662		return ENOMEM;
663	}
664
665	size = fw->datasize;
666	data = fw->data;
667	dest_image_ptr = OCE_DMAPTR(&dma_mem, uint8_t);
668
669	while (size) {
670		chunk_size = MIN(size, (32*1024));
671
672		bcopy(data, dest_image_ptr, chunk_size);
673
674		rc = oce_mbox_lancer_write_flashrom(sc, chunk_size, offset,
675				&dma_mem, &data_written, &add_status);
676
677		if (rc)
678			break;
679
680		size	-= data_written;
681		data	+= data_written;
682		offset	+= data_written;
683		pause("yield", 10);
684
685	}
686
687	if (!rc)
688		/* Commit the firmware*/
689		rc = oce_mbox_lancer_write_flashrom(sc, 0, offset, &dma_mem,
690						&data_written, &add_status);
691	if (rc) {
692		device_printf(sc->dev, "Lancer firmware load error. "
693			"Addstatus = 0x%x, status = %d \n", add_status, rc);
694		rc = EIO;
695	}
696	oce_dma_free(sc, &dma_mem);
697	return rc;
698
699}
700
701
702static void
703oce_add_stats_sysctls_be3(POCE_SOFTC sc,
704				  struct sysctl_ctx_list *ctx,
705				  struct sysctl_oid *stats_node)
706{
707	struct sysctl_oid *rx_stats_node, *tx_stats_node;
708	struct sysctl_oid_list *rx_stat_list, *tx_stat_list;
709	struct sysctl_oid_list *queue_stats_list;
710	struct sysctl_oid *queue_stats_node;
711	struct oce_drv_stats *stats;
712	char prefix[32];
713	int i;
714
715	stats = &sc->oce_stats_info;
716
717	rx_stats_node = SYSCTL_ADD_NODE(ctx,
718					SYSCTL_CHILDREN(stats_node),
719					OID_AUTO,"rx", CTLFLAG_RD,
720					NULL, "RX Ethernet Statistics");
721	rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
722
723
724	SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_pkts",
725			CTLFLAG_RD, &stats->rx.t_rx_pkts,
726			"Total Received Packets");
727	SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_bytes",
728			CTLFLAG_RD, &stats->rx.t_rx_bytes,
729			"Total Received Bytes");
730	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_frags",
731			CTLFLAG_RD, &stats->rx.t_rx_frags, 0,
732			"Total Received Fragements");
733	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_mcast_pkts",
734			CTLFLAG_RD, &stats->rx.t_rx_mcast_pkts, 0,
735			"Total Received Multicast Packets");
736	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_ucast_pkts",
737			CTLFLAG_RD, &stats->rx.t_rx_ucast_pkts, 0,
738			"Total Received Unicast Packets");
739	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_rxcp_errs",
740			CTLFLAG_RD, &stats->rx.t_rxcp_errs, 0,
741			"Total Receive completion errors");
742	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "pause_frames",
743			CTLFLAG_RD, &stats->u0.be.rx_pause_frames, 0,
744			"Pause Frames");
745	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "priority_pause_frames",
746			CTLFLAG_RD, &stats->u0.be.rx_priority_pause_frames, 0,
747			"Priority Pause Frames");
748	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "control_frames",
749			CTLFLAG_RD, &stats->u0.be.rx_control_frames, 0,
750			"Control Frames");
751
752	for (i = 0; i < sc->nrqs; i++) {
753		sprintf(prefix, "queue%d",i);
754		queue_stats_node = SYSCTL_ADD_NODE(ctx,
755						SYSCTL_CHILDREN(rx_stats_node),
756						OID_AUTO, prefix, CTLFLAG_RD,
757						NULL, "Queue name");
758		queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
759
760		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_pkts",
761			CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_pkts,
762			"Receive Packets");
763		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_bytes",
764			CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_bytes,
765			"Recived Bytes");
766		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rx_frags",
767			CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_frags, 0,
768			"Received Fragments");
769		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
770				"rx_mcast_pkts", CTLFLAG_RD,
771				&sc->rq[i]->rx_stats.rx_mcast_pkts, 0,
772					"Received Multicast Packets");
773		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
774				"rx_ucast_pkts", CTLFLAG_RD,
775				&sc->rq[i]->rx_stats.rx_ucast_pkts, 0,
776					"Received Unicast Packets");
777		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rxcp_err",
778			CTLFLAG_RD, &sc->rq[i]->rx_stats.rxcp_err, 0,
779			"Received Completion Errors");
780
781	}
782
783	rx_stats_node = SYSCTL_ADD_NODE(ctx,
784					SYSCTL_CHILDREN(rx_stats_node),
785					OID_AUTO, "err", CTLFLAG_RD,
786					NULL, "Receive Error Stats");
787	rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
788
789	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "crc_errs",
790			CTLFLAG_RD, &stats->u0.be.rx_crc_errors, 0,
791			"CRC Errors");
792	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "pbuf_errors",
793			CTLFLAG_RD, &stats->u0.be.rx_drops_no_pbuf, 0,
794			"Drops due to pbuf full");
795	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "erx_errors",
796			CTLFLAG_RD, &stats->u0.be.rx_drops_no_erx_descr, 0,
797			"ERX Errors");
798	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "alignment_errors",
799			CTLFLAG_RD, &stats->u0.be.rx_drops_too_many_frags, 0,
800			"RX Alignmnet Errors");
801	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "in_range_errors",
802			CTLFLAG_RD, &stats->u0.be.rx_in_range_errors, 0,
803			"In Range Errors");
804	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "out_range_errors",
805			CTLFLAG_RD, &stats->u0.be.rx_out_range_errors, 0,
806			"Out Range Errors");
807	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "frame_too_long",
808			CTLFLAG_RD, &stats->u0.be.rx_frame_too_long, 0,
809			"Frame Too Long");
810	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "address_match_errors",
811			CTLFLAG_RD, &stats->u0.be.rx_address_match_errors, 0,
812			"Address Match Errors");
813	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_small",
814			CTLFLAG_RD, &stats->u0.be.rx_dropped_too_small, 0,
815			"Dropped Too Small");
816	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_short",
817			CTLFLAG_RD, &stats->u0.be.rx_dropped_too_short, 0,
818			"Dropped Too Short");
819	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
820			"dropped_header_too_small", CTLFLAG_RD,
821			&stats->u0.be.rx_dropped_header_too_small, 0,
822			"Dropped Header Too Small");
823	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_tcp_length",
824			CTLFLAG_RD, &stats->u0.be.rx_dropped_tcp_length, 0,
825			"Dropped TCP Length");
826	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_runt",
827			CTLFLAG_RD, &stats->u0.be.rx_dropped_runt, 0,
828			"Dropped runt");
829	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "ip_checksum_errs",
830			CTLFLAG_RD, &stats->u0.be.rx_ip_checksum_errs, 0,
831			"IP Checksum Errors");
832	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "tcp_checksum_errs",
833			CTLFLAG_RD, &stats->u0.be.rx_tcp_checksum_errs, 0,
834			"TCP Checksum Errors");
835	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "udp_checksum_errs",
836			CTLFLAG_RD, &stats->u0.be.rx_udp_checksum_errs, 0,
837			"UDP Checksum Errors");
838	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "fifo_overflow_drop",
839			CTLFLAG_RD, &stats->u0.be.rxpp_fifo_overflow_drop, 0,
840			"FIFO Overflow Drop");
841	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
842			"input_fifo_overflow_drop", CTLFLAG_RD,
843			&stats->u0.be.rx_input_fifo_overflow_drop, 0,
844			"Input FIFO Overflow Drop");
845
846	tx_stats_node = SYSCTL_ADD_NODE(ctx,
847					SYSCTL_CHILDREN(stats_node), OID_AUTO,
848					"tx",CTLFLAG_RD, NULL,
849					"TX Ethernet Statistics");
850	tx_stat_list = SYSCTL_CHILDREN(tx_stats_node);
851
852	SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_pkts",
853			CTLFLAG_RD, &stats->tx.t_tx_pkts,
854			"Total Transmit Packets");
855	SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_bytes",
856			CTLFLAG_RD, &stats->tx.t_tx_bytes,
857			"Total Transmit Bytes");
858	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_reqs",
859			CTLFLAG_RD, &stats->tx.t_tx_reqs, 0,
860			"Total Transmit Requests");
861	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_stops",
862			CTLFLAG_RD, &stats->tx.t_tx_stops, 0,
863			"Total Transmit Stops");
864	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_wrbs",
865			CTLFLAG_RD, &stats->tx.t_tx_wrbs, 0,
866			"Total Transmit WRB's");
867	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_compl",
868			CTLFLAG_RD, &stats->tx.t_tx_compl, 0,
869			"Total Transmit Completions");
870	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO,
871			"total_ipv6_ext_hdr_tx_drop", CTLFLAG_RD,
872			&stats->tx.t_ipv6_ext_hdr_tx_drop, 0,
873			"Total Transmit IPV6 Drops");
874	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "pauseframes",
875			CTLFLAG_RD, &stats->u0.be.tx_pauseframes, 0,
876			"Pause Frames");
877	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "priority_pauseframes",
878			CTLFLAG_RD, &stats->u0.be.tx_priority_pauseframes, 0,
879			"Priority Pauseframes");
880	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "controlframes",
881			CTLFLAG_RD, &stats->u0.be.tx_controlframes, 0,
882			"Tx Control Frames");
883
884	for (i = 0; i < sc->nwqs; i++) {
885		sprintf(prefix, "queue%d",i);
886		queue_stats_node = SYSCTL_ADD_NODE(ctx,
887						SYSCTL_CHILDREN(tx_stats_node),
888						OID_AUTO, prefix, CTLFLAG_RD,
889						NULL, "Queue name");
890		queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
891
892		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_pkts",
893			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_pkts,
894			"Transmit Packets");
895		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_bytes",
896			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_bytes,
897			"Transmit Bytes");
898		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_reqs",
899			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_reqs, 0,
900			"Transmit Requests");
901		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_stops",
902			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_stops, 0,
903			"Transmit Stops");
904		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_wrbs",
905			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_wrbs, 0,
906			"Transmit WRB's");
907		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_compl",
908			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_compl, 0,
909			"Transmit Completions");
910		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
911			"ipv6_ext_hdr_tx_drop",CTLFLAG_RD,
912			&sc->wq[i]->tx_stats.ipv6_ext_hdr_tx_drop, 0,
913			"Transmit IPV6 Ext Header Drop");
914
915	}
916	return;
917}
918
919
920static void
921oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
922				  struct sysctl_ctx_list *ctx,
923				  struct sysctl_oid *stats_node)
924{
925	struct sysctl_oid *rx_stats_node, *tx_stats_node;
926	struct sysctl_oid_list *rx_stat_list, *tx_stat_list;
927	struct sysctl_oid_list *queue_stats_list;
928	struct sysctl_oid *queue_stats_node;
929	struct oce_drv_stats *stats;
930	char prefix[32];
931	int i;
932
933	stats = &sc->oce_stats_info;
934
935	rx_stats_node = SYSCTL_ADD_NODE(ctx,
936					SYSCTL_CHILDREN(stats_node),
937					OID_AUTO, "rx", CTLFLAG_RD,
938					NULL, "RX Ethernet Statistics");
939	rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
940
941
942	SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_pkts",
943			CTLFLAG_RD, &stats->rx.t_rx_pkts,
944			"Total Received Packets");
945	SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_bytes",
946			CTLFLAG_RD, &stats->rx.t_rx_bytes,
947			"Total Received Bytes");
948	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_frags",
949			CTLFLAG_RD, &stats->rx.t_rx_frags, 0,
950			"Total Received Fragements");
951	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_mcast_pkts",
952			CTLFLAG_RD, &stats->rx.t_rx_mcast_pkts, 0,
953			"Total Received Multicast Packets");
954	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_ucast_pkts",
955			CTLFLAG_RD, &stats->rx.t_rx_ucast_pkts, 0,
956			"Total Received Unicast Packets");
957	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_rxcp_errs",
958			CTLFLAG_RD, &stats->rx.t_rxcp_errs, 0,
959			"Total Receive completion errors");
960	SYSCTL_ADD_UQUAD(ctx, rx_stat_list, OID_AUTO, "pause_frames",
961			CTLFLAG_RD, &stats->u0.xe201.rx_pause_frames,
962			"Pause Frames");
963	SYSCTL_ADD_UQUAD(ctx, rx_stat_list, OID_AUTO, "control_frames",
964			CTLFLAG_RD, &stats->u0.xe201.rx_control_frames,
965			"Control Frames");
966
967	for (i = 0; i < sc->nrqs; i++) {
968		sprintf(prefix, "queue%d",i);
969		queue_stats_node = SYSCTL_ADD_NODE(ctx,
970						SYSCTL_CHILDREN(rx_stats_node),
971						OID_AUTO, prefix, CTLFLAG_RD,
972						NULL, "Queue name");
973		queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
974
975		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_pkts",
976			CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_pkts,
977			"Receive Packets");
978		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_bytes",
979			CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_bytes,
980			"Recived Bytes");
981		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rx_frags",
982			CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_frags, 0,
983			"Received Fragments");
984		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
985			"rx_mcast_pkts", CTLFLAG_RD,
986			&sc->rq[i]->rx_stats.rx_mcast_pkts, 0,
987			"Received Multicast Packets");
988		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
989			"rx_ucast_pkts",CTLFLAG_RD,
990			&sc->rq[i]->rx_stats.rx_ucast_pkts, 0,
991			"Received Unicast Packets");
992		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rxcp_err",
993			CTLFLAG_RD, &sc->rq[i]->rx_stats.rxcp_err, 0,
994			"Received Completion Errors");
995
996	}
997
998	rx_stats_node = SYSCTL_ADD_NODE(ctx,
999					SYSCTL_CHILDREN(rx_stats_node),
1000					OID_AUTO, "err", CTLFLAG_RD,
1001					NULL, "Receive Error Stats");
1002	rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
1003
1004	SYSCTL_ADD_UQUAD(ctx, rx_stat_list, OID_AUTO, "crc_errs",
1005			CTLFLAG_RD, &stats->u0.xe201.rx_crc_errors,
1006			"CRC Errors");
1007	SYSCTL_ADD_UQUAD(ctx, rx_stat_list, OID_AUTO, "alignment_errors",
1008			CTLFLAG_RD, &stats->u0.xe201.rx_alignment_errors,
1009			"RX Alignmnet Errors");
1010	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "in_range_errors",
1011			CTLFLAG_RD, &stats->u0.xe201.rx_in_range_errors, 0,
1012			"In Range Errors");
1013	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "out_range_errors",
1014			CTLFLAG_RD, &stats->u0.xe201.rx_out_of_range_errors, 0,
1015			"Out Range Errors");
1016	SYSCTL_ADD_UQUAD(ctx, rx_stat_list, OID_AUTO, "frame_too_long",
1017			CTLFLAG_RD, &stats->u0.xe201.rx_frames_too_long,
1018			"Frame Too Long");
1019	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "address_match_errors",
1020			CTLFLAG_RD, &stats->u0.xe201.rx_address_match_errors, 0,
1021			"Address Match Errors");
1022	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_small",
1023			CTLFLAG_RD, &stats->u0.xe201.rx_dropped_too_small, 0,
1024			"Dropped Too Small");
1025	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_short",
1026			CTLFLAG_RD, &stats->u0.xe201.rx_dropped_too_short, 0,
1027			"Dropped Too Short");
1028	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
1029			"dropped_header_too_small", CTLFLAG_RD,
1030			&stats->u0.xe201.rx_dropped_header_too_small, 0,
1031			"Dropped Header Too Small");
1032	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
1033			"dropped_tcp_length", CTLFLAG_RD,
1034			&stats->u0.xe201.rx_dropped_invalid_tcp_length, 0,
1035			"Dropped TCP Length");
1036	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_runt",
1037			CTLFLAG_RD, &stats->u0.xe201.rx_dropped_runt, 0,
1038			"Dropped runt");
1039	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "ip_checksum_errs",
1040			CTLFLAG_RD, &stats->u0.xe201.rx_ip_checksum_errors, 0,
1041			"IP Checksum Errors");
1042	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "tcp_checksum_errs",
1043			CTLFLAG_RD, &stats->u0.xe201.rx_tcp_checksum_errors, 0,
1044			"TCP Checksum Errors");
1045	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "udp_checksum_errs",
1046			CTLFLAG_RD, &stats->u0.xe201.rx_udp_checksum_errors, 0,
1047			"UDP Checksum Errors");
1048	SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "input_fifo_overflow_drop",
1049			CTLFLAG_RD, &stats->u0.xe201.rx_fifo_overflow, 0,
1050			"Input FIFO Overflow Drop");
1051
1052	tx_stats_node = SYSCTL_ADD_NODE(ctx,
1053					SYSCTL_CHILDREN(stats_node),
1054					OID_AUTO, "tx", CTLFLAG_RD,
1055					NULL, "TX Ethernet Statistics");
1056	tx_stat_list = SYSCTL_CHILDREN(tx_stats_node);
1057
1058	SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_pkts",
1059			CTLFLAG_RD, &stats->tx.t_tx_pkts,
1060			"Total Transmit Packets");
1061	SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_bytes",
1062			CTLFLAG_RD, &stats->tx.t_tx_bytes,
1063			"Total Transmit Bytes");
1064	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_reqs",
1065			CTLFLAG_RD, &stats->tx.t_tx_reqs, 0,
1066			"Total Transmit Requests");
1067	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_stops",
1068			CTLFLAG_RD, &stats->tx.t_tx_stops, 0,
1069			"Total Transmit Stops");
1070	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_wrbs",
1071			CTLFLAG_RD, &stats->tx.t_tx_wrbs, 0,
1072			"Total Transmit WRB's");
1073	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_compl",
1074			CTLFLAG_RD, &stats->tx.t_tx_compl, 0,
1075			"Total Transmit Completions");
1076	SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO,
1077			"total_ipv6_ext_hdr_tx_drop",
1078			CTLFLAG_RD, &stats->tx.t_ipv6_ext_hdr_tx_drop, 0,
1079			"Total Transmit IPV6 Drops");
1080	SYSCTL_ADD_UQUAD(ctx, tx_stat_list, OID_AUTO, "pauseframes",
1081			CTLFLAG_RD, &stats->u0.xe201.tx_pause_frames,
1082			"Pause Frames");
1083	SYSCTL_ADD_UQUAD(ctx, tx_stat_list, OID_AUTO, "controlframes",
1084			CTLFLAG_RD, &stats->u0.xe201.tx_control_frames,
1085			"Tx Control Frames");
1086
1087	for (i = 0; i < sc->nwqs; i++) {
1088		sprintf(prefix, "queue%d",i);
1089		queue_stats_node = SYSCTL_ADD_NODE(ctx,
1090						SYSCTL_CHILDREN(tx_stats_node),
1091						OID_AUTO, prefix, CTLFLAG_RD,
1092						NULL, "Queue name");
1093		queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
1094
1095		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_pkts",
1096			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_pkts,
1097			"Transmit Packets");
1098		SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_bytes",
1099			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_bytes,
1100			"Transmit Bytes");
1101		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_reqs",
1102			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_reqs, 0,
1103			"Transmit Requests");
1104		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_stops",
1105			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_stops, 0,
1106			"Transmit Stops");
1107		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_wrbs",
1108			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_wrbs, 0,
1109			"Transmit WRB's");
1110		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_compl",
1111			CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_compl, 0,
1112			"Transmit Completions");
1113		SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
1114			"ipv6_ext_hdr_tx_drop", CTLFLAG_RD,
1115			&sc->wq[i]->tx_stats.ipv6_ext_hdr_tx_drop, 0,
1116			"Transmit IPV6 Ext Header Drop");
1117
1118	}
1119	return;
1120}
1121
1122
1123void
1124oce_refresh_queue_stats(POCE_SOFTC sc)
1125{
1126	struct oce_drv_stats *adapter_stats;
1127	int i;
1128
1129	adapter_stats = &sc->oce_stats_info;
1130
1131	/* Caluculate total TX and TXstats from all queues */
1132
1133	bzero(&adapter_stats->rx, sizeof(struct oce_rx_stats));
1134	for (i = 0; i < sc->nrqs; i++) {
1135
1136		adapter_stats->rx.t_rx_pkts += sc->rq[i]->rx_stats.rx_pkts;
1137		adapter_stats->rx.t_rx_bytes += sc->rq[i]->rx_stats.rx_bytes;
1138		adapter_stats->rx.t_rx_frags += sc->rq[i]->rx_stats.rx_frags;
1139		adapter_stats->rx.t_rx_mcast_pkts +=
1140					sc->rq[i]->rx_stats.rx_mcast_pkts;
1141		adapter_stats->rx.t_rx_ucast_pkts +=
1142					sc->rq[i]->rx_stats.rx_ucast_pkts;
1143		adapter_stats->rx.t_rxcp_errs += sc-> rq[i]->rx_stats.rxcp_err;
1144	}
1145
1146	bzero(&adapter_stats->tx, sizeof(struct oce_tx_stats));
1147	for (i = 0; i < sc->nwqs; i++) {
1148		adapter_stats->tx.t_tx_reqs += sc->wq[i]->tx_stats.tx_reqs;
1149		adapter_stats->tx.t_tx_stops += sc->wq[i]->tx_stats.tx_stops;
1150		adapter_stats->tx.t_tx_wrbs += sc->wq[i]->tx_stats.tx_wrbs;
1151		adapter_stats->tx.t_tx_compl += sc->wq[i]->tx_stats.tx_compl;
1152		adapter_stats->tx.t_tx_bytes += sc->wq[i]->tx_stats.tx_bytes;
1153		adapter_stats->tx.t_tx_pkts += sc->wq[i]->tx_stats.tx_pkts;
1154		adapter_stats->tx.t_ipv6_ext_hdr_tx_drop +=
1155				sc->wq[i]->tx_stats.ipv6_ext_hdr_tx_drop;
1156	}
1157
1158}
1159
1160
1161
1162static void
1163copy_stats_to_sc_xe201(POCE_SOFTC sc)
1164{
1165	struct oce_xe201_stats *adapter_stats;
1166	struct mbx_get_pport_stats *nic_mbx;
1167	struct pport_stats *port_stats;
1168
1169	nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_pport_stats);
1170	port_stats = &nic_mbx->params.rsp.pps;
1171	adapter_stats = &sc->oce_stats_info.u0.xe201;
1172
1173	adapter_stats->tx_pkts = port_stats->tx_pkts;
1174	adapter_stats->tx_unicast_pkts = port_stats->tx_unicast_pkts;
1175	adapter_stats->tx_multicast_pkts = port_stats->tx_multicast_pkts;
1176	adapter_stats->tx_broadcast_pkts = port_stats->tx_broadcast_pkts;
1177	adapter_stats->tx_bytes = port_stats->tx_bytes;
1178	adapter_stats->tx_unicast_bytes = port_stats->tx_unicast_bytes;
1179	adapter_stats->tx_multicast_bytes = port_stats->tx_multicast_bytes;
1180	adapter_stats->tx_broadcast_bytes = port_stats->tx_broadcast_bytes;
1181	adapter_stats->tx_discards = port_stats->tx_discards;
1182	adapter_stats->tx_errors = port_stats->tx_errors;
1183	adapter_stats->tx_pause_frames = port_stats->tx_pause_frames;
1184	adapter_stats->tx_pause_on_frames = port_stats->tx_pause_on_frames;
1185	adapter_stats->tx_pause_off_frames = port_stats->tx_pause_off_frames;
1186	adapter_stats->tx_internal_mac_errors =
1187		port_stats->tx_internal_mac_errors;
1188	adapter_stats->tx_control_frames = port_stats->tx_control_frames;
1189	adapter_stats->tx_pkts_64_bytes = port_stats->tx_pkts_64_bytes;
1190	adapter_stats->tx_pkts_65_to_127_bytes =
1191		port_stats->tx_pkts_65_to_127_bytes;
1192	adapter_stats->tx_pkts_128_to_255_bytes =
1193		port_stats->tx_pkts_128_to_255_bytes;
1194	adapter_stats->tx_pkts_256_to_511_bytes =
1195		port_stats->tx_pkts_256_to_511_bytes;
1196	adapter_stats->tx_pkts_512_to_1023_bytes =
1197		port_stats->tx_pkts_512_to_1023_bytes;
1198	adapter_stats->tx_pkts_1024_to_1518_bytes =
1199		port_stats->tx_pkts_1024_to_1518_bytes;
1200	adapter_stats->tx_pkts_1519_to_2047_bytes =
1201		port_stats->tx_pkts_1519_to_2047_bytes;
1202	adapter_stats->tx_pkts_2048_to_4095_bytes =
1203		port_stats->tx_pkts_2048_to_4095_bytes;
1204	adapter_stats->tx_pkts_4096_to_8191_bytes =
1205		port_stats->tx_pkts_4096_to_8191_bytes;
1206	adapter_stats->tx_pkts_8192_to_9216_bytes =
1207		port_stats->tx_pkts_8192_to_9216_bytes;
1208	adapter_stats->tx_lso_pkts = port_stats->tx_lso_pkts;
1209	adapter_stats->rx_pkts = port_stats->rx_pkts;
1210	adapter_stats->rx_unicast_pkts = port_stats->rx_unicast_pkts;
1211	adapter_stats->rx_multicast_pkts = port_stats->rx_multicast_pkts;
1212	adapter_stats->rx_broadcast_pkts = port_stats->rx_broadcast_pkts;
1213	adapter_stats->rx_bytes = port_stats->rx_bytes;
1214	adapter_stats->rx_unicast_bytes = port_stats->rx_unicast_bytes;
1215	adapter_stats->rx_multicast_bytes = port_stats->rx_multicast_bytes;
1216	adapter_stats->rx_broadcast_bytes = port_stats->rx_broadcast_bytes;
1217	adapter_stats->rx_unknown_protos = port_stats->rx_unknown_protos;
1218	adapter_stats->rx_discards = port_stats->rx_discards;
1219	adapter_stats->rx_errors = port_stats->rx_errors;
1220	adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
1221	adapter_stats->rx_alignment_errors = port_stats->rx_alignment_errors;
1222	adapter_stats->rx_symbol_errors = port_stats->rx_symbol_errors;
1223	adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
1224	adapter_stats->rx_pause_on_frames = port_stats->rx_pause_on_frames;
1225	adapter_stats->rx_pause_off_frames = port_stats->rx_pause_off_frames;
1226	adapter_stats->rx_frames_too_long = port_stats->rx_frames_too_long;
1227	adapter_stats->rx_internal_mac_errors =
1228		port_stats->rx_internal_mac_errors;
1229	adapter_stats->rx_undersize_pkts = port_stats->rx_undersize_pkts;
1230	adapter_stats->rx_oversize_pkts = port_stats->rx_oversize_pkts;
1231	adapter_stats->rx_fragment_pkts = port_stats->rx_fragment_pkts;
1232	adapter_stats->rx_jabbers = port_stats->rx_jabbers;
1233	adapter_stats->rx_control_frames = port_stats->rx_control_frames;
1234	adapter_stats->rx_control_frames_unknown_opcode =
1235		port_stats->rx_control_frames_unknown_opcode;
1236	adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors;
1237	adapter_stats->rx_out_of_range_errors =
1238		port_stats->rx_out_of_range_errors;
1239	adapter_stats->rx_address_match_errors =
1240		port_stats->rx_address_match_errors;
1241	adapter_stats->rx_vlan_mismatch_errors =
1242		port_stats->rx_vlan_mismatch_errors;
1243	adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small;
1244	adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short;
1245	adapter_stats->rx_dropped_header_too_small =
1246		port_stats->rx_dropped_header_too_small;
1247	adapter_stats->rx_dropped_invalid_tcp_length =
1248		port_stats->rx_dropped_invalid_tcp_length;
1249	adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt;
1250	adapter_stats->rx_ip_checksum_errors =
1251		port_stats->rx_ip_checksum_errors;
1252	adapter_stats->rx_tcp_checksum_errors =
1253		port_stats->rx_tcp_checksum_errors;
1254	adapter_stats->rx_udp_checksum_errors =
1255		port_stats->rx_udp_checksum_errors;
1256	adapter_stats->rx_non_rss_pkts = port_stats->rx_non_rss_pkts;
1257	adapter_stats->rx_ipv4_pkts = port_stats->rx_ipv4_pkts;
1258	adapter_stats->rx_ipv6_pkts = port_stats->rx_ipv6_pkts;
1259	adapter_stats->rx_ipv4_bytes = port_stats->rx_ipv4_bytes;
1260	adapter_stats->rx_ipv6_bytes = port_stats->rx_ipv6_bytes;
1261	adapter_stats->rx_nic_pkts = port_stats->rx_nic_pkts;
1262	adapter_stats->rx_tcp_pkts = port_stats->rx_tcp_pkts;
1263	adapter_stats->rx_iscsi_pkts = port_stats->rx_iscsi_pkts;
1264	adapter_stats->rx_management_pkts = port_stats->rx_management_pkts;
1265	adapter_stats->rx_switched_unicast_pkts =
1266		port_stats->rx_switched_unicast_pkts;
1267	adapter_stats->rx_switched_multicast_pkts =
1268		port_stats->rx_switched_multicast_pkts;
1269	adapter_stats->rx_switched_broadcast_pkts =
1270		port_stats->rx_switched_broadcast_pkts;
1271	adapter_stats->num_forwards = port_stats->num_forwards;
1272	adapter_stats->rx_fifo_overflow = port_stats->rx_fifo_overflow;
1273	adapter_stats->rx_input_fifo_overflow =
1274		port_stats->rx_input_fifo_overflow;
1275	adapter_stats->rx_drops_too_many_frags =
1276		port_stats->rx_drops_too_many_frags;
1277	adapter_stats->rx_drops_invalid_queue =
1278		port_stats->rx_drops_invalid_queue;
1279	adapter_stats->rx_drops_mtu = port_stats->rx_drops_mtu;
1280	adapter_stats->rx_pkts_64_bytes = port_stats->rx_pkts_64_bytes;
1281	adapter_stats->rx_pkts_65_to_127_bytes =
1282		port_stats->rx_pkts_65_to_127_bytes;
1283	adapter_stats->rx_pkts_128_to_255_bytes =
1284		port_stats->rx_pkts_128_to_255_bytes;
1285	adapter_stats->rx_pkts_256_to_511_bytes =
1286		port_stats->rx_pkts_256_to_511_bytes;
1287	adapter_stats->rx_pkts_512_to_1023_bytes =
1288		port_stats->rx_pkts_512_to_1023_bytes;
1289	adapter_stats->rx_pkts_1024_to_1518_bytes =
1290		port_stats->rx_pkts_1024_to_1518_bytes;
1291	adapter_stats->rx_pkts_1519_to_2047_bytes =
1292		port_stats->rx_pkts_1519_to_2047_bytes;
1293	adapter_stats->rx_pkts_2048_to_4095_bytes =
1294		port_stats->rx_pkts_2048_to_4095_bytes;
1295	adapter_stats->rx_pkts_4096_to_8191_bytes =
1296		port_stats->rx_pkts_4096_to_8191_bytes;
1297	adapter_stats->rx_pkts_8192_to_9216_bytes =
1298		port_stats->rx_pkts_8192_to_9216_bytes;
1299}
1300
1301
1302
1303static void
1304copy_stats_to_sc_be2(POCE_SOFTC sc)
1305{
1306	struct oce_be_stats *adapter_stats;
1307	struct oce_pmem_stats *pmem;
1308	struct oce_rxf_stats_v0 *rxf_stats;
1309	struct oce_port_rxf_stats_v0 *port_stats;
1310	struct mbx_get_nic_stats_v0 *nic_mbx;
1311	uint32_t port = sc->port_id;
1312
1313	nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats_v0);
1314	pmem = &nic_mbx->params.rsp.stats.pmem;
1315	rxf_stats = &nic_mbx->params.rsp.stats.rxf;
1316	port_stats = &nic_mbx->params.rsp.stats.rxf.port[port];
1317
1318	adapter_stats = &sc->oce_stats_info.u0.be;
1319
1320
1321	/* Update stats */
1322	adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
1323	adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
1324	adapter_stats->rx_control_frames = port_stats->rx_control_frames;
1325	adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors;
1326	adapter_stats->rx_frame_too_long = port_stats->rx_frame_too_long;
1327	adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt;
1328	adapter_stats->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
1329	adapter_stats->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
1330	adapter_stats->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
1331	adapter_stats->rxpp_fifo_overflow_drop =
1332					port_stats->rxpp_fifo_overflow_drop;
1333	adapter_stats->rx_dropped_tcp_length =
1334		port_stats->rx_dropped_tcp_length;
1335	adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small;
1336	adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short;
1337	adapter_stats->rx_out_range_errors = port_stats->rx_out_range_errors;
1338	adapter_stats->rx_dropped_header_too_small =
1339		port_stats->rx_dropped_header_too_small;
1340	adapter_stats->rx_input_fifo_overflow_drop =
1341		port_stats->rx_input_fifo_overflow_drop;
1342	adapter_stats->rx_address_match_errors =
1343		port_stats->rx_address_match_errors;
1344	adapter_stats->rx_alignment_symbol_errors =
1345		port_stats->rx_alignment_symbol_errors;
1346	adapter_stats->tx_pauseframes = port_stats->tx_pauseframes;
1347	adapter_stats->tx_controlframes = port_stats->tx_controlframes;
1348
1349	if (sc->if_id)
1350		adapter_stats->jabber_events = rxf_stats->port1_jabber_events;
1351	else
1352		adapter_stats->jabber_events = rxf_stats->port0_jabber_events;
1353
1354	adapter_stats->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
1355	adapter_stats->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
1356	adapter_stats->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
1357	adapter_stats->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
1358	adapter_stats->forwarded_packets = rxf_stats->forwarded_packets;
1359	adapter_stats->rx_drops_mtu = rxf_stats->rx_drops_mtu;
1360	adapter_stats->rx_drops_no_tpre_descr =
1361		rxf_stats->rx_drops_no_tpre_descr;
1362	adapter_stats->rx_drops_too_many_frags =
1363		rxf_stats->rx_drops_too_many_frags;
1364	adapter_stats->eth_red_drops = pmem->eth_red_drops;
1365}
1366
1367
1368static void
1369copy_stats_to_sc_be3(POCE_SOFTC sc)
1370{
1371	struct oce_be_stats *adapter_stats;
1372	struct oce_pmem_stats *pmem;
1373	struct oce_rxf_stats_v1 *rxf_stats;
1374	struct oce_port_rxf_stats_v1 *port_stats;
1375	struct mbx_get_nic_stats *nic_mbx;
1376	uint32_t port = sc->port_id;
1377
1378	nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats);
1379	pmem = &nic_mbx->params.rsp.stats.pmem;
1380	rxf_stats = &nic_mbx->params.rsp.stats.rxf;
1381	port_stats = &nic_mbx->params.rsp.stats.rxf.port[port];
1382
1383	adapter_stats = &sc->oce_stats_info.u0.be;
1384
1385	/* Update stats */
1386	adapter_stats->pmem_fifo_overflow_drop =
1387		port_stats->pmem_fifo_overflow_drop;
1388	adapter_stats->rx_priority_pause_frames =
1389		port_stats->rx_priority_pause_frames;
1390	adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
1391	adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
1392	adapter_stats->rx_control_frames = port_stats->rx_control_frames;
1393	adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors;
1394	adapter_stats->rx_frame_too_long = port_stats->rx_frame_too_long;
1395	adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt;
1396	adapter_stats->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
1397	adapter_stats->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
1398	adapter_stats->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
1399	adapter_stats->rx_dropped_tcp_length =
1400		port_stats->rx_dropped_tcp_length;
1401	adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small;
1402	adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short;
1403	adapter_stats->rx_out_range_errors = port_stats->rx_out_range_errors;
1404	adapter_stats->rx_dropped_header_too_small =
1405		port_stats->rx_dropped_header_too_small;
1406	adapter_stats->rx_input_fifo_overflow_drop =
1407		port_stats->rx_input_fifo_overflow_drop;
1408	adapter_stats->rx_address_match_errors =
1409		port_stats->rx_address_match_errors;
1410	adapter_stats->rx_alignment_symbol_errors =
1411		port_stats->rx_alignment_symbol_errors;
1412	adapter_stats->rxpp_fifo_overflow_drop =
1413		port_stats->rxpp_fifo_overflow_drop;
1414	adapter_stats->tx_pauseframes = port_stats->tx_pauseframes;
1415	adapter_stats->tx_controlframes = port_stats->tx_controlframes;
1416	adapter_stats->jabber_events = port_stats->jabber_events;
1417
1418	adapter_stats->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
1419	adapter_stats->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
1420	adapter_stats->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
1421	adapter_stats->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
1422	adapter_stats->forwarded_packets = rxf_stats->forwarded_packets;
1423	adapter_stats->rx_drops_mtu = rxf_stats->rx_drops_mtu;
1424	adapter_stats->rx_drops_no_tpre_descr =
1425		rxf_stats->rx_drops_no_tpre_descr;
1426	adapter_stats->rx_drops_too_many_frags =
1427		rxf_stats->rx_drops_too_many_frags;
1428
1429	adapter_stats->eth_red_drops = pmem->eth_red_drops;
1430}
1431
1432
1433int
1434oce_stats_init(POCE_SOFTC sc)
1435{
1436	int rc = 0, sz;
1437
1438	if (IS_BE(sc) || IS_SH(sc)) {
1439		if (sc->flags & OCE_FLAGS_BE2)
1440			sz = sizeof(struct mbx_get_nic_stats_v0);
1441		else
1442			sz = sizeof(struct mbx_get_nic_stats);
1443	} else
1444		sz = sizeof(struct mbx_get_pport_stats);
1445
1446	rc = oce_dma_alloc(sc, sz, &sc->stats_mem, 0);
1447
1448	return rc;
1449}
1450
1451
1452void
1453oce_stats_free(POCE_SOFTC sc)
1454{
1455
1456	oce_dma_free(sc, &sc->stats_mem);
1457
1458}
1459
1460
1461int
1462oce_refresh_nic_stats(POCE_SOFTC sc)
1463{
1464	int rc = 0, reset = 0;
1465
1466	if (IS_BE(sc) || IS_SH(sc)) {
1467		if (sc->flags & OCE_FLAGS_BE2) {
1468			rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem);
1469			if (!rc)
1470				copy_stats_to_sc_be2(sc);
1471		} else {
1472			rc = oce_mbox_get_nic_stats(sc, &sc->stats_mem);
1473			if (!rc)
1474				copy_stats_to_sc_be3(sc);
1475		}
1476
1477	} else {
1478		rc = oce_mbox_get_pport_stats(sc, &sc->stats_mem, reset);
1479		if (!rc)
1480			copy_stats_to_sc_xe201(sc);
1481	}
1482
1483	return rc;
1484}
1485
1486static int
1487oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS)
1488{
1489	int result = 0, error;
1490	int rc = 0;
1491	POCE_SOFTC sc = (POCE_SOFTC) arg1;
1492
1493	/* sysctl default handler */
1494	error = sysctl_handle_int(oidp, &result, 0, req);
1495	if (error || !req->newptr)
1496		return (error);
1497
1498	if(result == -1) {
1499		return EINVAL;
1500	}
1501	bzero((char *)sfp_vpd_dump_buffer, TRANSCEIVER_DATA_SIZE);
1502
1503	rc = oce_mbox_read_transrecv_data(sc, PAGE_NUM_A0);
1504	if(rc)
1505		return rc;
1506
1507	rc = oce_mbox_read_transrecv_data(sc, PAGE_NUM_A2);
1508	if(rc)
1509		return rc;
1510
1511	return rc;
1512}
1513