if_flags = (IFF_BROADCAST | IFF_SIMPLEX);/*支持廣播和單播*/ /* 調(diào)用通用以太網(wǎng)初始化例程 */ dprintf(("Attaching interface...n")); ether_ifattach(ifp, ETHER_BPF_SUPPORTED); /* 在。1 freebsd網(wǎng)卡驅(qū)動(dòng)程序詳解( 四 )。" />

日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

1 freebsd網(wǎng)卡驅(qū)動(dòng)程序詳解( 四 )


ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX);/*支持廣播和單播*/

/* 調(diào)用通用以太網(wǎng)初始化例程 */
dprintf(("Attaching interface...n"));
ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
/*
在if_ethersubr.c中的ether_ifattach例程
void ether_ifattach(ifp, bpf) 調(diào)用時(shí),ETHER_BPF_SUPPORTED是BSD的
包過濾器,如果在編譯時(shí)設(shè)置文件沒有
打開包過濾器,那么代表0,否則是1
register struct ifnet *ifp;
int bpf;
{
register struct ifaddr *ifa;
register struct sockaddr_dl *sdl;

if_attach(ifp); 此例程在if.c 中
ifp->if_type = IFT_ETHER;代表以太網(wǎng)
ifp->if_addrlen = 6;硬件地址長度是6
ifp->if_hdrlen = 14;包的頭長度是6 6 2=14,其中2是協(xié)議類型
ifp->if_mtu = ETHERMTU; 為1500,多此一舉,在前面你可看到,已
經(jīng)填充了.
ifp->if_resolvemulti = ether_resolvemulti; 以太網(wǎng)解析多播例程指針
if (ifp->if_baudrate == 0) 波特率
ifp->if_baudrate = 10000000;
ifa = ifnet_addrs[ifp->if_index - 1];在ifnet_addrs[]數(shù)組中找到本地址指針
KASSERT(ifa != NULL, ("%s: no lladdr!n", __FUNCTION__));
sdl = (struct sockaddr_dl *)ifa->ifa_addr; ifa->ifa_addr在此時(shí)指向的是sockaddr_dl結(jié)構(gòu).
sdl->sdl_type = IFT_ETHER;
sdl->sdl_alen = ifp->if_addrlen;
bcopy((IFP2AC(ifp))->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);把硬件地址拷貝到sdl結(jié)構(gòu)中
if (bpf) bpf為真,即加入了BSD包過濾
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
if (ng_ether_attach_p != NULL)
(*ng_ether_attach_p)(ifp);
}

*/
printf("el%d: 3c501 address mn",idev->id_unit,
sc->arpcom.ac_enaddr, ":");

dprintf(("el_attach() finished.n"));
return(1);
}

/* 該例程重設(shè)接口. 在el_watchdog()中調(diào)用,因?yàn)閣atchdog不在本驅(qū)動(dòng)程序中支持,所以從不被調(diào)用*/
static void
el_reset(xsc)/*上面的一個(gè)函數(shù),重設(shè)硬件*/
void *xsc;
{
struct el_softc *sc = xsc;
int s;

dprintf(("elreset()n"));
s = splimp();/*關(guān)網(wǎng)絡(luò)中斷*/
el_stop(sc);/*下面的一個(gè)函數(shù)*/
el_init(sc);/*重新初始化卡*/
splx(s);/*開網(wǎng)絡(luò)中斷*/
}
/*停止接口,在el_ioctl()和el_reset()中調(diào)用*/
static void el_stop(xsc)
void *xsc;
{
struct el_softc *sc = xsc;

outb(sc->el_base EL_AC,0);/*用0寫輔助命令寄存器*/
}

/* 初始化接口. */
static void
el_init(xsc)
void *xsc;
{
struct el_softc *sc = xsc;
struct ifnet *ifp;
int s;
u_short base;

ifp = &sc->arpcom.ac_if;/*定位ifnet結(jié)構(gòu)*/
base = sc->el_base;/*網(wǎng)卡基本I/O地址*/

/* 如果地址不知道,什么也不做. */
if(TAILQ_EMPTY(&ifp->if_addrhead)) /* 在if.c中的if_attach例程
中已經(jīng)填充,由el_attach調(diào)用
ether_attach時(shí)再調(diào)用if_attach */
return;

s = splimp();/*關(guān)網(wǎng)絡(luò)中斷*/

/* 重設(shè)板卡. */
dprintf(("Resetting board...n"));
el_hardreset(sc);/*該函數(shù)在上面,重設(shè)硬件*/

/* 設(shè)置接收寄存器 rx */
dprintf(("Configuring rx...n"));
if(ifp->if_flags & IFF_PROMISC) /*是混雜模式?EL_RXC是0X6接收命令寄存器*/
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));
outb(base EL_RBC,0);/*接收緩沖寄存器清0*/

/* 設(shè)置傳輸寄存器 TX */
dprintf(("Configuring tx...n"));
outb(base EL_TXC,0);

/* 開始接收 */
dprintf(("Starting reception...n"));
outb(base EL_AC,(EL_AC_IRQE|EL_AC_RX));/*EL_AC_IRQE是IRQ enable(可用) EL_AC_RX為接收寄存器*/

/* 設(shè)置一些開始使用的標(biāo)志 */
ifp->if_flags |= IFF_RUNNING;/*加上正在運(yùn)行標(biāo)志*/
ifp->if_flags &= ~IFF_OACTIVE;/*去掉正在傳輸標(biāo)志*/

/* 調(diào)用輸出. */
el_start(ifp);

splx(s);/*開網(wǎng)絡(luò)中斷*/
}

推薦閱讀