Linux网卡驱动程序详解

来源:Linux认证    发布时间:2012-11-10    Linux认证视频    评论


}
/* 开始在接口上输出.从队列中得到包并输出他们,在输出中,留出接收用一部分时间,即打开中断再关闭中断,这样使接口接到的一些数据包不会丢失.
*/
static void
el_start(struct ifnet *ifp)
{
struct el_softc *sc;
u_short base;
struct mbuf *m, *m0;
int s, i, len, retries, done;
/* 定位softc结构的指针*/
sc = ifp->if_softc;
base = sc->el_base;/*基地址在输入输出指令时常要用到*/
dprintf(("el_start()...n"));
s = splimp();/*因为下面涉及到if_flags的操作,所以要关闭网络中断*/
/* 如果输出正在进行,则退出 */
if(sc->arpcom.ac_if.if_flags & IFF_OACTIVE)
return;
sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;/*加上输出正在进行传输标志*/
/* 主循环
*/
while(1) {/*唯一出口是准备传输的数据为空,即m0==NULL时*/
/* 从队列中移出下一数据包到m0中,请看头文件if_var.h
#define IF_DEQUEUE(ifq, m) {
(m) = (ifq)->ifq_head; ifq是一mbuf指针队列,把第一个mbuf指针放到m中
if (m) {
if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) 重排队列
(ifq)->ifq_tail = 0;
(m)->m_nextpkt = 0;
(ifq)->ifq_len--;
}
}

*/
IF_DEQUEUE(&sc->arpcom.ac_if.if_snd,m0);/* &sc->arpcom.ac_if.if_snd指向发送队列,该宏取出第一个mubf的指针放到m0中,看上面的说明.
这是数据结构的好教材*/
/* 如果发送缓冲区指针为空,即已经发送完,则退出,此是该无穷循环的唯一出口. */
if(m0 == NULL) {
sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;/*出去前当然要去掉输出正在进行标志*/
splx(s);
return;
}
/* 关闭接收 */
outb(base+EL_AC,EL_AC_HOST);/*EL_AC_HOST为系统总线可访问缓冲,即系统总线网卡要用 */
outb(base+EL_RBC,0);/*接收缓冲寄存器清0*/
/* 拷贝mbuf中的数据到softc结构定义的成员el_pktbuf中,缓冲大小是EL_BUFSIZ即2048. */
len = 0;
for(m = m0; m != NULL; m = m->m_next) { /* m0是一mbuf指针,也是一mbuf链的第一个,此
次要发送的是一mbuf链,不是一单个mbuf*/
if(m->m_len == 0)
continue;
bcopy(mtod(m,caddr_t),sc->el_pktbuf+len,m->m_len);/*m->len是该mbuf链的数据长度,sc->el_pktbuf是该卡的发送临时缓冲,要发送的数据在这集中,然后传送到网卡上,太费时间了,应该直接放置到网卡的存储器中.*/
len += m->m_len; /*len是这次要发送的总数*/
}
m_freem(m0); /*释放该mbuf链*/
len = max(len,ETHER_MIN_LEN); /*ETHER_MIN_LEN是发送的最小长度*/
/* 如果有BPF,就交给BPF验证 */
if(sc->arpcom.ac_if.if_bpf)
bpf_tap(&sc->arpcom.ac_if, sc->el_pktbuf, len);/*你当然可以在这写一点自己的验证过程*/
/* 传送数据包到板卡 */
dprintf(("el: xfr pkt length=%d...n",len));
i = EL_BUFSIZ - len;/*EL_BUFSIZ=2048字节*/
outb(base+EL_GPBL,(i & 0xff)); /*告诉发送的长度*/
outb(base+EL_GPBH,((i>>&0xff));
outsb(base+EL_BUF,sc->el_pktbuf,len);/*传输数据到板卡*/
/* 开始发送数据包 */
retries=0;/*下面做循环用的,在发不出去时,循环15次*/
done=0; /*done=1时发送成功了*/
while(!done) {
if(el_xmit(sc,len)) { /* 调用发送例程,其实只要传送base就可以了 */
done = -1;
break;
}

视频学习

我考网版权与免责声明

① 凡本网注明稿件来源为"原创"的所有文字、图片和音视频稿件,版权均属本网所有。任何媒体、网站或个人转载、链接转贴或以其他方式复制发表时必须注明"稿件来源:我考网",违者本网将依法追究责任;

② 本网部分稿件来源于网络,任何单位或个人认为我考网发布的内容可能涉嫌侵犯其合法权益,应该及时向我考网书面反馈,并提供身份证明、权属证明及详细侵权情况证明,我考网在收到上述法律文件后,将会尽快移除被控侵权内容。

最近更新

社区交流

考试问答