网卡驱动8-MII接口以及linux内核对MII的支持
来源:互联网 发布:php class 实例 编辑:程序博客网 时间:2024/05/16 08:11
首先,向大家推荐一些文章。
http://blog.chinaunix.net/uid-24148050-id-131084.html
http://hi.baidu.com/lds102/item/eae3262c77b897de0f37f966
http://blog.csdn.net/zyboy2000/article/details/4525726
这上面说了MII、RMII、SMII、GMII等一系列的接口。
网口一般是这样
MacàPhyà网络变压器àRJ45口
但是只是从电路上不一定看得这么清楚,应为有些是集成的,例如DM9000就是mac+phy,还有很多网络变压器和RJ45口在一起。对于我们写驱动,要知道的是Mac和Pht之间的接口,其他的还是比较透明的。而它们的接口就是上面提的一些。
MII是(Medium Independent Interface)的意思,是指不用考虑媒体是铜轴、光纤、电缆等,因为这些媒体处理的相关工作都有PHY或者叫做MAC的芯片完成。 MII支持10兆和100兆的操作,不支持1000兆。
我们看一下MII的接口图(分别相对于mac和 phy)
前16位是数据传输,MDC和MDIO是SMI总线的东西,用于管理phy。这篇文章主要就是看linux内核对SMI总线的使用。
上面有篇文章是这么说的:
Mac对Phy的管理是使用SMI(SerialManagement Interface)总线通过读写PHY的寄存器来完成的。PHY里面的部分寄存器是IEEE定义的,这样PHY把自己的目前的状态反映到寄存器里面,MAC通过SMI总线不断的读取PHY的状态寄存器以得知目前PHY的状态,例如连接速度,双工的能力等。
上面让我在意的是PHY里面的部分寄存器是IEEE定义的。那我们看看内核里的定义吧.linux-3.0.8
include/linux/mii.h
/* Generic MII registers. */#define MII_BMCR 0x00 /* Basic mode control register */#define MII_BMSR 0x01 /* Basic mode status register */#define MII_PHYSID1 0x02 /* PHYS ID 1 */#define MII_PHYSID2 0x03 /* PHYS ID 2 */#define MII_ADVERTISE 0x04 /* Advertisement control reg */#define MII_LPA 0x05 /* Link partner ability reg */#define MII_EXPANSION 0x06 /* Expansion register */#define MII_CTRL1000 0x09 /* 1000BASE-T control */#define MII_STAT1000 0x0a /* 1000BASE-T status */#define MII_ESTATUS 0x0f /* Extended Status */#define MII_DCOUNTER 0x12 /* Disconnect counter */#define MII_FCSCOUNTER 0x13 /* False carrier counter */#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */#define MII_RERRCOUNTER 0x15 /* Receive error counter */#define MII_SREVISION 0x16 /* Silicon revision */#define MII_RESV1 0x17 /* Reserved... */#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */#define MII_PHYADDR 0x19 /* PHY address */#define MII_RESV2 0x1a /* Reserved... */#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */#define MII_NCONFIG 0x1c /* Network interface config */
我们在看看DM9000的定义:
不是所有都支持。
例如我们要启动自动协商机制,只要把control寄存器的的第12位置1就可以了。
现在摆在我们的面前有两个问题
1. DM9000如何操作去写或读。
2. linux提供了什么样的接口。
先看第一个问题:下面是DM9000的几个寄存器
上面可以看成是4个寄存器
EPCR: phy控制寄存器
EPAR: phy地址寄存器
EPDRL:phy数据寄存器低8位
EPDRH:phy数据寄存器高8位
读:
1. 先写入寄存器的地址(就是上面的MII Register Description上面的。你可以在mii.h中看到定义)到EPAR寄存器。
2. 把EPCR的ERPRR位(读命令)和EPOS(选择PHY)置位。
3. 读EEPROM用的是等待EPCR的ERRE变为0,为1表示正在进行。读PHY用的是延时1m秒。看一下uboot,都是用延时等待。
4. 清除EPCR的ERPRR位。
5. 读EPDRL和EPDRH。
写:
1. 先写入寄存器的地址到EPAR寄存器。
2. 写数据到ERDRL和EPDRH。
3. 把EPCR的ERPRW(写命令)和EPOS(选择PHY)置位。
4. 延时1m秒,等待完成。
5. 清除EPCR的ERPRR位。
下面我们看linux内核提供的接口。
struct mii_if_info {int phy_id;int advertising;int phy_id_mask;int reg_num_mask;unsigned int full_duplex : 1;/* is full duplex? */unsigned int force_media : 1;/* is autoneg. disabled? */unsigned int supports_gmii : 1; /* are GMII registers supported? */struct net_device *dev;int (*mdio_read) (struct net_device *dev, int phy_id, int location);void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);};
看一下dm9000网卡的初始化:
db->mii.phy_id_mask = 0x1f;//这个给驱动用,dm9000没用,是考虑smi总线上有多个phy时。db->mii.reg_num_mask = 0x1f;//寄存器maskdb->mii.force_media = 0;db->mii.full_duplex = 0;db->mii.dev = ndev;db->mii.mdio_read = dm9000_phy_read;db->mii.mdio_write = dm9000_phy_write;
dm9000不支持gmii,所以没对它初始化
如果你提供了这些,对phy的操作就可以同drivers/net/mii.c中的函数去操作,不用再去看那些mii的寄存器了(当然有些非标准的要自己写)。我看看mii.c提供的
EXPORT_SYMBOL(mii_link_ok);EXPORT_SYMBOL(mii_nway_restart);EXPORT_SYMBOL(mii_ethtool_gset);EXPORT_SYMBOL(mii_ethtool_sset);EXPORT_SYMBOL(mii_check_link);EXPORT_SYMBOL(mii_check_media);EXPORT_SYMBOL(mii_check_gmii_support);EXPORT_SYMBOL(generic_mii_ioctl);我们上次说的ethtool很多要依赖它们。mii_link_ok:读链接状态mii_nway_restart: 重启接口的自动协商机制mii_ethtool_gset:获取接口设置。查看结构体struct ethtool_cmd有什么设置,上篇文章说过。mii_ethtool_sset:设置接口设置。mii_check_link:检测MII链接状态。这个会调用netif_carrier_on/off上报内核。mii_check_media:检查双工改变。Full or Halfmii_check_gmii_support:是否支持gmii,这个是1000M的支持generic_mii_ioctl:ioctl接口。这个可以放在驱动的ioctl里面,用户可以通过socket的ioctl调用。
下次我们说一个千兆的网卡,对phy的控制。
- 网卡驱动8-MII接口以及linux内核对MII的支持
- linux网卡phy-mii驱动mdio调试zz150120a
- MII 接口
- MII接口
- MII接口
- MII接口
- MII接口
- MII
- MII
- MII
- MII
- MII
- MII
- linux内核对网卡驱动多队列的支持
- linux内核对网卡驱动多队列的支持
- imx515 fec 驱动mii 的实现
- MII、RMII、GMII接口的详细介绍
- MII、RMII、GMII接口的详细介绍
- 致终将逝去的Windows XP
- C++错误查询
- eclipse中的vim插件使用
- 关于一篇Python装饰器的文章链接
- Phpcms V9 调用全站最新文章的方法
- 网卡驱动8-MII接口以及linux内核对MII的支持
- 14年春面试前学习计划(一)
- 给定整数数组,相邻两个之间之差为1或者-1,求给定数在数组中的位置
- 计算机应用和软件开发
- POJ 2392 初涉多重背包
- fpm简介
- Ext Js技术之面板的初步使用
- 】The application’s PagerAdapter changed the adapter’s contents without calling PagerAdapter#notifyDa
- javascript不一样的写法