ether_input(&sc->arpcom.ac_if,eh,m);/*传输给上一层的包括ifnet结构,以太网头部,一mbuf*/ } /* 中断例程 */ static void elintr(int unit) { register struct el_softc *sc; register int base; int stat, rxstat, len, done; /* 寻址softc和I/O基地址 */ sc = &el_softc[unit]; base = sc->el_base; dprintf(("elintr: ")); /* 检查板卡状态 */ stat = inb(base+EL_AS); if(stat & EL_AS_RXBUSY) {/*接收忙*/ (void)inb(base+EL_RXC);/*读接收命令寄存器*/ outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));/* 用IRQ(中断)使能和接收 写辅助命令寄存器*/ return; } done = 0; while(!done) { rxstat = inb(base+EL_RXS); if(rxstat & EL_RXS_STALE) {/*EL_RXS_STALE代表接受状态没有改变*/ (void)inb(base+EL_RXC);/*读接收命令寄存器*/ outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));/* 用IRQ(中断)使能和接收 写辅助命令寄存器*/ return; } /* 如果这有一个溢出发生,重新初始化板卡. */ if(!(rxstat & EL_RXS_NOFLOW)) { dprintf(("overflow.n")); el_hardreset(sc); /* 使板卡回到接收模式 */ if(sc->arpcom.ac_if.if_flags & IFF_PROMISC) outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); else outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); (void)inb(base+EL_AS);/*读辅助状态寄存器*/ outb(base+EL_RBC,0);/*清除接收缓冲*/ (void)inb(base+EL_RXC);/*读接收命令寄存器*/ outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));/* 用IRQ(中断)使能和接收 写辅助命令寄存器*/ return; } /* 到这应该是进来了一数据包 */ len = inb(base+EL_RBL); len |= inb(base+EL_RBH) << 8;/*包长度的高低位组合为该包的长度*/ dprintf(("receive len=%d rxstat=%x ",len,rxstat)); outb(base+EL_AC,EL_AC_HOST);/*EL_AC_HOST为系统总线可访问缓冲 */ /* 如果包太短或太长,回到接收模式并返回 */ if((len <= sizeof(struct ether_header)) || (len > ETHER_MAX_LEN)) {/*如果包小于以太网头部的长度或大于最大长度*/ if(sc->arpcom.ac_if.if_flags & IFF_PROMISC)/*为重置硬件准备if_flags*/ outb(base+EL_RXC,(EL_RXC_PROMISC|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); else outb(base+EL_RXC,(EL_RXC_ABROAD|EL_RXC_AGF|EL_RXC_DSHORT|EL_RXC_DDRIB|EL_RXC_DOFLOW)); (void)inb(base+EL_AS);/*读辅助状态寄存器*/ outb(base+EL_RBC,0);/*清除接收缓冲*/ (void)inb(base+EL_RXC);/*读接收命令寄存器*/ outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX));/* 用IRQ(中断)使能和接收 写辅助命令寄存器*/ return; } sc->arpcom.ac_if.if_ipackets++;/*统计使用,说明接收包总数*/ /* 拷贝数据到我们的缓冲 */ outb(base+EL_GPBL,0); outb(base+EL_GPBH,0); insb(base+EL_BUF,sc->el_pktbuf,len);/*从端口读一串数据到指定地址()*/ outb(base+EL_RBC,0); outb(base+EL_AC,EL_AC_RX); dprintf(("m-->",sc->el_pktbuf+6,":"));/*也放置到el_pktbuf中,发送也放在他中,在发送时有一个开中断接数据包的过程不过那时候el_pktbuf中没有数据,不会相互影响.*/ dprintf(("mn",sc->el_pktbuf,":")); /* 把数据传递到上一层 */ len -= sizeof(struct ether_header); elread(sc,(caddr_t)(sc->el_pktbuf),len); /* 对状态? */ stat = inb(base+EL_AS); /* 如果忙不为真则继续 */ if(!(stat & EL_AS_RXBUSY)) dprintf((" ")); else done = 1; /*退出循环*/ } (void)inb(base+EL_RXC); outb(base+EL_AC,(EL_AC_IRQE|EL_AC_RX)); return; } |