armlinux驱动dm9000网卡驱动分析(四)_第1页
armlinux驱动dm9000网卡驱动分析(四)_第2页
armlinux驱动dm9000网卡驱动分析(四)_第3页
armlinux驱动dm9000网卡驱动分析(四)_第4页
armlinux驱动dm9000网卡驱动分析(四)_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 HYPERLINK :/ ARM-Linux驱动-DM9000网卡驱动分析(四)1、接下来接着分析DM9000网卡驱动的数据接收函数cpp HYPERLINK :/ o view plain view o copy copy/*Receivedapacketandpasstoupperlayer*接收数据包,将数据包传递给上层*/staticvoiddm9000_rx(structnet_device*dev)board_info_t*db=netdev_priv(dev);/*得到网卡私有信息数据结构的首地址*/structdm9000_rxhdrrxhdr;/*该结构体封装了dm9000

2、接收的数据包信息*/structsk_buff*skb;u8rxbyte,*rdptr;boolGoodPacket;intRxLen;/*Checkpacketreadyornot*/do/*MRCMDX是内存数据预取读命令*/ior(db,DM9000_MRCMDX);/*Dummyread*/*Getmostupdateddata*/rxbyte=readb(db-io_data);/*Statuscheck:thisbytemustbe0or1*/*DM9000_PKT_ERR0 x02,表示接收出错*/if(rxbyte&DM9000_PKT_ERR)dev_warn(db-dev,

3、statuscheckfail:%dn,rxbyte);/*输出提示信息*/iow(db,DM9000_RCR,0 x00);/*StopDevice关闭设备*/iow(db,DM9000_ISR,IMR_PAR);/*StopINTrequest停止中断请求*/return;/*DM9000_PKT_RDY0 x01没有准备好,直接返回*/if(!(rxbyte&DM9000_PKT_RDY)return;/*Apacketreadynow&Getstatus/length*/GoodPacket=true;writeb(DM9000_MRCMD,db-io_addr);/*MRCMD是地址

4、增加的数据读取命令*/(db-inblk)(db-io_data,&rxhdr,sizeof(rxhdr);/*读取数据,从RX_SRAM到rxhdr结构体中*/RxLen=le16_to_cpu(rxhdr.RxLen);if(netif_msg_rx_status(db)dev_dbg(db-dev,RX:status%02x,length%04xn,rxhdr.RxStatus,RxLen);/*PacketStatuscheck,检查包的完整性*/if(RxLendev,RX:BadPacket(runt)n);/*如果数据长度大于DM9000_PKT_MAX,即1536*/if(Rx

5、LenDM9000_PKT_MAX)dev_dbg(db-dev,RST:RXLen:%xn,RxLen);/*rxhdr.RxStatusisidenticaltoRSRregister.*/*这里也是包的检查*/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,fifoerrorn);dev-stats.rx_fifo_errors+;

6、if(rxhdr.RxStatus&RSR_CE)if(netif_msg_rx_err(db)dev_dbg(db-dev,crcerrorn);dev-stats.rx_crc_errors+;if(rxhdr.RxStatus&RSR_RF)if(netif_msg_rx_err(db)dev_dbg(db-dev,lengtherrorn);dev-stats.rx_length_errors+;/*MovedatafromDM9000,从DM9000获取数据*/if(GoodPacket&(skb=dev_alloc_skb(RxLen+4)!=NULL)skb_reserve(sk

7、b,2);rdptr=(u8*)skb_put(skb,RxLen-4);/*ReadreceivedpacketfromRXSRAM*/*将RXSRAM中的数据读取到skbuff结构体*/(db-inblk)(db-io_data,rdptr,RxLen);dev-stats.rx_bytes+=RxLen;/*Passtoupperlayer*/skb-protocol=eth_type_trans(skb,dev);if(db-rx_csum)if(rxbyte&0 x1c)ip_summed=CHECKSUM_UNNECESSARY;elseskb-ip_summed=CHECKSUM

8、_NONE;netif_rx(skb);/*将skbuff结构体发送给上层*/dev-stats.rx_packets+;/*计数增1*/else/*needtodumpthepacketsdata*/*坏包,丢弃*/(db-dumpblk)(db-io_data,RxLen);while(rxbyte&DM9000_PKT_RDY);2、下面是完整的DM9000驱动代码,可以完整的查看cpp HYPERLINK :/ o view plain view plain HYPERLINK :/ o copy copy#include#include#include#include#include

9、#include#include#include#include#include#include#include#include#include#include#include#include#include#includedm9000.h#include#include#include/*Board/System/Debuginformation/definition-*/#defineDM9000_PHY0 x40/*PHYaddress0 x01*/#defineCARDNAMEdm9000#defineDRV_VERSION1.31/*Transmittimeout,default5s

10、econds.*/staticintwatchdog=5000;module_param(watchdog,int,0400);MODULE_PARM_DESC(watchdog,transmittimeoutinmilliseconds);/*DM9000registeraddresslocking.*TheDM9000usesanaddressregistertocontrolwheredatawritten*tothedataregistergoes.Thismeansthattheaddressregister*mustbepreservedoverinterruptsorsimila

11、rcalls.*Duringinterruptandothercriticalcalls,aspinlockisusedto*protectthesystem,butthecallsthemselvessavetheaddress*intheaddressregisterincasetheyareinterruptinganother*accesstothedevice.*Forgeneralaccessesalockisprovidedsothatcallswhichare*allowedtosleepareserialisedsothattheaddressregisterdoes*not

12、needtobesaved.Thislockalsoservestoserialiseaccess*totheEEPROMandPHYaccessregisterswhicharesharedbetween*thesetwodevices.*/*ThedriversupportstheoriginalDM9000E,andnowthetwonewer*devices,DM9000AandDM9000B.*/enumdm9000_typeTYPE_DM9000E,/*originalDM9000*/TYPE_DM9000A,TYPE_DM9000B;/*Structure/enumdeclara

13、tion-*/typedefstructboard_infovoid_iomem*io_addr;/*RegisterI/Obaseaddress*/void_iomem*io_data;/*DataI/Oaddress*/u16irq;/*IRQ*/u16tx_pkt_cnt;u16queue_pkt_len;u16queue_start_addr;u16queue_ip_summed;u16dbug_cnt;u8io_mode;/*0:word,2:byte*/u8phy_addr;u8imr_all;unsignedintflags;unsignedintin_suspend:1;uns

14、ignedintwake_supported:1;intdebug_level;enumdm9000_typetype;void(*inblk)(void_iomem*port,void*data,intlength);void(*outblk)(void_iomem*port,void*data,intlength);void(*dumpblk)(void_iomem*port,intlength);structdevice*dev;/*parentdevice*/structresource*addr_res;/*resourcesfound*/structresource*data_re

15、s;structresource*addr_req;/*resourcesrequested*/structresource*data_req;structresource*irq_res;intirq_wake;structmutexaddr_lock;/*phyandeepromaccesslock*/structdelayed_workphy_poll;structnet_device*ndev;spinlock_tlock;structmii_if_infomii;u32msg_enable;u32wake_state;intrx_csum;intcan_csum;intip_summ

16、ed;board_info_t;/*debugcode*/#definedm9000_dbg(db,lev,msg.)doif(lev)CONFIG_DM9000_DEBUGLEVEL&(lev)debug_level)dev_dbg(db-dev,msg);while(0)staticinlineboard_info_t*to_dm9000_board(structnet_device*dev)returnnetdev_priv(dev);/*DM9000networkboardroutine-*/staticvoiddm9000_reset(board_info_t*db)dev_dbg(

17、db-dev,resettingdevicen);/*RESETdevice*/writeb(DM9000_NCR,db-io_addr);udelay(200);writeb(NCR_RST,db-io_data);udelay(200);/*ReadabytefromI/Oport*/staticu8ior(board_info_t*db,intreg)writeb(reg,db-io_addr);returnreadb(db-io_data);/*WriteabytetoI/Oport*/staticvoidiow(board_info_t*db,intreg,intvalue)writ

18、eb(reg,db-io_addr);writeb(value,db-io_data);/*routinesforsendingblocktochip*/staticvoiddm9000_outblk_8bit(void_iomem*reg,void*data,intcount)writesb(reg,data,count);staticvoiddm9000_outblk_16bit(void_iomem*reg,void*data,intcount)writesw(reg,data,(count+1)1);staticvoiddm9000_outblk_32bit(void_iomem*re

19、g,void*data,intcount)writesl(reg,data,(count+3)2);/*inputblockfromchiptomemory*/staticvoiddm9000_inblk_8bit(void_iomem*reg,void*data,intcount)readsb(reg,data,count);staticvoiddm9000_inblk_16bit(void_iomem*reg,void*data,intcount)readsw(reg,data,(count+1)1);staticvoiddm9000_inblk_32bit(void_iomem*reg,

20、void*data,intcount)readsl(reg,data,(count+3)2);/*dumpblockfromchiptonull*/staticvoiddm9000_dumpblk_8bit(void_iomem*reg,intcount)inti;inttmp;for(i=0;i1;for(i=0;i2;for(i=0;idumpblk=dm9000_dumpblk_8bit;db-outblk=dm9000_outblk_8bit;db-inblk=dm9000_inblk_8bit;break;case3:dev_dbg(db-dev,:3byteIO,fallingba

21、ckto16bitn);case2:db-dumpblk=dm9000_dumpblk_16bit;db-outblk=dm9000_outblk_16bit;db-inblk=dm9000_inblk_16bit;break;case4:default:db-dumpblk=dm9000_dumpblk_32bit;db-outblk=dm9000_outblk_32bit;db-inblk=dm9000_inblk_32bit;break;staticvoiddm9000_schedule_poll(board_info_t*db)if(db-type=TYPE_DM9000E)sched

22、ule_delayed_work(&db-phy_poll,HZ*2);staticintdm9000_ioctl(structnet_device*dev,structifreq*req,intcmd)board_info_t*dm=to_dm9000_board(dev);if(!netif_running(dev)return-EINVAL;returngeneric_mii_ioctl(&dm-mii,if_mii(req),cmd,NULL);staticunsignedintdm9000_read_locked(board_info_t*db,intreg)unsignedlong

23、flags;unsignedintret;spin_lock_irqsave(&db-lock,flags);ret=ior(db,reg);spin_unlock_irqrestore(&db-lock,flags);returnret;staticintdm9000_wait_eeprom(board_info_t*db)unsignedintstatus;inttimeout=8;/*waitmax8msec*/*TheDM9000datasheetssayweshouldbeableto*polltheERREbitinEPCRtowaitfortheEEPROM*operation.

24、Fromtestingseveralchips,thisbit*doesnotseemtowork.*Weattempttousethebit,butfallbacktothe*timeout(whichiswhywedonotreturnanerror*onexpiry)tosaythattheEEPROMoperationhas*completed.*/while(1)status=dm9000_read_locked(db,DM9000_EPCR);if(status&EPCR_ERRE)=0)break;msleep(1);if(timeout-dev,timeoutwaitingEE

25、PROMn);break;return0;/*ReadaworddatafromEEPROM*/staticvoiddm9000_read_eeprom(board_info_t*db,intoffset,u8*to)unsignedlongflags;if(db-flags&DM9000_PLATF_NO_EEPROM)to0=0 xff;to1=0 xff;return;mutex_lock(&db-addr_lock);spin_lock_irqsave(&db-lock,flags);iow(db,DM9000_EPAR,offset);iow(db,DM9000_EPCR,EPCR_

26、ERPRR);spin_unlock_irqrestore(&db-lock,flags);dm9000_wait_eeprom(db);/*delayforat-least150uS*/msleep(1);spin_lock_irqsave(&db-lock,flags);iow(db,DM9000_EPCR,0 x0);to0=ior(db,DM9000_EPDRL);to1=ior(db,DM9000_EPDRH);spin_unlock_irqrestore(&db-lock,flags);mutex_unlock(&db-addr_lock);/*WriteaworddatatoSR

27、OM*/staticvoiddm9000_write_eeprom(board_info_t*db,intoffset,u8*data)unsignedlongflags;if(db-flags&DM9000_PLATF_NO_EEPROM)return;mutex_lock(&db-addr_lock);spin_lock_irqsave(&db-lock,flags);iow(db,DM9000_EPAR,offset);iow(db,DM9000_EPDRH,data1);iow(db,DM9000_EPDRL,data0);iow(db,DM9000_EPCR,EPCR_WEP|EPC

28、R_ERPRW);spin_unlock_irqrestore(&db-lock,flags);dm9000_wait_eeprom(db);mdelay(1);/*waitatleast150uStoclear*/spin_lock_irqsave(&db-lock,flags);iow(db,DM9000_EPCR,0);spin_unlock_irqrestore(&db-lock,flags);mutex_unlock(&db-addr_lock);/*ethtoolops*/staticvoiddm9000_get_drvinfo(structnet_device*dev,struc

29、tethtool_drvinfo*info)board_info_t*dm=to_dm9000_board(dev);strcpy(info-driver,CARDNAME);strcpy(info-version,DRV_VERSION);strcpy(info-bus_info,to_platform_device(dm-dev)-name);staticu32dm9000_get_msglevel(structnet_device*dev)board_info_t*dm=to_dm9000_board(dev);returndm-msg_enable;staticvoiddm9000_s

30、et_msglevel(structnet_device*dev,u32value)board_info_t*dm=to_dm9000_board(dev);dm-msg_enable=value;staticintdm9000_get_settings(structnet_device*dev,structethtool_cmd*cmd)board_info_t*dm=to_dm9000_board(dev);mii_ethtool_gset(&dm-mii,cmd);return0;staticintdm9000_set_settings(structnet_device*dev,stru

31、ctethtool_cmd*cmd)board_info_t*dm=to_dm9000_board(dev);returnmii_ethtool_sset(&dm-mii,cmd);staticintdm9000_nway_reset(structnet_device*dev)board_info_t*dm=to_dm9000_board(dev);returnmii_nway_restart(&dm-mii);staticuint32_tdm9000_get_rx_csum(structnet_device*dev)board_info_t*dm=to_dm9000_board(dev);r

32、eturndm-rx_csum;staticintdm9000_set_rx_csum_unlocked(structnet_device*dev,uint32_tdata)board_info_t*dm=to_dm9000_board(dev);if(dm-can_csum)dm-rx_csum=data;iow(dm,DM9000_RCSR,dm-rx_csum?RCSR_CSUM:0);return0;return-EOPNOTSUPP;staticintdm9000_set_rx_csum(structnet_device*dev,uint32_tdata)board_info_t*d

33、m=to_dm9000_board(dev);unsignedlongflags;intret;spin_lock_irqsave(&dm-lock,flags);ret=dm9000_set_rx_csum_unlocked(dev,data);spin_unlock_irqrestore(&dm-lock,flags);returnret;staticintdm9000_set_tx_csum(structnet_device*dev,uint32_tdata)board_info_t*dm=to_dm9000_board(dev);intret=-EOPNOTSUPP;if(dm-can

34、_csum)ret=ethtool_op_set_tx_csum(dev,data);returnret;staticu32dm9000_get_link(structnet_device*dev)board_info_t*dm=to_dm9000_board(dev);u32ret;if(dm-flags&DM9000_PLATF_EXT_PHY)ret=mii_link_ok(&dm-mii);elseret=dm9000_read_locked(dm,DM9000_NSR)&NSR_LINKST?1:0;returnret;#defineDM_EEPROM_MAGIC(0 x444D39

35、4B)staticintdm9000_get_eeprom_len(structnet_device*dev)return128;staticintdm9000_get_eeprom(structnet_device*dev,structethtool_eeprom*ee,u8*data)board_info_t*dm=to_dm9000_board(dev);intoffset=ee-offset;intlen=ee-len;inti;/*EEPROMaccessisalignedtotwobytes*/if(len&1)!=0|(offset&1)!=0)return-EINVAL;if(

36、dm-flags&DM9000_PLATF_NO_EEPROM)return-ENOENT;ee-magic=DM_EEPROM_MAGIC;for(i=0;ioffset;intlen=ee-len;inti;/*EEPROMaccessisalignedtotwobytes*/if(len&1)!=0|(offset&1)!=0)return-EINVAL;if(dm-flags&DM9000_PLATF_NO_EEPROM)return-ENOENT;if(ee-magic!=DM_EEPROM_MAGIC)return-EINVAL;for(i=0;isupported=dm-wake

37、_supported?WAKE_MAGIC:0;w-wolopts=dm-wake_state;staticintdm9000_set_wol(structnet_device*dev,structethtool_wolinfo*w)board_info_t*dm=to_dm9000_board(dev);unsignedlongflags;u32opts=w-wolopts;u32wcr=0;if(!dm-wake_supported)return-EOPNOTSUPP;if(opts&WAKE_MAGIC)return-EINVAL;if(opts&WAKE_MAGIC)wcr|=WCR_

38、MAGICEN;mutex_lock(&dm-addr_lock);spin_lock_irqsave(&dm-lock,flags);iow(dm,DM9000_WCR,wcr);spin_unlock_irqrestore(&dm-lock,flags);mutex_unlock(&dm-addr_lock);if(dm-wake_state!=opts)/*changeinwolstate,updateIRQstate*/if(!dm-wake_state)set_irq_wake(dm-irq_wake,1);elseif(dm-wake_state&!opts)set_irq_wak

39、e(dm-irq_wake,0);dm-wake_state=opts;return0;staticconststructethtool_opsdm9000_ethtool_ops=.get_drvinfo=dm9000_get_drvinfo,.get_settings=dm9000_get_settings,.set_settings=dm9000_set_settings,.get_msglevel=dm9000_get_msglevel,.set_msglevel=dm9000_set_msglevel,.nway_reset=dm9000_nway_reset,.get_link=d

40、m9000_get_link,.get_wol=dm9000_get_wol,.set_wol=dm9000_set_wol,.get_eeprom_len=dm9000_get_eeprom_len,.get_eeprom=dm9000_get_eeprom,.set_eeprom=dm9000_set_eeprom,.get_rx_csum=dm9000_get_rx_csum,.set_rx_csum=dm9000_set_rx_csum,.get_tx_csum=ethtool_op_get_tx_csum,.set_tx_csum=dm9000_set_tx_csum,;static

41、voiddm9000_show_carrier(board_info_t*db,unsignedcarrier,unsignednsr)structnet_device*ndev=db-ndev;unsignedncr=dm9000_read_locked(db,DM9000_NCR);if(carrier)dev_info(db-dev,%s:linkup,%dMbps,%s-duplex,noLPAn,ndev-name,(nsr&NSR_SPEED)?10:100,(ncr&NCR_FDX)?full:half);elsedev_info(db-dev,%s:linkdownn,ndev

42、-name);staticvoiddm9000_poll_work(structwork_struct*w)structdelayed_work*dw=to_delayed_work(w);board_info_t*db=container_of(dw,board_info_t,phy_poll);structnet_device*ndev=db-ndev;if(db-flags&DM9000_PLATF_SIMPLE_PHY&!(db-flags&DM9000_PLATF_EXT_PHY)unsignednsr=dm9000_read_locked(db,DM9000_NSR);unsign

43、edold_carrier=netif_carrier_ok(ndev)?1:0;unsignednew_carrier;new_carrier=(nsr&NSR_LINKST)?1:0;if(old_carrier!=new_carrier)if(netif_msg_link(db)dm9000_show_carrier(db,new_carrier,nsr);if(!new_carrier)netif_carrier_off(ndev);elsenetif_carrier_on(ndev);elsemii_check_media(&db-mii,netif_msg_link(db),0);

44、if(netif_running(ndev)dm9000_schedule_poll(db);/*dm9000_release_board*releaseaboard,andanymappedresources*/staticvoiddm9000_release_board(structplatform_device*pdev,structboard_info*db)/*unmapourresources*/iounmap(db-io_addr);iounmap(db-io_data);/*releasetheresources*/release_resource(db-data_req);k

45、free(db-data_req);release_resource(db-addr_req);kfree(db-addr_req);staticunsignedchardm9000_type_to_char(enumdm9000_typetype)switch(type)caseTYPE_DM9000E:returne;caseTYPE_DM9000A:returna;caseTYPE_DM9000B:returnb;return?;/*SetDM9000multicastaddress*/staticvoiddm9000_hash_table_unlocked(structnet_devi

46、ce*dev)board_info_t*db=netdev_priv(dev);structnetdev_hw_addr*ha;inti,oft;u32hash_val;u16hash_table4;u8rcr=RCR_DIS_LONG|RCR_DIS_CRC|RCR_RXEN;dm9000_dbg(db,1,entering%sn,_func_);for(i=0,oft=DM9000_PAR;idev_addri);/*ClearHashTable*/for(i=0;iflags&IFF_PROMISC)rcr|=RCR_PRMSC;if(dev-flags&IFF_ALLMULTI)rcr

47、|=RCR_ALL;/*themulticastaddressinHashTable:64bits*/netdev_for_each_mc_addr(ha,dev)hash_val=ether_crc_le(6,ha-addr)&0 x3f;hash_tablehash_val/16|=(u16)1(hash_val%16);/*WritethehashtabletoMACMDtable*/for(i=0,oft=DM9000_MAR;i8);iow(db,DM9000_RCR,rcr);staticvoiddm9000_hash_table(structnet_device*dev)boar

48、d_info_t*db=netdev_priv(dev);unsignedlongflags;spin_lock_irqsave(&db-lock,flags);dm9000_hash_table_unlocked(dev);spin_unlock_irqrestore(&db-lock,flags);/*Initializedm9000board*/staticvoiddm9000_init_dm9000(structnet_device*dev)board_info_t*db=netdev_priv(dev);unsignedintimr;unsignedintncr;dm9000_dbg

49、(db,1,entering%sn,_func_);/*I/Omode*/db-io_mode=ior(db,DM9000_ISR)6;/*ISRbit7:6keepsI/Omode*/*Checksummode*/dm9000_set_rx_csum_unlocked(dev,db-rx_csum);/*GPIO0onpre-activatePHY*/iow(db,DM9000_GPR,0);/*REG_1Fbit0activatephyxcer*/iow(db,DM9000_GPCR,GPCR_GEP_CNTL);/*LetGPIO0output*/iow(db,DM9000_GPR,0)

50、;/*EnablePHY*/ncr=(db-flags&DM9000_PLATF_EXT_PHY)?NCR_EXT_PHY:0;/*ifwolisneeded,thenalwayssetNCR_WAKEENotherwiseweend*updumpingthewakeeventsifwedisablethis.Thereisalready*awake-maskinDM9000_WCR*/if(db-wake_supported)ncr|=NCR_WAKEEN;iow(db,DM9000_NCR,ncr);/*Programoperatingregister*/iow(db,DM9000_TCR

51、,0);/*TXPollingclear*/iow(db,DM9000_BPTR,0 x3f);/*Less3Kb,200us*/iow(db,DM9000_FCR,0 xff);/*FlowControl*/iow(db,DM9000_SMCR,0);/*SpecialMode*/*clearTXstatus*/iow(db,DM9000_NSR,NSR_WAKEST|NSR_TX2END|NSR_TX1END);iow(db,DM9000_ISR,ISR_CLR_STATUS);/*Clearinterruptstatus*/*Setaddressfiltertable*/dm9000_h

52、ash_table_unlocked(dev);imr=IMR_PAR|IMR_PTM|IMR_PRM;if(db-type!=TYPE_DM9000E)imr|=IMR_LNKCHNG;db-imr_all=imr;/*EnableTX/RXinterruptmask*/iow(db,DM9000_IMR,imr);/*InitDrivervariable*/db-tx_pkt_cnt=0;db-queue_pkt_len=0;dev-trans_start=jiffies;/*Ourwatchdogtimedout.Calledbythenetworkinglayer*/staticvoi

53、ddm9000_timeout(structnet_device*dev)board_info_t*db=netdev_priv(dev);u8reg_save;unsignedlongflags;/*Savepreviousregisteraddress*/reg_save=readb(db-io_addr);spin_lock_irqsave(&db-lock,flags);netif_stop_queue(dev);dm9000_reset(db);dm9000_init_dm9000(dev);/*WecanacceptTXpacketsagain*/dev-trans_start=j

54、iffies;/*preventtxtimeout*/netif_wake_queue(dev);/*Restorepreviousregisteraddress*/writeb(reg_save,db-io_addr);spin_unlock_irqrestore(&db-lock,flags);staticvoiddm9000_send_packet(structnet_device*dev,intip_summed,u16pkt_len)board_info_t*dm=to_dm9000_board(dev);/*TheDM9000isnotsmartenoughtoleavefragm

55、entedpacketsalone.*/if(dm-ip_summed!=ip_summed)if(ip_summed=CHECKSUM_NONE)iow(dm,DM9000_TCCR,0);elseiow(dm,DM9000_TCCR,TCCR_IP|TCCR_UDP|TCCR_TCP);dm-ip_summed=ip_summed;/*SetTXlengthtoDM9000*/*设置TX数据的长度到寄存器TXPLL和TXPLH*/iow(dm,DM9000_TXPLL,pkt_len);iow(dm,DM9000_TXPLH,pkt_len8);/*IssueTXpollingcomman

56、d*/*设置发送控制寄存器的发送请求位*/iow(dm,DM9000_TCR,TCR_TXREQ);/*ClearedafterTXcomplete*/*Hardwarestarttransmission.*Sendapackettomediafromtheupperlayer.*/staticintdm9000_start_xmit(structsk_buff*skb,structnet_device*dev)unsignedlongflags;board_info_t*db=netdev_priv(dev);/*获取网卡虽有信息的存储结构信息的地址*/dm9000_dbg(db,3,%s:

57、n,_func_);if(db-tx_pkt_cnt1)returnNETDEV_TX_BUSY;spin_lock_irqsave(&db-lock,flags);/*获得自旋锁*/*MovedatatoDM9000TXRAM*/*MWCMD即MemorydatawritecommandwithaddressincrementRegister(F8H)*根据IO操作模式(8-bitor16-bit)来增加写指针1或2*/writeb(DM9000_MWCMD,db-io_addr);(db-outblk)(db-io_data,skb-data,skb-len);/*将数据从sk_buff中

58、copy到网卡的TXSRAM中*/dev-stats.tx_bytes+=skb-len;/*统计发送的字节数*/db-tx_pkt_cnt+;/*待发送计数*/*TXcontrol:Firstpacketimmediatelysend,secondpacketqueue*/if(db-tx_pkt_cnt=1)dm9000_send_packet(dev,skb-ip_summed,skb-len);/*如果计数为1,直接发送*/else/*如果是第2个,则*/*Secondpacket*/db-queue_pkt_len=skb-len;db-queue_ip_summed=skb-ip_

59、summed;netif_stop_queue(dev);/*告诉上层停止发送*/spin_unlock_irqrestore(&db-lock,flags);/*解锁*/*freethisSKB,释放SKB*/dev_kfree_skb(skb);returnNETDEV_TX_OK;/*DM9000interrupthandler*receivethepackettoupperlayer,freethetransmittedpacket*/staticvoiddm9000_tx_done(structnet_device*dev,board_info_t*db)inttx_status=i

60、or(db,DM9000_NSR);/*GotTXstatus*/if(tx_status&(NSR_TX2END|NSR_TX1END)/*第一个或第二个数据包发送完毕*/*Onepacketsentcomplete*/db-tx_pkt_cnt-;/*待发送的数据包个数减1*/dev-stats.tx_packets+;/*发送的数据包加1*/if(netif_msg_tx_done(db)dev_dbg(db-dev,txdone,NSR%02xn,tx_status);/*Queuepacketcheck&send*/if(db-tx_pkt_cnt0)/*如果还有数据包*/dm900

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论