Linux 下smi/mdio总线通信
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/mii.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/types.h>
#include <netinet/in.h> #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芯片产商的识别码。 举个实例,marvell 88E1116, 无论是光口模式还是电口模式, 寄存器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 下smi/mdio总线通信的更多相关文章
- Linux下smi/mdio总线驱动
Linux下smi/mdio总线驱动 韩大卫@吉林师范大学 MII(媒体独立接口), 是IEEE802.3定义的以太网行业标准接口, smi是mii中的标准管理接口, 有两跟管脚, mdio 和mdc ...
- Linux下简单的socket通信实例
Linux下简单的socket通信实例 If you spend too much time thinking about a thing, you’ll never get it done. —Br ...
- linux下的qt串口通信
1.linux下的qt串口通信跟windows唯一的差别就是端口号的名字,windows下面是COM,而linux是ttyUSB0的路径 2.一般情况下linux插上USB转串口线就可以在/dev/目 ...
- Linux下进程间管道通信小作业
在进行这次作业之前,我们先来看看什么是管道吧! 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间, ...
- Linux下的USB总线驱动(一)
版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127 一.USB理论 1. USB概念概述 USB1.0版本速度1.5Mbps(低速USB) USB1 ...
- win7系统无线 VirtualBox rehat 32位linux 下 host-only模式相互通信及上网 配置
虚拟机环境:virtualBox虚拟环境 redhat 32位 主机环境 : win7 无线路由 模式: host-only win7下nat模式原先的设置基于 有网线连接的情形下,在使用了无线路由之 ...
- Linux下Tun/Tap设备通信原理
Tun/Tap都是虚拟网卡,没有直接映射到物理网卡,是一种纯软件的实现.Tun是三层虚拟设备,能够处理三层即IP包,Tap是二层设备,能处理链路层网络包如以太网包.使用虚拟网络设备,可以实现隧道,如O ...
- Linux下C语言socket通信实现发送读取的文件内容--简单实现代码
本次代码涉及到的内容:socket通讯,文件读取 读取的文件以及文件位置: 要读取的文件和c文件在同一个目录下.客户端(client)读取的是123.xml,服务端(server)读取的是23.xml ...
- linux下有名管道进程通信
一.任务 1.学习mkfifo等函数: 2.了解有名管道的特点.阻塞打开与非阻塞打开等: 3.编写一个关于有名管道进程通信的程序,并运行. 二.相关概念 1.相关函数 创建有名管道的函数是mkfifo ...
随机推荐
- CSS marging相关
一.margin可以为负值 在盒模型中,内容区的width/height.padding.border都不能为负值,但是margin例外,它可以为负值. margin负值的本质,在于它改变了元素在普通 ...
- requests(一): 发送一个json格式的post请求
今天给一位同学解决post发送数据格式为json格式的请求,顺便确认一下问题归属. 背景: 用postman工具发送一个数据格式为json的请求,得到了服务器的响应. 用python的requests ...
- 20165230 2017-2018-2《Java程序设计》课程总结
20165230 2017-2018-2<Java程序设计>课程总结 一.作业链接汇总 每周作业链接 预备作业1:我期望的师生关系 预备作业2:做中学learning by doing个人 ...
- 洛谷 P4656: LOJ 2484: [CEOI2017]Palindromic Partitions
菜菜只能靠写简单字符串哈希维持生活. 题目传送门:LOJ #2484. 题意简述: 题面讲得很清楚了. 题解: 很显然从两边往中间推,能选的就选上这个贪心策略是对的. 如何判断能不能选上,直接字符串哈 ...
- Project Euler Problem2
Even Fibonacci numbers Problem 2 Each new term in the Fibonacci sequence is generated by adding the ...
- OS X 10.11:在exFAT分区的外置硬盘上使用Time Machine。
Time Machine默认需要使用HFS+分区的外置硬盘,但在网络硬盘上也可以使用单个的 .sparsebundle 镜像文件备份.在本地USB或Firewire等接口连接的外置硬盘,只有exFAT ...
- 【LOJ】#6432. 「PKUSC2018」真实排名
题解 简单分析一下,如果这个选手成绩是0,直接输出\(\binom{n}{k}\) 如果这个选手的成绩没有被翻倍,那么找到大于等于它的数(除了它自己)有a个,翻倍后不大于它的数有b个,那么就从这\(a ...
- Educational Codeforces Round 41 (Rated for Div. 2)
这场没打又亏疯了!!! A - Tetris : 类似俄罗斯方块,模拟一下就好啦. #include<bits/stdc++.h> #define fi first #define se ...
- ubuntu下hadoop,spark配置
转载来自:http://www.cnblogs.com/spark-china/p/3941878.html 在VMWare 中准备第二.第三台运行Ubuntu系统的机器: 在VMWare中构建第 ...
- InnoDB的锁机制浅析(All in One)
目录 InnoDB的锁机制浅析 1. 前言 2. 锁基本概念 2.1 共享锁和排它锁 2.2 意向锁-Intention Locks 2.3 锁的兼容性 3. InnoDB中的锁 3.1 准备工作 3 ...