首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Open Ethernet IP core 介绍及其 ucLinux 驱动(2)

Open Ethernet IP core 介绍及其 ucLinux 驱动(2)

open ethernet 设备初始化(Device initialization)
1
struct net_device * __init oeth_init(int unit);




oeth_init() 是 open Ethernet 设备驱动的入口,它只会在 Linux 初始化时调用一次,之后其占用的空间会被释放掉。oeth_init() 会调用 oeth_probe() 函数分配 IO 空间(通过 iomap())对 MAC 控制器的相关配置寄存器进行设置,比如工作模式,以太帧最大最小长度,TX/RX BD pointer, 设置 MAC 地址,清除状态标志以及中断使能等;然后会调用 register_netdev() 向 Linux 内核注册该网络设备。
这里主要介绍一下 open Ethernet MAC core 几个重要的寄存器,这几个寄存器的配置正确与否直接决定着该网络设备的工作稳定性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typedef struct _oeth_regs {
        uint    moder;          /* Mode Register */
        uint    int_src;        /* Interrupt Source Register */
        uint    int_mask;       /* Interrupt Mask Register */
        uint    ipgt;           /* Back to Bak Inter Packet Gap Register */
        uint    ipgr1;          /* Non Back to Back Inter Packet Gap Register 1 */
        uint    ipgr2;          /* Non Back to Back Inter Packet Gap Register 2 */
        uint    packet_len;     /* Packet Length Register (min. and max.) */
        uint    collconf;       /* Collision and Retry Configuration Register */
        uint    tx_bd_num;      /* Transmit Buffer Descriptor Number Register */
        uint    ctrlmoder;      /* Control Module Mode Register */
        uint    miimoder;       /* MII Mode Register */
        uint    miicommand;     /* MII Command Register */
        uint    miiaddress;     /* MII Address Register */
        uint    miitx_data;     /* MII Transmit Data Register */
        uint    miirx_data;     /* MII Receive Data Register */
        uint    miistatus;      /* MII Status Register */
        uint    mac_addr0;      /* MAC Individual Address Register 0 */
        uint    mac_addr1;      /* MAC Individual Address Register 1 */
        uint    hash_addr0;     /* Hash Register 0 */
        uint    hash_addr1;     /* Hash Register 1 */                           
} oeth_regs;




参考 ucLinux 代码 Linux-2.6/drivers/net/open_eth.c 中 oeth_probe() 函数有对上述寄存器具体设置。
这里值得一提的是以 mii* 命名开头的寄存器相关设置。MII Management (MIIM) 用于PHY 寄存器控制和相关状态信息的访问,比如 Link status。 与此相应,PHY 便提供了一些寄存器便于这样的操作。MIIM 物理接口包括一根双向数据线 MDIO(Management Data Input/Output) 和一根时钟线 MDC(Management Data Clock),MIIM 操作的命令和数据便通过这串行接口在 MAC 和 PHY 传递。如果使能了 OETH_SYSFS_MDIO_ACCESS,则在 Linux 用户可通过 sysfs 文件系统实现从 userspace 访问 MIIM 管理数据的访问。
open ethernet 设备方法(Device methods)网络设备的设备方法可以分为两种,基本方法和可选方法。以下代码是初始化函数调用 oeth_probe() 对 net_device * net 结构体成员的填充。
1
2
3
4
5
6
7
8
9
10
11
12
dev->open = oeth_open;
dev->hard_start_xmit = oeth_start_xmit;
dev->stop = oeth_close;
dev->get_stats = oeth_get_stats;
dev->set_multicast_list = oeth_set_multicast_list;
dev->set_mac_address = oeth_set_mac_add;

bmcr_val = eth_mdread(dev, PHY_ADDRESS, MII_BMCR);
dev->do_ioctl = mii_ioctl;
cep->mii.dev = dev;
cep->mii.mdio_read = eth_mdread;
cep->mii.mdio_write = eth_mdwrite;




oeth_open() 打开该网络接口。用户命令 ifconfig 激活该网络接口时,该接口函数会被调用。Oeth_open() 向系统注册内存使用空间,申请中断号注册中断处理函数等。中断号宏 MACIRQ_NUM 和寄存器基地址 ETH_BASE_ADD 根据实际的硬件设计相应的设置。
1
2
3
4
5
6
7
    /*Install eth interrupt handler*/
request_irq(MACIRQ_NUM, oeth_interrupt, 0, "eth", (void *)dev);
    /*Enable receiver and transmitter */
    regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
    /*set tasklet for receiver and transmitter*/
tasklet_init(&cep->oeth_rx_tasklet, oeth_rx, (unsigned long)dev);
    tasklet_init(&cep->oeth_tx_tasklet, oeth_tx, (unsigned long)dev);




通常对于10/100M 的网卡设备,驱动会采用中断方式(对于更高速(10Gb) 的网卡,采用通常意义的中断方式效率较低)。中断处理函数 (ISR) oeth_interrupt 必须精短,只需要做最少的事情,而具体的数据包处理由 taskelet 去完成。在这里, oeth_interrupt 的任务就是根据中断事件标志调度数据收发相应的 tasklet, 如下:
1
2
3
4
5
6
/* Handle receive event in its own function.*/
    if (int_events & (OETH_INT_RXF | OETH_INT_RXE | OETH_INT_BUSY))
        tasklet_schedule(&cep->oeth_rx_tasklet);      
    /* Handle transmit event in its own function. */
    if (int_events & (OETH_INT_TXB | OETH_INT_TXE))
        tasklet_schedule(&cep->oeth_tx_tasklet);




图 3. oeth interrupt service routineoeth_start_xmit() 是由设备驱动发起数据包的传送。
图 4. oeth_start_xmit()oeth_get_stats() 返回网络接口的统计状态,譬如接收和发送字节数,以及错误丢包等信息。用户用“ifconfig” 命令可以查看到这些统计信息。
此外,还提供了 MIIM 相关的设备方法用于对 PHY 的访问控制。
1
2
3
4
5
cep->mii.mdio_read = eth_mdread;//读PHY寄存器
    cep->mii.mdio_write = eth_mdwrite;//写PHY寄存器
    cep->mii.phy_id_mask = 0x1f;
    cep->mii.reg_num_mask = 0x1f;
    cep->mii.phy_id = PHY_ADDRESS;




ucLinux 也提供了通用的 MII 访问方法用于访问修改 PHY 收发器的工作模式,参见 unLinux 源代码<linux/mii.h>
结束语在嵌入式领域通常需要涉及到软硬件接口的问题,open ethernet MAC core 是一个开放公开的结构,不光是软件可以开源,硬件设计也可以开放,开源,这种硬件的公开性为软件开放提供更多便利性,可以为软件需要定制特定硬件,譬如 TOE(TCP/IP Offload Engine) 技术将传统的 TCP/IP 协议从软件处理搬移到网卡 (NIC) 硬件完成,这种软硬件的开放性必然促进IT技术,尤其是嵌入式系统的创新。
返回列表