/******************************************************************************
 *
 *	pm3386_linux_app.c
 *	--------------------
 *	Examples using Linux configuration and status device driver for pm3386
 *	devices. This code is specific to the mthood hardware.
 *
 ******************************************************************************
 *
 *	COPYRIGHT 2003 BY RADISYS CORPORATION.  ALL RIGHTS RESERVED.
 *
 ******************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "pm3386_linux.h"

/*
 * 	Global storage for 2 device handles
 */
static unsigned int	dev0 = 0, dev1 = 0;


/*
 * 	Global storage for 2 user context parameters
 */
static UINT32	usrCtxt0 = 0;
static UINT32	usrCtxt1 = 1;


/*
 * 	Forward declarations
 */
void pm3386Callback( void *usrCtxt, PM3386_INTERRUPTS *pIntr );
void StartMacs();
void StopMacs();
void ShowMac(int);
void ShowMacStats();

static int openPM3386devices()
{
	/* open device */
	dev0 = open("/dev/pm338x0", O_RDWR, 0);
	if( dev0 == -1 ) {
		dev0 = 0;
		return PM3386_DEVICE_NOT_FOUND;
	}

	dev1 = open("/dev/pm338x1", O_RDWR, 0);
		if( dev1 == -1 ) {
			dev1 = 0;
			return PM3386_DEVICE_NOT_FOUND;
	}
	return PM3386_SUCCESS;
}

static void closePM3386devices()
{
	if (dev0) close(dev0);
	if (dev1) close(dev1);
	dev0 = dev1 = 0;
}


/*
 *	StartMacs()
 *	-----------
 *	Init pm3386 driver, open macs, install isr callbacks, and enable rx and tx
 */
void StartMacs( void )
{
	PM3386_STATUS		status;
	PM3386_CHAN_CFG		chanCfg;

	status = openPM3386devices();
	if(status != PM3386_SUCCESS )
	{
		printf("StartMacs: device open failed. Device not found\n");
		exit(-1);
	}

	/* enable rx and tx device 0, chan 0 */
	chanCfg.chan 	= 0;
	chanCfg.val		= 1;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 0, Status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	/* enable rx and tx device 0, chan 0 */
	chanCfg.chan 	= 1;
	chanCfg.val		= 1;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 0, Status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	/* enable rx and tx device 1, chan 0 */
	chanCfg.chan 	= 0;
	chanCfg.val		= 1;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 0, Status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	/* enable rx and tx device 1, chan 0 */
	chanCfg.chan 	= 1;
	chanCfg.val		= 1;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 0, Status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	chanCfg.chan 	= 0;
	chanCfg.val		= 0;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_CRCEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}
	chanCfg.chan 	= 1;
	chanCfg.val		= 0;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_CRCEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	chanCfg.chan 	= 0;
	chanCfg.val		= 0;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_CRCEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}
	chanCfg.chan 	= 1;
	chanCfg.val		= 0;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_CRCEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	chanCfg.chan 	= 0;
	chanCfg.val		= 1;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_PASS_ERR, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}
	chanCfg.chan 	= 1;
	chanCfg.val		= 1;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_PASS_ERR, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	chanCfg.chan 	= 0;
	chanCfg.val		= 1;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_PASS_ERR, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}
	chanCfg.chan 	= 1;
	chanCfg.val		= 1;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_PASS_ERR, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	chanCfg.chan 	= 0;
	chanCfg.val		= 1;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_PASS_CTRL, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}
	chanCfg.chan 	= 1;
	chanCfg.val		= 1;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_PASS_CTRL, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	chanCfg.chan 	= 0;
	chanCfg.val		= 1;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_PASS_CTRL, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}
	chanCfg.chan 	= 1;
	chanCfg.val		= 1;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_PASS_CTRL, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StartMacs: ioctl failed on device 1, Status = 0x%x\n", status);
		exit(-1);
	}

	closePM3386devices();

	printf("PM3386 devices started\n");
}


/*
 *	ShowMac()
 *	-----------
 *	Show all settings for a pm3386 device
 */
void ShowMac( int device )
{
	PM3386_STATUS			status;
	PM3386_HANDLE			dev;
	UINT16					*p0 = NULL;
	UINT16					*p1 = NULL;
	UINT16					data;
	PM3386_CHAN_CFG			chanCfg0, chanCfg1;
	PM3386_CHAN_MAC_ADDR	macAddr0, macAddr1;
	PM3386_CHAN_AMATCH		amatch0, amatch1;
	PM3386_CHAN_VMATCH		vmatch0, vmatch1;
	PM3386_CHAN_MHASH		mhash0, mhash1;
	PM3386_CHAN_FLTR_CTRL	fCtrl0, fCtrl1;
	PM3386_INTERRUPTS		inten;
	int						i;

	status = openPM3386devices();
	if(status != PM3386_SUCCESS )
	{
		printf("ShowMac: device open failed. Device not found\n");
		exit(-1);
	}

	if( device == 0 )
		dev = dev0;
	else if( device == 1 )
		dev = dev1;
	else
	{
		printf("Invalid device number\n");
		return;
	}

	/* set channels */
	chanCfg0.chan 	= 0;
	chanCfg1.chan 	= 1;
	macAddr0.chan 	= 0;
	macAddr1.chan 	= 1;
	amatch0.chan 	= 0;
	amatch1.chan	= 1;
	vmatch0.chan 	= 0;
	vmatch1.chan	= 1;
	mhash0.chan 	= 0;
	mhash1.chan		= 1;
	fCtrl0.chan 	= 0;
	fCtrl1.chan		= 1;


	/* device id */
	status = ioctl( dev, PM3386_IOCTL_DEV_GET_ID, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_DEV_GET_ID failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Chip ID                   0x%04x\n", data);

	/* device revision */
	status = ioctl( dev, PM3386_IOCTL_DEV_GET_REV, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_DEV_GET_REV failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Chip Rev                  0x%04x\n", data);

	/* device int status */
	status = ioctl( dev, PM3386_IOCTL_DEV_GET_INT_STTS, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_DEV_GET_INT_STTS failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Interrupt Status          0x%04x\n", data);

	/* device status */
	status = ioctl( dev, PM3386_IOCTL_DEV_GET_DEV_STTS, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_DEV_GET_DEV_STTS failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Device Status             0x%04x\n", data);

	/* device rool status */
	status = ioctl( dev, PM3386_IOCTL_DEV_GET_ROOL_STTS, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_DEV_GET_ROOL_STTS failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("ROOL Status               0x%04x\n", data);

	/* device dool status */
	status = ioctl( dev, PM3386_IOCTL_DEV_GET_DOOL_STTS, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_DEV_GET_DOOL_STTS failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("DOOL Status               0x%04x\n", data);

	/* equalized tx mode */
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_EQ_MODE, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_PL3IP_GET_EQ_MODE failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Equalized tx mode         0x%04x\n", data);

	/* pause mode */
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_PMODE, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_PL3IP_GET_PMODE failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Pause mode                0x%04x\n", data);

	/* Equalization threshold */
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_EQ_TSHLD, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_PL3IP_GET_EQ_TSHLD failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Equalization threshold    0x%04x\n", data);

	/* Equalization difference */
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_EQ_DIFF, &data );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_IOCTL_PL3IP_GET_EQ_DIFF failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Equalization difference   0x%04x\n", data);

	/*** channel hi water ****/
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_CHAN_HI_WATER, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_PL3IP_GET_CHAN_HI_WATER failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_CHAN_HI_WATER, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_PL3IP_GET_CHAN_HI_WATER failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel Hi Water          0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel lo water ****/
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_CHAN_LO_WATER, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_PL3IP_GET_CHAN_LO_WATER failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_CHAN_LO_WATER, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_PL3IP_GET_CHAN_LO_WATER failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel Lo Water          0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel pkt burst ****/
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_CHAN_PKT_BURST, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_PL3IP_GET_CHAN_PKT_BURST failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_PL3IP_GET_CHAN_PKT_BURST, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_PL3IP_GET_CHAN_PKT_BURST failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel pkt burst         0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel fifo reserve ****/
	status = ioctl( dev, PM3386_IOCTL_PL3EP_GET_CHAN_FIFO_RSV, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_PL3EP_GET_CHAN_FIFO_RSV failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_PL3EP_GET_CHAN_FIFO_RSV, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_PL3EP_GET_CHAN_FIFO_RSV failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel fifo reserve      0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel min frame ****/
	status = ioctl( dev, PM3386_IOCTL_PL3EP_GET_CHAN_MIN_FRAME, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_PL3EP_GET_CHAN_MIN_FRAME failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_PL3EP_GET_CHAN_MIN_FRAME, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_PL3EP_GET_CHAN_MIN_FRAME failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel min frame         0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel L32B ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_L32B, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_L32B failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_L32B, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_L32B failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel L32B              0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel L10B ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_L10B, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_L10B failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_L10B, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_L10B failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel L10B              0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel paden ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PADEN, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_PADEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PADEN, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_PADEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel paden             0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel crcen ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_CRCEN, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_CRCEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_CRCEN, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_CRCEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel crcen             0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel fctx ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_FCTX, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_FCTX failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_FCTX, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_FCTX failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel fctx              0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel fcrx ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_FCRX, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_FCRX failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_FCRX, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_FCRX failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel fcrx              0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel longp ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_LONGP, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_LONGP failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_LONGP, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_LONGP failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel longp             0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel rxen ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_RXEN, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_RXEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_RXEN, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_RXEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel rxen              0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel txen ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_TXEN, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_TXEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_TXEN, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_TXEN failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel txen              0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel ipg ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_IPG, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_IPG failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_IPG, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_IPG failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel ipg               0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel station address ****/
	macAddr0.chan = 0;
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_STN_ADDR, &macAddr0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_STN_ADDR failed, status = 0x%x\n", status);
		exit(-1);
	}
	macAddr1.chan = 1;
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_STN_ADDR, &macAddr1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_STN_ADDR failed, status = 0x%x\n", status);
		exit(-1);
	}

	printf("Channel stn addr          0x");
	for (i=5; i>=0; i--)
		printf("%02x", macAddr0.macAddr[i]);
	printf("  0x");
	for (i=5; i>=0; i--)
		printf("%02x", macAddr1.macAddr[i]);
	printf("\n");

	/*** channel max rx frame ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MAX_RX_FRAME, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_MAX_RX_FRAME failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MAX_RX_FRAME, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_MAX_RX_FRAME failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("Channel max rx frame      0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel AN enable ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_EN, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_AN_EN failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_EN, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_AN_EN failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel AN enable         0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel AN status ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_STTS, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_AN_STTS failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_STTS, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_AN_STTS failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel AN status         0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel AN Adv Lo ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_ADV_LO, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_AN_ADV_LO failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_ADV_LO, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_AN_ADV_LO failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel AN Adv Lo         0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel AN Adv Hi ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_ADV_HI, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_AN_ADV_HI failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_ADV_HI, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_AN_ADV_HI failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel AN Adv Hi         0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel AN Link Lo ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_LINK_LO, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_AN_LINK_LO failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_LINK_LO, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_AN_LINK_LO failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel AN Link Lo        0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel AN Link Hi ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_LINK_HI, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_AN_LINK_HI failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_AN_LINK_HI, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_AN_LINK_HI failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel AN Link Hi        0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel host pause ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_HOST_PAUSE, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_HOST_PAUSE failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_HOST_PAUSE, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_HOST_PAUSE failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel host pause        0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel pass err ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PASS_ERR, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_PASS_ERR failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PASS_ERR, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_PASS_ERR failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel pass err          0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel pass ctrl ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PASS_CTRL, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_PASS_CTRL failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PASS_CTRL, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_PASS_CTRL failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel pass ctrl         0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel pause time ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PAUSE_TIME, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_PAUSE_TIME failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PAUSE_TIME, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_PAUSE_TIME failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel pause time        0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel pause ival ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PAUSE_IVAL, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_PAUSE_IVAL failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PAUSE_IVAL, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_PAUSE_IVAL failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel pause ival        0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel max tx frame ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MAX_TX_FRAME, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_MAX_TX_FRAME failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MAX_TX_FRAME, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_MAX_TX_FRAME failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel max tx frame      0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel rx fwd thsld ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_RX_FWD_TSHLD, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_RX_FWD_TSHLD failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_RX_FWD_TSHLD, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_RX_FWD_TSHLD failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel rx fwd thsld      0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	for( i=0; i<PM3386_MAX_FILTERS; i++ )
	{
		/*** channel addr match i ****/
		amatch0.num = i;
		amatch1.num = i;
		status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_ADDR_MATCH, &amatch0 );
		if( status != PM3386_SUCCESS )
		{
			printf("Chan0: PM3386_IOCTL_EGMAC_GET_ADDR_MATCH failed, status = 0x%x\n", status);
			exit(-1);
		}
		status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_ADDR_MATCH, &amatch1 );
		if( status != PM3386_SUCCESS )
		{
			printf("Chan1: PM3386_IOCTL_EGMAC_GET_ADDR_MATCH failed, status = 0x%x\n", status);
			exit(-1);
		}
		p0 = (UINT16 *)(amatch0.macAddr);
		p1 = (UINT16 *)(amatch1.macAddr);
		printf("channel addr match %d      0x%04x%04x%04x  0x%04x%04x%04x\n",
											i, *p0, *(p0+1), *(p0+2), *p1, *(p1+1), *(p1+2) );
	}


	for( i=0; i<PM3386_MAX_FILTERS; i++ )
	{
		/*** channel vid match i ****/
		vmatch0.num = i;
		vmatch1.num = i;
		status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_VID_MATCH, &vmatch0 );
		if( status != PM3386_SUCCESS )
		{
			printf("Chan0: PM3386_IOCTL_EGMAC_GET_VID_MATCH failed, status = 0x%x\n", status);
			exit(-1);
		}
		status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_VID_MATCH, &vmatch1 );
		if( status != PM3386_SUCCESS )
		{
			printf("Chan1: PM3386_IOCTL_EGMAC_GET_VID_MATCH failed, status = 0x%x\n", status);
			exit(-1);
		}
		printf("channel vid match %d       0x%04x          0x%04x\n", i, vmatch0.vid, vmatch1.vid );
	}

	/*** channel mhash ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MHASH, &mhash0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_MHASH failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MHASH, &mhash1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_MHASH failed, status = 0x%x\n", status);
		exit(-1);
	}
	p0 = (UINT16 *)(&(mhash0.mhash));
	p1 = (UINT16 *)(&(mhash1.mhash));
	printf("Channel mhash             0x%04x%04x%04x%04x  0x%04x%04x%04x%04x\n",
										*p0, *(p0+1), *(p0+2), *(p0+3), *p1, *(p1+1), *(p1+2), *(p1+3) );

	for( i=0; i<PM3386_MAX_FILTERS; i++ )
	{
		/*** channel fltr ctrl i ****/
		fCtrl0.num = i;
		fCtrl1.num = i;
		status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_ADDR_FILT_CTRL, &fCtrl0 );
		if( status != PM3386_SUCCESS )
		{
			printf("Chan0: PM3386_IOCTL_EGMAC_GET_ADDR_FILT_CTRL failed, status = 0x%x\n", status);
			exit(-1);
		}
		status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_ADDR_FILT_CTRL, &fCtrl1 );
		if( status != PM3386_SUCCESS )
		{
			printf("Chan1: PM3386_IOCTL_EGMAC_GET_ADDR_FILT_CTRL failed, status = 0x%x\n", status);
			exit(-1);
		}
		printf("channel fltr ctrl %d       0x%04x          0x%04x\n", i, fCtrl0.val, fCtrl1.val );
	}

	/*** channel mhash en ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MHASH_EN, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_MHASH_EN failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_MHASH_EN, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_MHASH_EN failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel mhash en          0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel promisc mode ****/
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PMODE, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_EGMAC_GET_PMODE failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_EGMAC_GET_PMODE, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_EGMAC_GET_PMODE failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel promisc mode      0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** channel serdes loopback ****/
	status = ioctl( dev, PM3386_IOCTL_SERDES_GET_SYS_LPBK, &chanCfg0 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan0: PM3386_IOCTL_SERDES_GET_SYS_LPBK failed, status = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev, PM3386_IOCTL_SERDES_GET_SYS_LPBK, &chanCfg1 );
	if( status != PM3386_SUCCESS )
	{
		printf("Chan1: PM3386_IOCTL_SERDES_GET_SYS_LPBK failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("channel serdes loopback   0x%04x          0x%04x\n", chanCfg0.val, chanCfg1.val );

	/*** interrput enables ****/
	status = ioctl( dev, PM3386_GET_INT_ENABLE, &inten );
	if( status != PM3386_SUCCESS )
	{
		printf("PM3386_GET_INT_ENABLE failed, status = 0x%x\n", status);
		exit(-1);
	}
	printf("inten.interface           0x%04x\n", inten.interface );
	printf("inten.mstat0              0x%04x\n", (UINT16)inten.mstat0 );
	printf("inten.mstat1              0x%04x\n", (UINT16)inten.mstat1 );

	closePM3386devices();
}



/*
 *	ShowMacStats()
 *	----------------
 *	Show mac stats for all devices and channels
 */
void ShowMacStats( void )
{
	PM3386_STATUS		status;
	PM3386_CHAN_STATS	chanStats0;
	PM3386_CHAN_STATS	chanStats1;
	PM3386_CHAN_STATS	chanStats2;
	PM3386_CHAN_STATS	chanStats3;
	UINT32 	*p0;
	UINT32 	*p1;
	UINT32 	*p2;
	UINT32 	*p3;

	/* point to correct channel for each mac */
	chanStats0.chan = 0;
	chanStats1.chan = 1;
	chanStats2.chan = 0;
	chanStats3.chan = 1;

	status = openPM3386devices();
	if(status != PM3386_SUCCESS )
	{
		printf("ShowMacStats: device open failed. Device not found\n");
		exit(-1);
	}

	/* get stats for mac 0 */
	status = ioctl( dev0, PM3386_IOCTL_MSTAT_READ_ALL_COUNTERS, &chanStats0 );
	if( status != PM3386_SUCCESS )
	{
		printf("ShowMacStats: ioctl failed, status = 0x%x\n", status);
		exit(-1);
	}

	/* get stats for mac 1 */
	status = ioctl( dev0, PM3386_IOCTL_MSTAT_READ_ALL_COUNTERS, &chanStats1 );
	if( status != PM3386_SUCCESS )
	{
		printf("ShowMacStats: ioctl failed, status = 0x%x\n", status);
		exit(-1);
	}

	/* get stats for mac 2 */
	status = ioctl( dev1, PM3386_IOCTL_MSTAT_READ_ALL_COUNTERS, &chanStats2 );
	if( status != PM3386_SUCCESS )
	{
		printf("ShowMacStats: ioctl failed, status = 0x%x\n", status);
		exit(-1);
	}

	/* get stats for mac 3 */
	status = ioctl( dev1, PM3386_IOCTL_MSTAT_READ_ALL_COUNTERS, &chanStats3 );
	if( status != PM3386_SUCCESS )
	{
		printf("ShowMacStats: ioctl failed, status = 0x%x\n", status);
		exit(-1);
	}

	/* make pointers for shortened typing */
	p0 = (UINT32 *)(chanStats0.stats);
	p1 = (UINT32 *)(chanStats1.stats);
	p2 = (UINT32 *)(chanStats2.stats);
	p3 = (UINT32 *)(chanStats3.stats);

	/* print stats */
	printf("                             Dev0,Chan0    Dev0,Chan1    Dev1,Chan0    Dev1,Chan1\n");
	printf("                             ----------    ----------    ----------    ----------\n");
	printf("FramesReceivedOK             0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("OctetsReceivedOK             0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FramesReceived               0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("OctetsReceived               0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("UnicastFramesReceivedOK      0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("MulticastFramesReceivedOK    0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("BroadcastFramesReceivedOK    0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TaggedFramesReceivedOK       0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("PauseMacCtrlFrameReceived    0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("MacCtrlFrameReceived         0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FrameCheckSequenceErrors     0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FramesLostInternalMacErr     0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("SymbolError                  0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("InRangeLengthErrors          0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	p0=p0+2; p1=p1+2; p2=p2+2; p3=p3+2;	/*skip element*/
	printf("FramesTooLongErrors          0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("Jabbers                      0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("Fragments                    0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("UndersizedFrames             0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("ReceiveFrames64              0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("ReceiveFrames65to127         0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("ReceivedFrames128to255       0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("ReceivedFrames256to511       0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("ReceivedFrames512to1023      0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("ReceivedFrames1024to1518     0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("ReceivedFrames1519toMax      0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("JumboOctetsReceivedOK        0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FilteredOctets               0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FilteredUnicastFrames        0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FilteredMulticastFrames      0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FilteredBroadcastFrames      0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("\n");

	p0=p0+2; p1=p1+2; p2=p2+2; p3=p3+2;	/*skip element*/
	printf("FramesTransmittedOK          0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("OctetsTransmittedOK          0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("OctetsTransmitted            0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("FramesLostInternalMacTxErr   0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TransmitSystemError          0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("UnicastFramesTxAttempted     0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("UnicastFramesTxOK            0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("MulticastFramesTxAttempted   0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("MulticastFramesTxOK          0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("BroadcastFramesTxAttempted   0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("BroadcastFramesTxOK          0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("PauseMacCtrlFramesTx         0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("MacCtrlFramesTx              0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TxFrames64                   0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TxFrames65to127              0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TxFrames128to255             0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TxFrames256to511             0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TxFrames512to1023            0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TxFrames1024to1518           0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("TxFrames1519toMax            0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);
	printf("JumboOctesTxOK               0x%02x%08x  0x%02x%08x  0x%02x%08x  0x%02x%08x\n", *p0++, *p0++, *p1++, *p1++, *p2++, *p2++, *p3++, *p3++);

	closePM3386devices();
}


/*
 *	pm3386Callback()
 *	------------------
 *	Callback function for pm3386 device interrupts.
 */
void pm3386Callback( void *usrCtxt, PM3386_INTERRUPTS *pIntr )
{
	UINT32 *p0 = (UINT32 *)(&(pIntr->mstat0));
	UINT32 *p1 = (UINT32 *)(&(pIntr->mstat1));

	printf("Device %d interrupt callback:\n", *((UINT32 *)usrCtxt));

	if(pIntr->interface & PM3386_INT_TX_ROOL)
	{
		printf("-> TX_ROOL\n");
	}

	if(pIntr->interface & PM3386_INT_RX_ROOL_0)
	{
		printf("-> RX_ROOL_CH0\n");
	}

	if(pIntr->interface & PM3386_INT_RX_DOOL_0)
	{
		printf("-> RX_DOOL_CH0\n");
	}

	if(pIntr->interface & PM3386_INT_RX_ROOL_1)
	{
		printf("-> RX_ROOL_CH1\n");
	}

	if(pIntr->interface & PM3386_INT_RX_DOOL_1)
	{
		printf("-> RX_DOOL_CH1\n");
	}

	if(pIntr->interface & PM3386_INT_PL3EP_CH0_FIFO_TRUNC)
	{
		printf("-> PL3EP_CH0_FIFO_TRUNC\n");
	}

	if(pIntr->interface & PM3386_INT_PL3EP_CH0_PERR)
	{
		printf("-> PL3EP_CH0_PERR\n");
	}

	if(pIntr->interface & PM3386_INT_PL3EP_CH1_FIFO_TRUNC)
	{
		printf("-> PL3EP_CH1_FIFO_TRUNC\n");
	}

	if(pIntr->interface & PM3386_INT_PL3EP_CH1_PERR)
	{
		printf("-> PL3EP_CH1_PERR\n");
	}

	if(pIntr->interface & PM3386_INT_PL3IP_CH0_SW_PROG_FAULT)
	{
		printf("-> PL3IP_CH0_SW_PROG_FAULT\n");
	}

	if(pIntr->interface & PM3386_INT_PL3IP_CH0_EQUALIZATION)
	{
		printf("-> PL3IP_CH0_EQUALIZATION\n");
	}

	if(pIntr->interface & PM3386_INT_PL3IP_CH1_SW_PROG_FAULT)
	{
		printf("-> PL3IP_CH1_SW_PROG_FAULT\n");
	}

	if(pIntr->interface & PM3386_INT_PL3IP_CH1_EQUALIZATION)
	{
		printf("-> PL3IP_CH1_EQUALIZATION\n");
	}

	printf("-> MSTAT0 = 0x%08x%08x\n", *p0, *(p0+1));
	printf("-> MSTAT1 = 0x%08x%08x\n", *p1, *(p1+1));
}

/*
 *	StopMacs()
 *	-----------
 *	disable rx and tx, remove callbacks, close macs, and stop pm3386 driver
 */
void StopMacs( void )
{
	PM3386_STATUS		status;
	PM3386_CHAN_CFG		chanCfg;
	PM3386_INTERRUPTS	inten;

	status = openPM3386devices();
	if(status != PM3386_SUCCESS )
	{
		printf("StopMacs: device open failed. Device not found\n");
		exit(-1);
	}

	/* disable rx and tx device 0, chan 0 */
	chanCfg.chan 	= 0;
	chanCfg.val		= 0;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 0, Staus = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 1, Staus = 0x%x\n", status);
		exit(-1);
	}

	/* disable rx and tx device 0, chan 0 */
	chanCfg.chan 	= 1;
	chanCfg.val		= 0;
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 0, Staus = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev0, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 1, Staus = 0x%x\n", status);
		exit(-1);
	}

	/* disable rx and tx device 1, chan 0 */
	chanCfg.chan 	= 0;
	chanCfg.val		= 0;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 0, Staus = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 1, Staus = 0x%x\n", status);
		exit(-1);
	}

	/* disable rx and tx device 1, chan 0 */
	chanCfg.chan 	= 1;
	chanCfg.val		= 0;
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_RXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 0, Staus = 0x%x\n", status);
		exit(-1);
	}
	status = ioctl( dev1, PM3386_IOCTL_EGMAC_SET_TXEN, &chanCfg );
	if( status != PM3386_SUCCESS )
	{
		printf("StopMacs: ioctl failed on device 1, Staus = 0x%x\n", status);
		exit(-1);
	}

	closePM3386devices();

	printf("PM3386 devices stopped\n");
}

