#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/myxmap.h>
#include <linux/myxconfig.h>
#include <linux/if.h>
#include <linux/sockios.h>
typedef unsigned short	u16;
#include <linux/mii.h>
#include <syslog.h>
/*
 * defines from linux/drivers/net/fusiv_toolkit/ap_code/inc/netpro/hostconfig.h
 */
#define MAC1_ID		1
#define MAC2_ID		2

static int			nif_fd;
static int			debug;
static char *			if_name;
static struct ifreq		ifr;
static struct mii_ioctl_data *	mii_p;
static u16			phy_id;

miir_exit(int rc)
{
	if (nif_fd) close(nif_fd);
}

u16
mdio_read(u16 reg_n)
{
	mii_p->phy_id = phy_id;
	mii_p->reg_num = reg_n;

	if (ioctl(nif_fd, SIOCGMIIREG, &ifr) == -1) {
		perror("mdio_read SIOCGMIIREG failed");
		miir_exit(errno);
	}
	return( mii_p->val_out );
}

void
mdio_write(u16 reg_n, u16 val)
{
	mii_p->phy_id = phy_id;
	mii_p->reg_num = reg_n;
	mii_p->val_in = val;

	if (ioctl(nif_fd, SIOCSMIIREG, &ifr) == -1) {
		perror("mdio_write SIOCSMIIREG failed");
		miir_exit(errno);
	}
}

int
do_if_name(char * name_p)
{
	if (strcmp("eth0", name_p) == 0) {
		phy_id = MAC1_ID;
	} else if (strcmp("eth1", name_p) == 0) {
		phy_id = MAC2_ID;
	} else {
		return(-1);
	}

	if_name = name_p;
	strcpy(ifr.ifr_name, if_name);
	return(0);
}


int
miir_main(int argc, char * argv[])
{
	u16	reg_n;
	u16	val;

	if (argc != 3) {
		usage(argv[0], 1);
	}

	if ((nif_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
		perror("nif socket failed");
		usage(argv[0], errno);
		miir_exit(errno);
	}

	memset(&ifr, 0, sizeof(ifr));
	mii_p = (struct mii_ioctl_data *)&ifr.ifr_data;
	if (do_if_name(argv[1])) {
		usage(argv[0], 1);
	}

	if (strcmp(argv[2], "all") == 0) {
		for (reg_n = 0; reg_n < 7; reg_n++) {
			val = mdio_read(reg_n);
			syslog(LOG_DEBUG, "miir registers reg<%2d> val<%04x>\n", reg_n, val);
		}
	} else {
		reg_n = (u16)strtol(argv[2], 0, 0);
		val = mdio_read(reg_n);
		syslog(LOG_DEBUG, "miir registers reg<%2d> val<%04x>\n", reg_n, val);
	}
	miir_exit(0);
}
