ARMLinux驱动DM9000网卡驱动分析(四).doc_第1页
ARMLinux驱动DM9000网卡驱动分析(四).doc_第2页
ARMLinux驱动DM9000网卡驱动分析(四).doc_第3页
ARMLinux驱动DM9000网卡驱动分析(四).doc_第4页
ARMLinux驱动DM9000网卡驱动分析(四).doc_第5页
免费预览已结束,剩余47页可下载查看

下载本文档

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

文档简介

ARM-Linux驱动-DM9000网卡驱动分析(四)1、接下来接着分析DM9000网卡驱动的数据接收函数cppview plaincopy1. /*2. *Receivedapacketandpasstoupperlayer3. *接收数据包,将数据包传递给上层4. */5. staticvoid6. dm9000_rx(structnet_device*dev)7. 8. board_info_t*db=netdev_priv(dev);/*得到网卡私有信息数据结构的首地址*/9. structdm9000_rxhdrrxhdr;/*该结构体封装了dm9000接收的数据包信息*/10. structsk_buff*skb;11. u8rxbyte,*rdptr;12. boolGoodPacket;13. intRxLen;14. 15. /*Checkpacketreadyornot*/16. do17. /*MRCMDX是内存数据预取读命令*/18. ior(db,DM9000_MRCMDX);/*Dummyread*/19. /*Getmostupdateddata*/20. rxbyte=readb(db-io_data);21. 22. /*Statuscheck:thisbytemustbe0or1*/23. /*DM9000_PKT_ERR0x02,表示接收出错*/24. if(rxbyte&DM9000_PKT_ERR)25. dev_warn(db-dev,statuscheckfail:%dn,rxbyte);/*输出提示信息*/26. iow(db,DM9000_RCR,0x00);/*StopDevice关闭设备*/27. iow(db,DM9000_ISR,IMR_PAR);/*StopINTrequest停止中断请求*/28. return;29. 30. 31. /*DM9000_PKT_RDY0x01没有准备好,直接返回*/32. if(!(rxbyte&DM9000_PKT_RDY)33. return;34. 35. /*Apacketreadynow&Getstatus/length*/36. GoodPacket=true;37. writeb(DM9000_MRCMD,db-io_addr);/*MRCMD是地址增加的数据读取命令*/38. 39. (db-inblk)(db-io_data,&rxhdr,sizeof(rxhdr);/*读取数据,从RX_SRAM到rxhdr结构体中*/40. 41. RxLen=le16_to_cpu(rxhdr.RxLen);42. 43. if(netif_msg_rx_status(db)44. dev_dbg(db-dev,RX:status%02x,length%04xn,45. rxhdr.RxStatus,RxLen);46. 47. /*PacketStatuscheck,检查包的完整性*/48. if(RxLendev,RX:BadPacket(runt)n);52. 53. /*如果数据长度大于DM9000_PKT_MAX,即1536*/54. if(RxLenDM9000_PKT_MAX)55. dev_dbg(db-dev,RST:RXLen:%xn,RxLen);56. 57. 58. /*rxhdr.RxStatusisidenticaltoRSRregister.*/59. /*这里也是包的检查*/60. if(rxhdr.RxStatus&(RSR_FOE|RSR_CE|RSR_AE|61. RSR_PLE|RSR_RWTO|62. RSR_LCS|RSR_RF)63. GoodPacket=false;64. if(rxhdr.RxStatus&RSR_FOE)65. if(netif_msg_rx_err(db)66. dev_dbg(db-dev,fifoerrorn);67. dev-stats.rx_fifo_errors+;68. 69. if(rxhdr.RxStatus&RSR_CE)70. if(netif_msg_rx_err(db)71. dev_dbg(db-dev,crcerrorn);72. dev-stats.rx_crc_errors+;73. 74. if(rxhdr.RxStatus&RSR_RF)75. if(netif_msg_rx_err(db)76. dev_dbg(db-dev,lengtherrorn);77. dev-stats.rx_length_errors+;78. 79. 80. 81. /*MovedatafromDM9000,从DM9000获取数据*/82. if(GoodPacket&83. (skb=dev_alloc_skb(RxLen+4)!=NULL)84. skb_reserve(skb,2);85. rdptr=(u8*)skb_put(skb,RxLen-4);86. 87. /*ReadreceivedpacketfromRXSRAM*/88. /*将RXSRAM中的数据读取到skbuff结构体*/89. (db-inblk)(db-io_data,rdptr,RxLen);90. dev-stats.rx_bytes+=RxLen;91. 92. /*Passtoupperlayer*/93. skb-protocol=eth_type_trans(skb,dev);94. if(db-rx_csum)95. if(rxbyte&0x1c)ip_summed=CHECKSUM_UNNECESSARY;97. else98. skb-ip_summed=CHECKSUM_NONE;99. 100. netif_rx(skb);/*将skbuff结构体发送给上层*/101. dev-stats.rx_packets+;/*计数增1*/102. 103. else104. /*needtodumpthepacketsdata*/105. /*坏包,丢弃*/106. (db-dumpblk)(db-io_data,RxLen);107. 108. while(rxbyte&DM9000_PKT_RDY);109. 2、下面是完整的DM9000驱动代码,可以完整的查看cppview plaincopy1. #include2. #include3. #include4. #include5. #include6. #include7. #include8. #include9. #include10. #include11. #include12. #include13. #include14. #include15. #include16. 17. #include18. #include19. #include20. 21. #includedm9000.h22. 23. #include24. #include25. #include26. 27. /*Board/System/Debuginformation/definition-*/28. 29. #defineDM9000_PHY0x40/*PHYaddress0x01*/30. 31. #defineCARDNAMEdm900032. #defineDRV_VERSION1.3133. 34. /*35. *Transmittimeout,default5seconds.36. */37. staticintwatchdog=5000;38. module_param(watchdog,int,0400);39. MODULE_PARM_DESC(watchdog,transmittimeoutinmilliseconds);40. 41. /*DM9000registeraddresslocking.42. *43. *TheDM9000usesanaddressregistertocontrolwheredatawritten44. *tothedataregistergoes.Thismeansthattheaddressregister45. *mustbepreservedoverinterruptsorsimilarcalls.46. *47. *Duringinterruptandothercriticalcalls,aspinlockisusedto48. *protectthesystem,butthecallsthemselvessavetheaddress49. *intheaddressregisterincasetheyareinterruptinganother50. *accesstothedevice.51. *52. *Forgeneralaccessesalockisprovidedsothatcallswhichare53. *allowedtosleepareserialisedsothattheaddressregisterdoes54. *notneedtobesaved.Thislockalsoservestoserialiseaccess55. *totheEEPROMandPHYaccessregisterswhicharesharedbetween56. *thesetwodevices.57. */58. 59. /*ThedriversupportstheoriginalDM9000E,andnowthetwonewer60. *devices,DM9000AandDM9000B.61. */62. 63. enumdm9000_type64. TYPE_DM9000E,/*originalDM9000*/65. TYPE_DM9000A,66. TYPE_DM9000B67. ;68. 69. /*Structure/enumdeclaration-*/70. typedefstructboard_info71. 72. void_iomem*io_addr;/*RegisterI/Obaseaddress*/73. void_iomem*io_data;/*DataI/Oaddress*/74. u16irq;/*IRQ*/75. 76. u16tx_pkt_cnt;77. u16queue_pkt_len;78. u16queue_start_addr;79. u16queue_ip_summed;80. u16dbug_cnt;81. u8io_mode;/*0:word,2:byte*/82. u8phy_addr;83. u8imr_all;84. 85. unsignedintflags;86. unsignedintin_suspend:1;87. unsignedintwake_supported:1;88. intdebug_level;89. 90. enumdm9000_typetype;91. 92. void(*inblk)(void_iomem*port,void*data,intlength);93. void(*outblk)(void_iomem*port,void*data,intlength);94. void(*dumpblk)(void_iomem*port,intlength);95. 96. structdevice*dev;/*parentdevice*/97. 98. structresource*addr_res;/*resourcesfound*/99. structresource*data_res;100. structresource*addr_req;/*resourcesrequested*/101. structresource*data_req;102. structresource*irq_res;103. 104. intirq_wake;105. 106. structmutexaddr_lock;/*phyandeepromaccesslock*/107. 108. structdelayed_workphy_poll;109. structnet_device*ndev;110. 111. spinlock_tlock;112. 113. structmii_if_infomii;114. u32msg_enable;115. u32wake_state;116. 117. intrx_csum;118. intcan_csum;119. intip_summed;120. board_info_t;121. 122. /*debugcode*/123. 124. #definedm9000_dbg(db,lev,msg.)do125. if(lev)CONFIG_DM9000_DEBUGLEVEL&126. (lev)debug_level)127. dev_dbg(db-dev,msg);128. 129. while(0)130. 131. staticinlineboard_info_t*to_dm9000_board(structnet_device*dev)132. 133. returnnetdev_priv(dev);134. 135. 136. /*DM9000networkboardroutine-*/137. 138. staticvoid139. dm9000_reset(board_info_t*db)140. 141. dev_dbg(db-dev,resettingdevicen);142. 143. /*RESETdevice*/144. writeb(DM9000_NCR,db-io_addr);145. udelay(200);146. writeb(NCR_RST,db-io_data);147. udelay(200);148. 149. 150. /*151. *ReadabytefromI/Oport152. */153. staticu8154. ior(board_info_t*db,intreg)155. 156. writeb(reg,db-io_addr);157. returnreadb(db-io_data);158. 159. 160. /*161. *WriteabytetoI/Oport162. */163. 164. staticvoid165. iow(board_info_t*db,intreg,intvalue)166. 167. writeb(reg,db-io_addr);168. writeb(value,db-io_data);169. 170. 171. /*routinesforsendingblocktochip*/172. 173. staticvoiddm9000_outblk_8bit(void_iomem*reg,void*data,intcount)174. 175. writesb(reg,data,count);176. 177. 178. staticvoiddm9000_outblk_16bit(void_iomem*reg,void*data,intcount)179. 180. writesw(reg,data,(count+1)1);181. 182. 183. staticvoiddm9000_outblk_32bit(void_iomem*reg,void*data,intcount)184. 185. writesl(reg,data,(count+3)2);186. 187. 188. /*inputblockfromchiptomemory*/189. 190. staticvoiddm9000_inblk_8bit(void_iomem*reg,void*data,intcount)191. 192. readsb(reg,data,count);193. 194. 195. 196. staticvoiddm9000_inblk_16bit(void_iomem*reg,void*data,intcount)197. 198. readsw(reg,data,(count+1)1);199. 200. 201. staticvoiddm9000_inblk_32bit(void_iomem*reg,void*data,intcount)202. 203. readsl(reg,data,(count+3)2);204. 205. 206. /*dumpblockfromchiptonull*/207. 208. staticvoiddm9000_dumpblk_8bit(void_iomem*reg,intcount)209. 210. inti;211. inttmp;212. 213. for(i=0;i1;223. 224. for(i=0;i2;234. 235. for(i=0;idumpblk=dm9000_dumpblk_8bit;254. db-outblk=dm9000_outblk_8bit;255. db-inblk=dm9000_inblk_8bit;256. break;257. 258. 259. case3:260. dev_dbg(db-dev,:3byteIO,fallingbackto16bitn);261. case2:262. db-dumpblk=dm9000_dumpblk_16bit;263. db-outblk=dm9000_outblk_16bit;264. db-inblk=dm9000_inblk_16bit;265. break;266. 267. case4:268. default:269. db-dumpblk=dm9000_dumpblk_32bit;270. db-outblk=dm9000_outblk_32bit;271. db-inblk=dm9000_inblk_32bit;272. break;273. 274. 275. 276. staticvoiddm9000_schedule_poll(board_info_t*db)277. 278. if(db-type=TYPE_DM9000E)279. schedule_delayed_work(&db-phy_poll,HZ*2);280. 281. 282. staticintdm9000_ioctl(structnet_device*dev,structifreq*req,intcmd)283. 284. board_info_t*dm=to_dm9000_board(dev);285. 286. if(!netif_running(dev)287. return-EINVAL;288. 289. returngeneric_mii_ioctl(&dm-mii,if_mii(req),cmd,NULL);290. 291. 292. staticunsignedint293. dm9000_read_locked(board_info_t*db,intreg)294. 295. unsignedlongflags;296. unsignedintret;297. 298. spin_lock_irqsave(&db-lock,flags);299. ret=ior(db,reg);300. spin_unlock_irqrestore(&db-lock,flags);301. 302. returnret;303. 304. 305. staticintdm9000_wait_eeprom(board_info_t*db)306. 307. unsignedintstatus;308. inttimeout=8;/*waitmax8msec*/309. 310. /*TheDM9000datasheetssayweshouldbeableto311. *polltheERREbitinEPCRtowaitfortheEEPROM312. *operation.Fromtestingseveralchips,thisbit313. *doesnotseemtowork.314. *315. *Weattempttousethebit,butfallbacktothe316. *timeout(whichiswhywedonotreturnanerror317. *onexpiry)tosaythattheEEPROMoperationhas318. *completed.319. */320. 321. while(1)322. status=dm9000_read_locked(db,DM9000_EPCR);323. 324. if(status&EPCR_ERRE)=0)325. break;326. 327. msleep(1);328. 329. if(timeout-dev,timeoutwaitingEEPROMn);331. break;332. 333. 334. 335. return0;336. 337. 338. /*339. *ReadaworddatafromEEPROM340. */341. staticvoid342. dm9000_read_eeprom(board_info_t*db,intoffset,u8*to)343. 344. unsignedlongflags;345. 346. if(db-flags&DM9000_PLATF_NO_EEPROM)347. to0=0xff;348. to1=0xff;349. return;350. 351. 352. mutex_lock(&db-addr_lock);353. 354. spin_lock_irqsave(&db-lock,flags);355. 356. iow(db,DM9000_EPAR,offset);357. iow(db,DM9000_EPCR,EPCR_ERPRR);358. 359. spin_unlock_irqrestore(&db-lock,flags);360. 361. dm9000_wait_eeprom(db);362. 363. /*delayforat-least150uS*/364. msleep(1);365. 366. spin_lock_irqsave(&db-lock,flags);367. 368. iow(db,DM9000_EPCR,0x0);369. 370. to0=ior(db,DM9000_EPDRL);371. to1=ior(db,DM9000_EPDRH);372. 373. spin_unlock_irqrestore(&db-lock,flags);374. 375. mutex_unlock(&db-addr_lock);376. 377. 378. /*379. *WriteaworddatatoSROM380. */381. staticvoid382. dm9000_write_eeprom(board_info_t*db,intoffset,u8*data)383. 384. unsignedlongflags;385. 386. if(db-flags&DM9000_PLATF_NO_EEPROM)387. return;388. 389. mutex_lock(&db-addr_lock);390. 391. spin_lock_irqsave(&db-lock,flags);392. iow(db,DM9000_EPAR,offset);393. iow(db,DM9000_EPDRH,data1);394. iow(db,DM9000_EPDRL,data0);395. iow(db,DM9000_EPCR,EPCR_WEP|EPCR_ERPRW);396. spin_unlock_irqrestore(&db-lock,flags);397. 398. dm9000_wait_eeprom(db);399. 400. mdelay(1);/*waitatleast150uStoclear*/401. 402. spin_lock_irqsave(&db-lock,flags);403. iow(db,DM9000_EPCR,0);404. spin_unlock_irqrestore(&db-lock,flags);405. 406. mutex_unlock(&db-addr_lock);407. 408. 409. /*ethtoolops*/410. 411. staticvoiddm9000_get_drvinfo(structnet_device*dev,412. structethtool_drvinfo*info)413. 414. board_info_t*dm=to_dm9000_board(dev);415. 416. strcpy(info-driver,CARDNAME);417. strcpy(info-version,DRV_VERSION);418. strcpy(info-bus_info,to_platform_device(dm-dev)-name);419. 420. 421. staticu32dm9000_get_msglevel(structnet_device*dev)422. 423. board_info_t*dm=to_dm9000_board(dev);424. 425. returndm-msg_enable;426. 427. 428. staticvoiddm9000_set_msglevel(structnet_device*dev,u32value)429. 430. board_info_t*dm=to_dm9000_board(dev);431. 432. dm-msg_enable=value;433. 434. 435. staticintdm9000_get_settings(structnet_device*dev,structethtool_cmd*cmd)436. 437. board_info_t*dm=to_dm9000_board(dev);438. 439. mii_ethtool_gset(&dm-mii,cmd);440. return0;441. 442. 443. staticintdm9000_set_settings(structnet_device*dev,structethtool_cmd*cmd)444. 445. board_info_t*dm=to_dm9000_board(dev);446. 447. returnmii_ethtool_sset(&dm-mii,cmd);44

温馨提示

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

评论

0/150

提交评论