免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1246 | 回复: 0
打印 上一主题 下一主题

mii-tool的限制/mii-tool与千兆网络 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-15 13:11 |只看该作者 |倒序浏览

mii-tool的限制/mii-tool与千兆网络
mii-tool的限制

mii-tool不支持1000M以上的网卡,这里我们先做个实验,先看看100M网卡能不能正确显示:

[root@localhost /]# mii-tool -v eth0
eth0: negotiated 100baseTx-FD, link ok
product info: vendor 00:40:63, model 50 rev 10
basic mode: autonegotiation enabled
basic status: autonegotiation complete, link ok
capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control
link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
#这里显示100M网卡

[root@localhost /]# ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: pumbg
Wake-on: d
Current message level: 0x00000001 (1)
Link detected: yes
#这里也显示是100M网卡

正常对于100M以下的网卡都可以用这俩个命令来查看,但是对于100M以上网卡的,mii-tool就会出现问题

mii-tool -v eth0
eth0: negotiated 100baseTx-FD, link ok
product info: vendor 00:aa:00, model 56 rev 0
basic mode: autonegotiation enabled
basic status: autonegotiation complete, link ok
capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control
link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
#这里显示100M网卡,实际上我是1000M的接口

ethtool eth0
Settings for eth0:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised auto-negotiation: Yes
Speed: 1000Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: umbg
Wake-on: d
Current message level: 0x00000007 (7)
Link detected: yes
#这里却正确的显示1000M网卡

这里简单分析一下mii-tool的显示部份的实现:
1、首先在主函数中打开套接字,循环调用处理函数:
int main(int argc, char **argv)
{
int i;
char s[6];
/* Open a basic socket. */
if ((skfd = socket(AF_INET, SOCK_DGRAM,0))
perror("socket");
exit(-1);
}

for (i = 0; i
sprintf(s, "eth%d", i);
do_one_xcvr(skfd, s, 1);
}

return 0;
}


do_one_xcvr的主要功能是调用ioctl取得网卡的phy_id,然后进一步处理:
int do_one_xcvr(int skfd, char *ifname, int maybe)
{
struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
/* Get the vitals from the interface. */
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(skfd, SIOCGMIIPHY, &ifr)
{
if (!maybe || (errno != ENODEV))
{
fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %sn",
ifname, strerror(errno));
}
return 1;
}

show_basic_mii(skfd, mii->phy_id);
}

关于SIOCGMIIPHY等宏的定义,很容易就可以找到了,这里不分析了……
show_basic_mii是整个核心了:
int show_basic_mii(int sock, int phy_id)
{
char buf[100];
int i, mii_val[32];
int bmcr, bmsr, advert, lkpar;
/* Some bits in the BMSR are latched, but we can't rely on being
the only reader, so only the current values are meaningful */
mdio_read(sock, MII_BMSR);
for (i = 0; i
mii_val = mdio_read(sock, i);

if (mii_val[MII_BMCR] == 0xffff) {
fprintf(stderr, " No MII transceiver present!.n");
return -1;
}

/* Descriptive rename. */
bmcr = mii_val[MII_BMCR]; bmsr = mii_val[MII_BMSR];
advert = mii_val[MII_ANAR]; lkpar = mii_val[MII_ANLPAR];

sprintf(buf, "%s: ", ifr.ifr_name);
if (bmcr & MII_BMCR_AN_ENA) {
if (bmsr & MII_BMSR_AN_COMPLETE) {
if (advert & lkpar) {
strcat(buf, (lkpar & MII_AN_ACK) ?
"negotiated" : "no autonegotiation,");
strcat(buf, media_list(advert & lkpar, 1));
strcat(buf, ", ");
} else {
strcat(buf, "autonegotiation failed, ");
}
} else if (bmcr & MII_BMCR_RESTART) {
strcat(buf, "autonegotiation restarted, ");
}
} else {
sprintf(buf+strlen(buf), "%s Mbit, %s duplex, ",
(bmcr & MII_BMCR_100MBIT) ? "100" : "10",
(bmcr & MII_BMCR_DUPLEX) ? "full" : "half");
}
strcat(buf, (bmsr & MII_BMSR_LINK_VALID) ? "link ok" : "no link");

printf("%sn", buf);

return 0;
}
可以看到,主要是通过mdio_read来读取相关信息的,之后就是判断比较和输出了,而输出网卡物一类型的时候,用到了media_list,先来看看mdio_read:
static int mdio_read(int skfd, int location)
{
struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
mii->reg_num = location;
if (ioctl(skfd, SIOCGMIIREG, &ifr)
fprintf(stderr, "SIOCGMIIREG on %s failed: %sn", ifr.ifr_name,
strerror(errno));
return -1;
}
return mii->val_out;
}
同样,也是用ioctl……^o^,再来看看media_list,它主要根据mdio_read返回来的相关值读取一个事先封装好的结构数组:
static char *media_list(int mask, int best)
{
static char buf[100];
int i;
*buf = '';
mask >>= 5;
for (i = 4; i >= 0; i--) {
if (mask & (1
strcat(buf, " ");
strcat(buf, media.name);
if (best) break;
}
}
if (mask & (1
strcat(buf, " flow-control");
return buf;
}
最后来看看media的定义的赋值:
const struct {
char *name;
u_short value;
} media[] = {
/* The order through 100baseT4 matches bits in the BMSR */
{ "10baseT-HD", MII_AN_10BASET_HD },
{ "10baseT-FD", MII_AN_10BASET_FD },
{ "100baseTx-HD", MII_AN_100BASETX_HD },
{ "100baseTx-FD", MII_AN_100BASETX_FD },
{ "100baseT4", MII_AN_100BASET4 },
{ "100baseTx", MII_AN_100BASETX_FD | MII_AN_100BASETX_HD },
{ "10baseT", MII_AN_10BASET_FD | MII_AN_10BASET_HD },
};

这里没有定义100M以上的接口,所以,mii-tool不支持1000M


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/13977/showart_340448.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP