为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

Cs8900a网卡驱动分析

2011-05-18 5页 doc 45KB 19阅读

用户头像

is_130067

暂无简介

举报
Cs8900a网卡驱动分析Nokia Standard Document Template CS8900A 驱动程序分析 (国嵌) 1. 寄存器 ·LINECTL(0112H) LINECTL决定CS8900的基本配置和物理接口。例如:设置初始值为00d3H,选择物理接口为10BASE-T,并使能设备的发送和接收控制位。 ·RXCTL(0104H) RXCTL控制CS8900接收特定数据报。设置RXTCL的初始值为0d05H,表示接收网络上的广播或者目标地址同本地物理地址相同的正确数据包。 ·RXCFG(0102H) RXCFG控制CS8900接收到特...
Cs8900a网卡驱动分析
Nokia Standard Document Template CS8900A 驱动程序分析 (国嵌) 1. 寄存器 ·LINECTL(0112H) LINECTL决定CS8900的基本配置和物理接口。例如:设置初始值为00d3H,选择物理接口为10BASE-T,并使能设备的发送和接收控制位。 ·RXCTL(0104H) RXCTL控制CS8900接收特定数据报。设置RXTCL的初始值为0d05H,示接收网络上的广播或者目标地址同本地物理地址相同的正确数据包。 ·RXCFG(0102H) RXCFG控制CS8900接收到特定数据报后会引发接收中断。RXCFG可设置为0103H,这样当收到一个正确的数据报后,CS8900会产生一个接收中断。 ·BUSCT(0116H) BUSCT可控制芯片的I/O接口的一些操作。设置初始值为8017H,打开CS8900的中断总控制位。 ·ISQ(0120H) ISQ是网卡芯片的中断状态寄存器,内部映射接收中断状态寄存器和发送中断状态寄存器的内容。 ·PORT0(0000H) 发送和接收数据时,CPU通过PORT0传递数据。 ·TXCMD(0004H) 发送控制寄存器,如果写入数据00C0H,那么网卡芯片在全部数据写入后开始发送数据。 ·TXLENG(0006H) 发送数据长度寄存器,发送数据时,首先写入发送数据长度,然后将数据通过PORT0写入芯片。 以上为几个最主要的工作寄存器(为16位)。 系统工作时,应首先对网卡芯片进行初始化,即写寄存器LINECTL、RXCTL、 RCCFG、BUSCT。 发数据时,写控制寄存器TXCMD,并将发送数据长度写入TXLENG,然后将数据依次写入PORT0口,网卡芯片将数据组织为链路层类型并添加填充位和CRC校验送到网络。 2. 程序框架 2.1​ 模块注册 static int __init init_cs8900a_s3c2410(void) { struct net_local *lp; int ret = 0; dev_cs89x0.irq = irq; dev_cs89x0.base_addr = io; dev_cs89x0.init = cs89x0_probe; request_region(dev_cs89x0.base_addr, NETCARD_IO_EXTENT, "cs8900a"); if (register_netdev(&dev_cs89x0) != 0) } 2.2​  2.3​ 设备检测 static int __init cs89x0_probe1(struct net_device *dev, int ioaddr) { /* get the chip type */ rev_type = readreg(dev, PRODUCT_ID_ADD); lp->chip_type = rev_type &~ REVISON_BITS; lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; if (lp->chip_type != CS8900) { printk(__FILE__ ": wrong device driver!\n"); ret = -ENODEV; goto after_kmalloc; } dev->dev_addr[0] = 0x00; dev->dev_addr[1] = 0x00; dev->dev_addr[2] = 0xc0; dev->dev_addr[3] = 0xff; dev->dev_addr[4] = 0xee; dev->dev_addr[5] = 0x08; set_mac_address(dev, dev->dev_addr); dev->irq = IRQ_LAN; printk(", IRQ %d", dev->irq); dev->open = net_open; dev->stop = net_close; dev->tx_timeout = net_timeout; dev->watchdog_timeo = 3 * HZ; dev->hard_start_xmit = net_send_packet; dev->get_stats = net_get_stats; dev->set_multicast_list = set_multicast_list; dev->set_mac_address = set_mac_address; /* Fill in the fields of the device structure with ethernet values. */ ether_setup(dev); } 2.4​  2.5​ 数据发送 static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { netif_stop_queue(dev); /* initiate a transmit sequence */ writeword(dev, TX_CMD_PORT, lp->send_cmd); writeword(dev, TX_LEN_PORT, skb->len); /* Test to see if the chip has allocated memory for the packet */ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { spin_unlock_irq(&lp->lock); DPRINTK(1, "cs89x0: Tx buffer not free!\n"); return 1; } /* Write the contents of the packet */ writeblock(dev, skb->data, skb->len); return 0; } 2.6​ 中断 static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { while ((status = readword(dev, ISQ_PORT))) { switch(status & ISQ_EVENT_MASK) { case ISQ_RECEIVER_EVENT: /* Got a packet(s). */ net_rx(dev); break; case ISQ_TRANSMITTER_EVENT: lp->stats.tx_packets++; netif_wake_queue(dev); /* Inform upper layers. */ break; } 2.7​ 接收 static void net_rx(struct net_device *dev) { status = inw(ioaddr + RX_FRAME_PORT); if ((status & RX_OK) == 0) { count_rx_errors(status, lp); return; } length = inw(ioaddr + RX_FRAME_PORT); /* Malloc up new buffer. */ skb = dev_alloc_skb(length + 2); if (skb == NULL) { lp->stats.rx_dropped++; return; } skb_reserve(skb, 2); /* mac头是14个字节,一开始保留两个字节,正是为了保证ip头的开始是四字节对齐的。*/ skb->len = length; skb->dev = dev; readblock(dev, skb->data, skb->len); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); }
/
本文档为【Cs8900a网卡驱动分析】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索