Linux下smi/mdio总线通信

韩大卫@吉林师范大学

下面代码描述了在用户层访问smi/mdio总线, 读写phy芯片寄存器的通用代码。Linux内核2.6以上通用。

将下面代码编译后,将可执行文件a.out 重命名为mdio

mdio eth0 1 读取phy寄存器1的数值

mdio eth0 0 0x1120 将0x1120写入phy寄存器1

eth0 为mac层控制器的名称, 一般为eth0 或mgmt0。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define reteck(ret) \

if(ret < 0){ \

printf("%m! \"%s\" : line: %d\n", __func__, __LINE__); \

goto lab; \

}

#define help() \

printf("mdio:\n"); \

printf("read operation: mdio reg_addr\n"); \

printf("write operation: mdio reg_addr value\n"); \

printf("For example:\n"); \

printf("mdio eth0 1\n"); \

printf("mdio eth0 0 0x12\n\n"); \

exit(0);

int sockfd;

int main(int argc, char *argv[]){

if(argc == 1 || !strcmp(argv[1], "-h")){

help();

}

struct mii_ioctl_data *mii = NULL;

struct ifreq ifr;

int ret;

memset(&ifr, 0, sizeof(ifr));

strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1);

sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);

reteck(sockfd);

//get phy address in smi bus

ret = ioctl(sockfd, SIOCGMIIPHY, &ifr);

reteck(ret);

mii = (struct mii_ioctl_data*)&ifr.ifr_data;

if(argc == 3){

mii->reg_num = (uint16_t)strtoul(argv[2], NULL, 0);

ret = ioctl(sockfd, SIOCGMIIREG, &ifr);

reteck(ret);

printf("read phy addr: 0x%x reg: 0x%x value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_out);

}else if(argc == 4){

mii->reg_num = (uint16_t)strtoul(argv[2], NULL, 0);

mii->val_in = (uint16_t)strtoul(argv[3], NULL, 0);

ret = ioctl(sockfd, SIOCSMIIREG, &ifr);

reteck(ret);

printf("write phy addr: 0x%x reg: 0x%x value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_in);

}

lab:

close(sockfd);

return 0;

}

很多人在read操作里面判断phy的link状态,

if(mii->val_out&

0x0004){

printf("linkup\n");

}else{

printf("linkdown\n");

}

其实这个做法是比较通用可行的。

解释一下,关于mii->val_out&

0x0004

大多数phy芯片的寄存器0为控制寄存器, 寄存器1 为状态寄存器,

寄存器3和4为Identifiier Register

, 这里的内容为phy芯片产商的识别码。

举个实例,marvell88E1116, 无论是光口模式还是电口模式, 寄存器1都是Status register

一般寄存器有16个bit, 第2个bit为link 状态, 第5个bit为自动协商,

一般这个状态寄存器的数值为:0x796d

意思是:

14bit : 有能力实现全双工100BASE-X工作模式

13bit : 有能力实现半双工100BASE-X工作模式

12bit : 有能力实现全双工10BASE-T工作模式

11 bit : 有能力实现半双工10BASE-T工作模式

8bit : 扩展信息描述在寄存器15.

6bit : MF报头抑制

5bit : 自动协商完成

3bit : 有能力自动协商

2bit :link 状态:up

0bit : 有扩展寄存器

NOTE:

上面的ioctl()在linux最底层的实现函数是在drivers/net/phy/

目录下, 如octeon处理器平台:

drivers/net/phy/mdio-octeon.c

这里面有mii总线读写phy寄存器的方法的实现函数:

octeon_mdiobus_read

octeon_mdiobus_write

ioctl的执行路径是:

用户层ioctl系统调用--> drivers/net层接口函数ndo_do_ioctl -->

drivers/net/phy层接口函数phy_mii_ioctl -->

通用接口函数mdiobus_read , 封装了mii_bus->read -->

最终是read的实现函数drivers/net/phy/mdio-octeon.c :octeon_mdiobus_read

linux访问mdio接口函数,Linux 下smi/mdio总线通信相关推荐

  1. Linux内核编程接口函数

    Linux内核编程接口函数 转载请注明出处: http://blog.csdn.net/drivelinux/article/details/8656280 字符设备相关函数 1.alloc_chrd ...

  2. linux内核的延时函数,linux中内核延时函数 (转)

    第一类延时函数原型是:(忙等) void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsi ...

  3. linux访问web地址命令(linux访问接口的命令)

    linux在命令符界面如何浏览网页 在命令符界面浏览网页可以使用lynx,links,w3m等的使用方式都很类似,以w3m为例:安装w3m浏览器:sudoapt-getinstallw3m:使用w3m ...

  4. linux字符串编码转换函数,Linux C++ 字符串 编码识别、编码转换

    最近在做一个类似垂直下载的爬虫系统.下载之后有个解析模块,解析之后要求编码一致的向后传入索引,便遇到了编码转换问题. 1. 编码的识别 推荐使用 libchardet, 可以在这个页面下载,使用说明就 ...

  5. 局域网服务器linux访问不了网,linux局域网不能相互访问

    1.关闭防火墙 /etc/init.d/iptable stop 2.关闭selinux 1.临时禁用SELinux: root@server# setenforce 0 这样重启服务器之后,还是会启 ...

  6. linux协议栈skb操作函数,linux协议栈skb操作函数

    1,struct sk_buff数据结构 struct sk_buff{ //这两个结构必须放在最前面 struct sk_buff *next; struct sk_buff *prev; stru ...

  7. linux内核的外部接口函数,linux内核中GPIO的使用(二)--标准接口函数

    在linux内核中,有一些基本模块可以使用标准的接口函数来操作,比如GPIO.interrupt.clock,所谓的标准接口函数是指一些与硬件平台无关的.linux下做驱动通用的函数, 常用的有: g ...

  8. linux访问nfs文件夹,linux配置NFS网络共享文件夹目录

    网络共享磁盘大家都用过,在windows上叫共享文件夹,linux叫共享目录,linux上配置网络共享目录也有很多中方式samba和nfs,各自有各自的优点,nfs是比较常用的. 1.安装NFS 服务 ...

  9. linux访问网站出现443,Linux访问网站一直出现超时

    问题描述: 开发java应用时,需要访问此网站,在windows上一切正常访问,部署到linux服务器上就出现了访问超时 [root@VM_18_115_centos ~]# wget 'https: ...

  10. linux 内核 fget,fgets函数 linux中fgets函数怎么用

    一个函数该如何使用?我们最先要了解的就是这个函数的语法以及具体的含义是什么,所以今天我们就来看一看fgets函数在实际的运用过程当中是如何使用的,希望能给大家带来一定的帮助. fgets函数--lin ...

最新文章

  1. 直观讲解一下RPC调用和HTTP调用的区别
  2. IDEA提升研发效能—高效定位篇
  3. 模拟人脑项目彻底宣告失败:耗资10亿欧,10年前轰动全球,如今死得悄无声息...
  4. Java设计模式-代理模式 理论代码相结合
  5. BZOJ-1934-Vote善意的投票-SHOI2007
  6. 2019年9月中国编程语言排行榜,C#排第三
  7. Python使用组合、排列和动态规划算法求解0-1背包问题
  8. 历日 [宋] 许月卿
  9. 使用虚幻引擎 4 年,网络架构大揭秘
  10. ACCESS中执行sql语句
  11. 安卓手机如何复制粘贴不重叠_多台电脑安卓手机跨设备复制粘贴利器——Clipbrd...
  12. python中θ符号怎么打出来_Python打印特殊符号及对应编码解析
  13. win7安装后系统保留分区无法分配盘符导致无法激活原因
  14. 1.3 熟悉 Ubuntu 桌面环境
  15. 【最新】CentOS7.8 部署redis6.0.1集群
  16. 手机邮箱怎么注册申请,手机邮箱在哪里找到,电子邮箱怎么弄?
  17. 【笔试真题】字节跳动产品岗笔试主观题解析!!
  18. 7-219 sdut-C语言实验-A+B for Input-Output Practice (不确定次数循环)7-220 sdut-C语言实验——两个数比较
  19. 二叉树(Binary Tree):先序遍历、中序遍历、后序遍历和层次遍历
  20. AI人脸检测和人脸识别是一个概念吗?有什么区别?

热门文章

  1. 沙普利算法java实现_Java实现婚姻稳定匹配Gale- Shapley算法
  2. sqlite3 表创建后设置主外键 联合主键 外键设置
  3. jmeter录制postman脚本
  4. windows 编程入门资料
  5. FAT文件系统详解(二)
  6. Arduino教程: 斯通恩 STWI101WT-01 人机交互显示屏和Arduino
  7. rs232接口_为什么越来越多人用RS232接口,却还分不清DB9、DB25的引脚定义?
  8. Microsoft Project——Project基本使用教程
  9. 小管家进销存_管家婆物联宝微订货V2.3发版公告
  10. 360导航源码php,51zxw 仿360网址导航源码