linux phy mdio 读取工具

mdio-tool.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/sockios.h>

#ifndef __GLIBC__
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#endif
#include "mii.h"

#define MDIO_TOOL_VERSION	"v1.0"

#define PHY_SLECT_PAGE	31
#define PHY_BASE_PAGE	0

//you can find kernel/driver/net/phy/phy.c : phy_mii_ioctl
#define MII_ADDR_C45	(1 << 30)
#define PHY_IS_C45	0x8000
#define PHY_C45_MASK	0x03e0


static struct ifreq ifr;
static int skfd = -1;

static int mdio_read(int location)
{
	struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
	mii->reg_num = location;

	if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
		fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
			strerror(errno));
		return -1;
	}
	return mii->val_out;
}

static int mdio_write(int location, int value)
{
	struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
	mii->reg_num = location;
	mii->val_in = value;

	if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
		fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
		strerror(errno));
		return -1;
	}

	return 0;
}

static int mdio_mmd_read(int devad, int reg)
{
	mdio_write(13, (devad | 0x0000));
	mdio_write(14, reg);
	mdio_write(13, (devad | 0x4000));
	return mdio_read(14);
}

static int mdio_mmd_write(int devad, int reg, int val)
{
	mdio_write(13, (devad | 0x0000));
	mdio_write(14, reg);
	mdio_write(13, (devad | 0x4000));
	return mdio_write(14, val);
}

static int mdio_c45_read(int devad, int reg)
{
	struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;

//	mii->reg_num = (MII_ADDR_C45 | (devad << 16) | (reg & 0xffff));
	mii->reg_num = reg;
	if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
		fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
			strerror(errno));
		return -1;
	}
	return mii->val_out;
}

static int mdio_c45_write(int devad, int reg, int val)
{
	struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;

//	mii->reg_num = (MII_ADDR_C45 | (devad << 16) | (reg & 0xffff));
	mii->reg_num = reg;
	mii->val_in = val;

	if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
		fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
			strerror(errno));
		return -1;
	}

	return 0;
}

static void help(void *op)
{
	if (((char *)op)[0] == 'w') {
		printf("Usage: mdio-tool [w] [dev] [reg] [val]\n");
		printf("or\n");
		printf("Usage: mdio-tool [w] [dev] [page] [reg] [val]\n");
		printf("or\n");
		printf("Usage: mdio-tool [w] [dev] [phyaddr] [page] [reg] [val]\n");

	} else if (((char*)op)[0] == 'r') {
		printf("Usage: mdio-tool [r] [dev] [reg]\n");
		printf("or\n");
		printf("Usage: mdio-tool [r] [dev] [page] [reg]\n");
		printf("or\n");
		printf("Usage: mdio-tool [r] [dev] [phyaddr] [page] [reg]\n");
	}else if (((char*)op)[0] == 'm'){
		if (((char*)op)[1] == 'w') {
			printf("Usage: mdio-tool [mw] [dev] [devad] [reg] [val]\n");
			printf("or\n");
			printf("Usage: mdio-tool [mw] [dev] [phyaddr] [devad] [reg] [val]\n");
		} else if (((char*)op)[1] == 'r'){
			printf("Usage: mdio-tool [mr] [dev] [devad] [reg]\n");
			printf("or\n");
			printf("Usage: mdio-tool [mr] [dev] [phyaddr] [devad] [reg]\n");
		}
	}else if (((char*)op)[0] == 'd'){
		if (((char*)op)[1] == 'w') {
			printf("Usage: mdio-tool [dw] [dev] [devad] [reg] [val]\n");
			printf("or\n");
			printf("Usage: mdio-tool [dw] [dev] [phyaddr] [devad] [reg] [val]\n");
		} else if (((char*)op)[1] == 'r'){
			printf("Usage: mdio-tool [dr] [dev] [devad] [reg]\n");
			printf("or\n");
			printf("Usage: mdio-tool [dr] [dev] [phyaddr] [devad] [reg]\n");
		}
	} else {
		printf("==========================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值