主题 : qq2440网卡MAC 地址配置问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 2063
精华: 0
发帖: 9
金钱: 90 两
威望: 27 点
综合积分: 18 分
注册时间: 2008-10-23
最后登录: 2011-06-01
楼主  发表于: 2008-11-20 17:43

 qq2440网卡MAC 地址配置问题

刚把2.6.24 移植通过,发现CS8900的缺省MAC地址是在驱动里面的,所以想动态的配置MAC地址。修改/etc/init.d/rcS,添加
ifconfig  eth0  down
ifconfig  eth0  hw  ether  1234567890ab 
ifconfig  eth0  up

配置IP 为
ifconfig eth0 192.168.1.240

启动后 用ifconfig 查看可以看见 MAC 地址已经被修改了,但是ping 102.168.1.1 就不通,其他局域网PC也ping不同开发版。


如果 去掉
ifconfig  eth0  down
ifconfig  eth0  hw  ether  1234567890ab 
ifconfig  eth0  up

使用网卡缺省MAC,则可以ping通192。168。1。1 ,其他PC 也可以ping通开发板


请各位大大指点一下,有可能是什么问题呢。
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2008-11-20 17:58
那你为什么不把驱动里缺省的MAC地址改成1234567890ab试试?
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 2063
精华: 0
发帖: 9
金钱: 90 两
威望: 27 点
综合积分: 18 分
注册时间: 2008-10-23
最后登录: 2011-06-01
2楼  发表于: 2008-11-20 18:13
这个是可以的哈。但是如果以后在一个局域网放2个设备就不能简单的通过配置来修改MAC地址了。
级别: 新手上路
UID: 2063
精华: 0
发帖: 9
金钱: 90 两
威望: 27 点
综合积分: 18 分
注册时间: 2008-10-23
最后登录: 2011-06-01
3楼  发表于: 2008-11-21 09:51
问题解决了哈,主要是我用的cs8900 驱动里面 修改MAC地址的函数只修改了内存数据结构,没有修改芯片寄存器,我把函数修改了一下,这下可以了。

谢谢 kasim 大侠的提醒哈。看来很多问题还是要自己分析一下才行哦。

  首先我查看cs8900的probe 函数 cs8900_probe,在里面定义了初始化的MAC地址保存在驱动的数据结构dev->dev_addr中,代码如下:
    dev->dev_addr[0] = 0x08;
    dev->dev_addr[1] = 0x00;
    dev->dev_addr[2] = 0x1e;
    dev->dev_addr[3] = 0x21;
    dev->dev_addr[4] = 0xc7;
    dev->dev_addr[5] = 0xf8;

紧跟着下面把地址写入到芯片中生效:

    for (i = 0; i < ETH_ALEN; i += 2)
        cs8900_write (dev,PP_IA + i,dev->dev_addr | (dev->dev_addr[i + 1] << 8));

PP_IA  为寄存器地址,所以在初始化的时候MAC地址是生效的。


然后我再考虑系统启动后 使用ifconfig 修改 MAC地址,这个时候    ndev->set_mac_address 函数进行操作的。

我检查了一下,我用的这个版本的驱动的cs8900_init 中 没有对此值赋值,而是在ether_setup中赋的缺省函数:
void ether_setup(struct net_device *dev)
{
    dev->header_ops        = ð_header_ops;

    dev->change_mtu        = eth_change_mtu;
    dev->set_mac_address     = eth_mac_addr;
    dev->validate_addr    = eth_validate_addr;

    dev->type        = ARPHRD_ETHER;
    dev->hard_header_len     = ETH_HLEN;
    dev->mtu        = ETH_DATA_LEN;
    dev->addr_len        = ETH_ALEN;
    dev->tx_queue_len    = 1000;    /* Ethernet wants good queues */
    dev->flags        = IFF_BROADCAST|IFF_MULTICAST;

    memset(dev->broadcast, 0xFF, ETH_ALEN);

}

eth_mac_addr 函数只修改内存数据,没有修改芯片寄存器。
static int eth_mac_addr(struct net_device *dev, void *p)
{
    struct sockaddr *addr = p;

    if (netif_running(dev))
        return -EBUSY;
    if (!is_valid_ether_addr(addr->sa_data))
        return -EADDRNOTAVAIL;
    memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
    return 0;
}

我的解决办法就是 自定自己的set_mac_address函数,定义如下
static int cs8900_set_mac_address(struct net_device *dev, void *p)
{
    int i;
    struct sockaddr *addr = p;

    if (netif_running(dev))
        return -EBUSY;

    if (!is_valid_ether_addr(addr->sa_data))
        return -EADDRNOTAVAIL;

    memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);

    /* set the Ethernet address */   
    for (i = 0; i < ETH_ALEN; i += 2)
        cs8900_write (dev,PP_IA + i,dev->dev_addr | (dev->dev_addr[i + 1] << 8));
    return 0;
}
然后在 inint对set_mac_address 赋值就可以了。

static int __init cs8900_init (void)
{
    struct net_device *ndev;

        ndev = alloc_etherdev(sizeof (cs8900_t));
        if (!ndev) {
                printk("%s: could not allocate device.\n", "cs8900");
                return -ENOMEM;
        }

    cs8900_dev = ndev;
    cs8900_dev->init = cs8900_probe;
    ether_setup (ndev);

    ndev->open              = cs8900_start;
    ndev->stop              = cs8900_stop;
    ndev->hard_start_xmit    = cs8900_send_start;
    ndev->get_stats          = cs8900_get_stats;
    ndev->set_multicast_list = cs8900_set_receive_mode;
    ndev->tx_timeout        = cs8900_transmit_timeout;
    ndev->set_mac_address      = cs8900_set_mac_address;   
    ndev->watchdog_timeo    = HZ;

    return (register_netdev (cs8900_dev));
}
[ 此贴被qwetiop在2008-11-23 13:20重新编辑 ]
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
4楼  发表于: 2008-11-21 10:02
分析解决问题的过程比解决问题本身有价值的多,希望能把你解决的过程分享给大家,谢谢
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 6051
精华: 0
发帖: 1
金钱: 10 两
威望: 10 点
综合积分: 2 分
注册时间: 2009-05-18
最后登录: 2009-05-23
5楼  发表于: 2009-05-23 16:11
大家好,新手求助,请问楼上的大侠,你们那个CS8900。C 驱动是不是能在命令行里修改MAC地址!!?