5.接收数据
- /*
* Received a packet and pass to upper layer
*/ - static void
- dm9000_rx(struct net_device *dev)
- {
- board_info_t *db = netdev_priv(dev);
- struct dm9000_rxhdr rxhdr;
- struct sk_buff *skb;
- u8 rxbyte, *rdptr;
- bool GoodPacket;
- int RxLen;
- /* Check packet ready or not */
- do {
- ior(db, DM9000_MRCMDX); /* Dummy read */
- //获取接收数据的长度
- /* Get most updated data */
- rxbyte = readb(db->io_data);
- //检查设备接收状态
- /* Status check: this byte must be 0 or 1 */
- if (rxbyte > DM9000_PKT_RDY) {
- dev_warn(db->dev, "status check fail: %d\n", rxbyte);
- iow(db, DM9000_RCR, 0x00); /* Stop Device */
- iow(db, DM9000_ISR, IMR_PAR); /* Stop INT request */
- return;
- }
- if (rxbyte != DM9000_PKT_RDY)
- return;
- /* A packet ready now & Get status/length */
- GoodPacket = true;
- writeb(DM9000_MRCMD, db->io_addr);
- (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
- RxLen = le16_to_cpu(rxhdr.RxLen);
- if (netif_msg_rx_status(db))
- dev_dbg(db->dev, "RX: status %02x, length %04x\n",
- rxhdr.RxStatus, RxLen);
- /* Packet Status check */
- if (RxLen < 0x40) {
- GoodPacket = false;
- if (netif_msg_rx_err(db))
- dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
- }
- if (RxLen > DM9000_PKT_MAX) {
- dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);
- }
- /* rxhdr.RxStatus is identical to RSR register. */
- if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |
- RSR_PLE | RSR_RWTO |
- RSR_LCS | RSR_RF)) {
- GoodPacket = false;
- if (rxhdr.RxStatus & RSR_FOE) {
- if (netif_msg_rx_err(db))
- dev_dbg(db->dev, "fifo error\n");
- dev->stats.rx_fifo_errors++;
- }
- if (rxhdr.RxStatus & RSR_CE) {
- if (netif_msg_rx_err(db))
- dev_dbg(db->dev, "crc error\n");
- dev->stats.rx_crc_errors++;
- }
- if (rxhdr.RxStatus & RSR_RF) {
- if (netif_msg_rx_err(db))
- dev_dbg(db->dev, "length error\n");
- dev->stats.rx_length_errors++;
- }
- }
- /* Move data from DM9000 */
- //如果接收正确,开始接收
- if (GoodPacket
- && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
- skb_reserve(skb, 2);
- rdptr = (u8 *) skb_put(skb, RxLen - 4);//获取skb的数据指针
- /* Read received packet from RX SRAM */
- (db->inblk)(db->io_data, rdptr, RxLen);//读取数据
- dev->stats.rx_bytes += RxLen;
- /* Pass to upper layer */
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);//将接收到的skb交给协议层
- dev->stats.rx_packets++;
- } else {
- /* need to dump the packet's data */
- (db->dumpblk)(db->io_data, RxLen);
- }
- } while (rxbyte == DM9000_PKT_RDY);
- }
6.发送完成
- /*
* DM9000 interrupt handler
* receive the packet to upper layer, free the transmitted packet
*/
- static void dm9000_tx_done(struct net_device *dev, board_info_t *db)
- {
- int tx_status = ior(db, DM9000_NSR); /* Got TX status */
- if (tx_status & (NSR_TX2END | NSR_TX1END)) {
- /* One packet sent complete */
- //将数据包计数减1
- db->tx_pkt_cnt--;
- dev->stats.tx_packets++;
- if (netif_msg_tx_done(db))
- dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
- /* Queue packet check & send */
- //如果数据包数量依然大于0,说明是TX RAM中的第二个包,再次启动发送,将TX RAM中第二个包发送出去
- if (db->tx_pkt_cnt > 0) {
- /*把数据的长度填到TXPLL(发送包长度低字节)和TXPLH(发送包长度高字节)中*/
- iow(db, DM9000_TXPLL, skb->len);
- iow(db, DM9000_TXPLH, skb->len >> 8);
- /*置发送控制寄存器(TX Control Register)的发送请求位TXREQ(Auto clears after sending completely),这样就可以发送出去了*/
- dev->trans_start = jiffies;
- }
- netif_wake_queue(dev);//唤醒发送队列
- }
- }
7.超时处理
- static void dm9000_timeout(struct net_device *dev)
- {
- board_info_t *db = netdev_priv(dev);
- u8 reg_save;
- unsigned long flags;
- /* Save previous register address */
- reg_save = readb(db->io_addr);
- spin_lock_irqsave(&db->lock, flags);
- //停止发送队列并复位DM9000网卡
- netif_stop_queue(dev);
- dm9000_reset(db);
- dm9000_init_dm9000(dev);
- /* We can accept TX packets again */
- //重新发送
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
- /* Restore previous register address */
- writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock, flags);
- }