etherelnk3.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931
  1. /*
  2. * Etherlink III, Fast EtherLink and Fast EtherLink XL adapters.
  3. * To do:
  4. * check robustness in the face of errors (e.g. busmaster & rxUnderrun);
  5. * RxEarly and busmaster;
  6. * autoSelect;
  7. * PCI latency timer and master enable;
  8. * errata list;
  9. * rewrite all initialisation.
  10. *
  11. * Product ID:
  12. * 9150 ISA 3C509[B]
  13. * 9050 ISA 3C509[B]-TP
  14. * 9450 ISA 3C509[B]-COMBO
  15. * 9550 ISA 3C509[B]-TPO
  16. *
  17. * 9350 EISA 3C579
  18. * 9250 EISA 3C579-TP
  19. *
  20. * 5920 EISA 3C592-[TP|COMBO|TPO]
  21. * 5970 EISA 3C597-TX Fast Etherlink 10BASE-T/100BASE-TX
  22. * 5971 EISA 3C597-T4 Fast Etherlink 10BASE-T/100BASE-T4
  23. * 5972 EISA 3C597-MII Fast Etherlink 10BASE-T/MII
  24. *
  25. * 5900 PCI 3C590-[TP|COMBO|TPO]
  26. * 5950 PCI 3C595-TX Fast Etherlink Shared 10BASE-T/100BASE-TX
  27. * 5951 PCI 3C595-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4
  28. * 5952 PCI 3C595-MII Fast Etherlink 10BASE-T/MII
  29. *
  30. * 9000 PCI 3C900-TPO Etherlink III XL PCI 10BASE-T
  31. * 9001 PCI 3C900-COMBO Etherlink III XL PCI 10BASE-T/10BASE-2/AUI
  32. * 9005 PCI 3C900B-COMBO Etherlink III XL PCI 10BASE-T/10BASE-2/AUI
  33. * 9050 PCI 3C905-TX Fast Etherlink XL Shared 10BASE-T/100BASE-TX
  34. * 9051 PCI 3C905-T4 Fast Etherlink Shared 10BASE-T/100BASE-T4
  35. * 9055 PCI 3C905B-TX Fast Etherlink Shared 10BASE-T/100BASE-TX
  36. * 9200 PCI 3C905C-TX Fast Etherlink Shared 10BASE-T/100BASE-TX
  37. *
  38. * 9058 PCMCIA 3C589[B]-[TP|COMBO]
  39. *
  40. * 627C MCA 3C529
  41. * 627D MCA 3C529-TP
  42. */
  43. #include "u.h"
  44. #include "lib.h"
  45. #include "mem.h"
  46. #include "dat.h"
  47. #include "fns.h"
  48. #include "io.h"
  49. #include "etherif.h"
  50. #define XCVRDEBUG if(0)print
  51. enum {
  52. IDport = 0x0110, /* anywhere between 0x0100 and 0x01F0 */
  53. };
  54. enum { /* all windows */
  55. CommandR = 0x000E,
  56. IntStatusR = 0x000E,
  57. };
  58. enum { /* Commands */
  59. GlobalReset = 0x0000,
  60. SelectRegisterWindow = 0x0001,
  61. EnableDcConverter = 0x0002,
  62. RxDisable = 0x0003,
  63. RxEnable = 0x0004,
  64. RxReset = 0x0005,
  65. Stall = 0x0006, /* 3C90x */
  66. TxDone = 0x0007,
  67. RxDiscard = 0x0008,
  68. TxEnable = 0x0009,
  69. TxDisable = 0x000A,
  70. TxReset = 0x000B,
  71. RequestInterrupt = 0x000C,
  72. AcknowledgeInterrupt = 0x000D,
  73. SetInterruptEnable = 0x000E,
  74. SetIndicationEnable = 0x000F, /* SetReadZeroMask */
  75. SetRxFilter = 0x0010,
  76. SetRxEarlyThresh = 0x0011,
  77. SetTxAvailableThresh = 0x0012,
  78. SetTxStartThresh = 0x0013,
  79. StartDma = 0x0014, /* initiate busmaster operation */
  80. StatisticsEnable = 0x0015,
  81. StatisticsDisable = 0x0016,
  82. DisableDcConverter = 0x0017,
  83. SetTxReclaimThresh = 0x0018, /* PIO-only adapters */
  84. PowerUp = 0x001B, /* not all adapters */
  85. PowerDownFull = 0x001C, /* not all adapters */
  86. PowerAuto = 0x001D, /* not all adapters */
  87. };
  88. enum { /* (Global|Rx|Tx)Reset command bits */
  89. tpAuiReset = 0x0001, /* 10BaseT and AUI transceivers */
  90. endecReset = 0x0002, /* internal Ethernet encoder/decoder */
  91. networkReset = 0x0004, /* network interface logic */
  92. fifoReset = 0x0008, /* FIFO control logic */
  93. aismReset = 0x0010, /* autoinitialise state-machine logic */
  94. hostReset = 0x0020, /* bus interface logic */
  95. dmaReset = 0x0040, /* bus master logic */
  96. vcoReset = 0x0080, /* on-board 10Mbps VCO */
  97. updnReset = 0x0100, /* upload/download (Rx/TX) logic */
  98. resetMask = 0x01FF,
  99. };
  100. enum { /* Stall command bits */
  101. upStall = 0x0000,
  102. upUnStall = 0x0001,
  103. dnStall = 0x0002,
  104. dnUnStall = 0x0003,
  105. };
  106. enum { /* SetRxFilter command bits */
  107. receiveIndividual = 0x0001, /* match station address */
  108. receiveMulticast = 0x0002,
  109. receiveBroadcast = 0x0004,
  110. receiveAllFrames = 0x0008, /* promiscuous */
  111. };
  112. enum { /* StartDma command bits */
  113. Upload = 0x0000, /* transfer data from adapter to memory */
  114. Download = 0x0001, /* transfer data from memory to adapter */
  115. };
  116. enum { /* IntStatus bits */
  117. interruptLatch = 0x0001,
  118. hostError = 0x0002, /* Adapter Failure */
  119. txComplete = 0x0004,
  120. txAvailable = 0x0008,
  121. rxComplete = 0x0010,
  122. rxEarly = 0x0020,
  123. intRequested = 0x0040,
  124. updateStats = 0x0080,
  125. transferInt = 0x0100, /* Bus Master Transfer Complete */
  126. dnComplete = 0x0200,
  127. upComplete = 0x0400,
  128. busMasterInProgress = 0x0800,
  129. commandInProgress = 0x1000,
  130. interruptMask = 0x07FE,
  131. };
  132. #define COMMAND(port, cmd, a) outs((port)+CommandR, ((cmd)<<11)|(a))
  133. #define STATUS(port) ins((port)+IntStatusR)
  134. enum { /* Window 0 - setup */
  135. Wsetup = 0x0000,
  136. /* registers */
  137. ManufacturerID = 0x0000, /* 3C5[08]*, 3C59[27] */
  138. ProductID = 0x0002, /* 3C5[08]*, 3C59[27] */
  139. ConfigControl = 0x0004, /* 3C5[08]*, 3C59[27] */
  140. AddressConfig = 0x0006, /* 3C5[08]*, 3C59[27] */
  141. ResourceConfig = 0x0008, /* 3C5[08]*, 3C59[27] */
  142. EepromCommand = 0x000A,
  143. EepromData = 0x000C,
  144. /* AddressConfig Bits */
  145. autoSelect9 = 0x0080,
  146. xcvrMask9 = 0xC000,
  147. /* ConfigControl bits */
  148. Ena = 0x0001,
  149. base10TAvailable9 = 0x0200,
  150. coaxAvailable9 = 0x1000,
  151. auiAvailable9 = 0x2000,
  152. /* EepromCommand bits */
  153. EepromReadRegister = 0x0080,
  154. EepromReadOffRegister = 0x00B0,
  155. EepromRead8bRegister = 0x0230,
  156. EepromBusy = 0x8000,
  157. };
  158. #define EEPROMCMD(port, cmd, a) outs((port)+EepromCommand, (cmd)|(a))
  159. #define EEPROMBUSY(port) (ins((port)+EepromCommand) & EepromBusy)
  160. #define EEPROMDATA(port) ins((port)+EepromData)
  161. enum { /* Window 1 - operating set */
  162. Wop = 0x0001,
  163. /* registers */
  164. Fifo = 0x0000,
  165. RxError = 0x0004, /* 3C59[0257] only */
  166. RxStatus = 0x0008,
  167. Timer = 0x000A,
  168. TxStatus = 0x000B,
  169. TxFree = 0x000C,
  170. /* RxError bits */
  171. rxOverrun = 0x0001,
  172. runtFrame = 0x0002,
  173. alignmentError = 0x0004, /* Framing */
  174. crcError = 0x0008,
  175. oversizedFrame = 0x0010,
  176. dribbleBits = 0x0080,
  177. /* RxStatus bits */
  178. rxBytes = 0x1FFF, /* 3C59[0257] mask */
  179. rxBytes9 = 0x07FF, /* 3C5[078]9 mask */
  180. rxError9 = 0x3800, /* 3C5[078]9 error mask */
  181. rxOverrun9 = 0x0000,
  182. oversizedFrame9 = 0x0800,
  183. dribbleBits9 = 0x1000,
  184. runtFrame9 = 0x1800,
  185. alignmentError9 = 0x2000, /* Framing */
  186. crcError9 = 0x2800,
  187. rxError = 0x4000,
  188. rxIncomplete = 0x8000,
  189. /* TxStatus Bits */
  190. txStatusOverflow = 0x0004,
  191. maxCollisions = 0x0008,
  192. txUnderrun = 0x0010,
  193. txJabber = 0x0020,
  194. interruptRequested = 0x0040,
  195. txStatusComplete = 0x0080,
  196. };
  197. enum { /* Window 2 - station address */
  198. Wstation = 0x0002,
  199. ResetOp905B = 0x000C,
  200. };
  201. enum { /* Window 3 - FIFO management */
  202. Wfifo = 0x0003,
  203. /* registers */
  204. InternalConfig = 0x0000, /* 3C509B, 3C589, 3C59[0257] */
  205. OtherInt = 0x0004, /* 3C59[0257] */
  206. RomControl = 0x0006, /* 3C509B, 3C59[27] */
  207. MacControl = 0x0006, /* 3C59[0257] */
  208. ResetOptions = 0x0008, /* 3C59[0257] */
  209. MediaOptions = 0x0008, /* 3C905B */
  210. RxFree = 0x000A,
  211. /* InternalConfig bits */
  212. disableBadSsdDetect = 0x00000100,
  213. ramLocation = 0x00000200, /* 0 external, 1 internal */
  214. ramPartition5to3 = 0x00000000,
  215. ramPartition3to1 = 0x00010000,
  216. ramPartition1to1 = 0x00020000,
  217. ramPartition3to5 = 0x00030000,
  218. ramPartitionMask = 0x00030000,
  219. xcvr10BaseT = 0x00000000,
  220. xcvrAui = 0x00100000, /* 10BASE5 */
  221. xcvr10Base2 = 0x00300000,
  222. xcvr100BaseTX = 0x00400000,
  223. xcvr100BaseFX = 0x00500000,
  224. xcvrMii = 0x00600000,
  225. xcvrMask = 0x00700000,
  226. autoSelect = 0x01000000,
  227. /* MacControl bits */
  228. deferExtendEnable = 0x0001,
  229. deferTimerSelect = 0x001E, /* mask */
  230. fullDuplexEnable = 0x0020,
  231. allowLargePackets = 0x0040,
  232. extendAfterCollision = 0x0080, /* 3C90xB */
  233. flowControlEnable = 0x0100, /* 3C90xB */
  234. vltEnable = 0x0200, /* 3C90xB */
  235. /* ResetOptions bits */
  236. baseT4Available = 0x0001,
  237. baseTXAvailable = 0x0002,
  238. baseFXAvailable = 0x0004,
  239. base10TAvailable = 0x0008,
  240. coaxAvailable = 0x0010,
  241. auiAvailable = 0x0020,
  242. miiConnector = 0x0040,
  243. };
  244. enum { /* Window 4 - diagnostic */
  245. Wdiagnostic = 0x0004,
  246. /* registers */
  247. VcoDiagnostic = 0x0002,
  248. FifoDiagnostic = 0x0004,
  249. NetworkDiagnostic = 0x0006,
  250. PhysicalMgmt = 0x0008,
  251. MediaStatus = 0x000A,
  252. BadSSD = 0x000C,
  253. UpperBytesOk = 0x000D,
  254. /* FifoDiagnostic bits */
  255. txOverrun = 0x0400,
  256. rxUnderrun = 0x2000,
  257. receiving = 0x8000,
  258. /* PhysicalMgmt bits */
  259. mgmtClk = 0x0001,
  260. mgmtData = 0x0002,
  261. mgmtDir = 0x0004,
  262. cat5LinkTestDefeat = 0x8000,
  263. /* MediaStatus bits */
  264. dataRate100 = 0x0002,
  265. crcStripDisable = 0x0004,
  266. enableSqeStats = 0x0008,
  267. collisionDetect = 0x0010,
  268. carrierSense = 0x0020,
  269. jabberGuardEnable = 0x0040,
  270. linkBeatEnable = 0x0080,
  271. jabberDetect = 0x0200,
  272. polarityReversed = 0x0400,
  273. linkBeatDetect = 0x0800,
  274. txInProg = 0x1000,
  275. dcConverterEnabled = 0x4000,
  276. auiDisable = 0x8000, /* 10BaseT transceiver selected */
  277. };
  278. enum { /* Window 5 - internal state */
  279. Wstate = 0x0005,
  280. /* registers */
  281. TxStartThresh = 0x0000,
  282. TxAvailableThresh = 0x0002,
  283. RxEarlyThresh = 0x0006,
  284. RxFilter = 0x0008,
  285. InterruptEnable = 0x000A,
  286. IndicationEnable = 0x000C,
  287. };
  288. enum { /* Window 6 - statistics */
  289. Wstatistics = 0x0006,
  290. /* registers */
  291. CarrierLost = 0x0000,
  292. SqeErrors = 0x0001,
  293. MultipleColls = 0x0002,
  294. SingleCollFrames = 0x0003,
  295. LateCollisions = 0x0004,
  296. RxOverruns = 0x0005,
  297. FramesXmittedOk = 0x0006,
  298. FramesRcvdOk = 0x0007,
  299. FramesDeferred = 0x0008,
  300. UpperFramesOk = 0x0009,
  301. BytesRcvdOk = 0x000A,
  302. BytesXmittedOk = 0x000C,
  303. };
  304. enum { /* Window 7 - bus master operations */
  305. Wmaster = 0x0007,
  306. /* registers */
  307. MasterAddress = 0x0000,
  308. MasterLen = 0x0006,
  309. MasterStatus = 0x000C,
  310. /* MasterStatus bits */
  311. masterAbort = 0x0001,
  312. targetAbort = 0x0002,
  313. targetRetry = 0x0004,
  314. targetDisc = 0x0008,
  315. masterDownload = 0x1000,
  316. masterUpload = 0x4000,
  317. masterInProgress = 0x8000,
  318. masterMask = 0xD00F,
  319. };
  320. enum { /* 3C90x extended register set */
  321. Timer905 = 0x001A, /* 8-bits */
  322. TxStatus905 = 0x001B, /* 8-bits */
  323. PktStatus = 0x0020, /* 32-bits */
  324. DnListPtr = 0x0024, /* 32-bits, 8-byte aligned */
  325. FragAddr = 0x0028, /* 32-bits */
  326. FragLen = 0x002C, /* 16-bits */
  327. ListOffset = 0x002E, /* 8-bits */
  328. TxFreeThresh = 0x002F, /* 8-bits */
  329. UpPktStatus = 0x0030, /* 32-bits */
  330. FreeTimer = 0x0034, /* 16-bits */
  331. UpListPtr = 0x0038, /* 32-bits, 8-byte aligned */
  332. /* PktStatus bits */
  333. fragLast = 0x00000001,
  334. dnCmplReq = 0x00000002,
  335. dnStalled = 0x00000004,
  336. upCompleteX = 0x00000008,
  337. dnCompleteX = 0x00000010,
  338. upRxEarlyEnable = 0x00000020,
  339. armCountdown = 0x00000040,
  340. dnInProg = 0x00000080,
  341. counterSpeed = 0x00000010, /* 0 3.2uS, 1 320nS */
  342. countdownMode = 0x00000020,
  343. /* UpPktStatus bits (dpd->control) */
  344. upPktLenMask = 0x00001FFF,
  345. upStalled = 0x00002000,
  346. upError = 0x00004000,
  347. upPktComplete = 0x00008000,
  348. upOverrun = 0x00010000, /* RxError<<16 */
  349. upRuntFrame = 0x00020000,
  350. upAlignmentError = 0x00040000,
  351. upCRCError = 0x00080000,
  352. upOversizedFrame = 0x00100000,
  353. upDribbleBits = 0x00800000,
  354. upOverflow = 0x01000000,
  355. dnIndicate = 0x80000000, /* FrameStartHeader (dpd->control) */
  356. updnLastFrag = 0x80000000, /* (dpd->len) */
  357. Nup = 16,
  358. Ndn = 8,
  359. };
  360. /*
  361. * Up/Dn Packet Descriptors.
  362. * The hardware info (np, control, addr, len) must be 8-byte aligned
  363. * and this structure size must be a multiple of 8.
  364. */
  365. typedef struct Pd Pd;
  366. typedef struct Pd {
  367. ulong np; /* next pointer */
  368. ulong control; /* FSH or UpPktStatus */
  369. ulong addr;
  370. ulong len;
  371. Pd* next;
  372. void* vaddr;
  373. } Pd;
  374. typedef struct Ctlr Ctlr;
  375. struct Ctlr {
  376. int port;
  377. Pcidev* pcidev;
  378. int irq;
  379. Ctlr* next;
  380. int active;
  381. int did;
  382. Lock wlock; /* window access */
  383. int attached;
  384. int busmaster;
  385. Block* rbp; /* receive buffer */
  386. Block* txbp; /* FIFO -based transmission */
  387. int txthreshold;
  388. int txbusy;
  389. int nup; /* full-busmaster -based reception */
  390. void* upbase;
  391. Pd* upr;
  392. Pd* uphead;
  393. int ndn; /* full-busmaster -based transmission */
  394. void* dnbase;
  395. Pd* dnr;
  396. Pd* dnhead;
  397. Pd* dntail;
  398. int dnq;
  399. long interrupts; /* statistics */
  400. long timer[2];
  401. long stats[BytesRcvdOk+3];
  402. int upqmax;
  403. int upqmaxhw;
  404. ulong upinterrupts;
  405. ulong upqueued;
  406. ulong upstalls;
  407. int dnqmax;
  408. int dnqmaxhw;
  409. ulong dninterrupts;
  410. ulong dnqueued;
  411. int xcvr; /* transceiver type */
  412. int eepromcmd; /* EEPROM read command */
  413. int rxstatus9; /* old-style RxStatus register */
  414. int rxearly; /* RxEarlyThreshold */
  415. int ts; /* threshold shift */
  416. int upenabled;
  417. int dnenabled;
  418. ulong cbfnpa; /* CardBus functions */
  419. ulong* cbfn;
  420. };
  421. static Ctlr* ctlrhead;
  422. static Ctlr* ctlrtail;
  423. static void
  424. init905(Ctlr* ctlr)
  425. {
  426. Pd *pd, *prev;
  427. uchar *vaddr;
  428. /*
  429. * Create rings for the receive and transmit sides.
  430. * Take care with alignment:
  431. * make sure ring base is 8-byte aligned;
  432. * make sure each entry is 8-byte aligned.
  433. */
  434. ctlr->upbase = malloc((ctlr->nup+1)*sizeof(Pd));
  435. ctlr->upr = (Pd*)ROUNDUP((ulong)ctlr->upbase, 8);
  436. vaddr = ialloc((ctlr->nup+1)*ROUNDUP(sizeof(Etherpkt)+4, 8), 8);
  437. prev = ctlr->upr;
  438. for(pd = &ctlr->upr[ctlr->nup-1]; pd >= ctlr->upr; pd--){
  439. pd->np = PADDR(&prev->np);
  440. pd->control = 0;
  441. pd->vaddr = vaddr;
  442. pd->addr = PADDR(vaddr);
  443. vaddr += ROUNDUP(sizeof(Etherpkt)+4, 8);
  444. pd->len = updnLastFrag|sizeof(Etherpkt);
  445. pd->next = prev;
  446. prev = pd;
  447. }
  448. ctlr->uphead = ctlr->upr;
  449. ctlr->dnbase = malloc((ctlr->ndn+1)*sizeof(Pd));
  450. ctlr->dnr = (Pd*)ROUNDUP((ulong)ctlr->dnbase, 8);
  451. vaddr = ialloc((ctlr->ndn+1)*ROUNDUP(sizeof(Etherpkt)+4, 8), 8);
  452. prev = ctlr->dnr;
  453. for(pd = &ctlr->dnr[ctlr->ndn-1]; pd >= ctlr->dnr; pd--){
  454. pd->next = prev;
  455. pd->vaddr = vaddr;
  456. pd->addr = PADDR(vaddr);
  457. vaddr += ROUNDUP(sizeof(Etherpkt)+4, 8);
  458. prev = pd;
  459. }
  460. ctlr->dnhead = ctlr->dnr;
  461. ctlr->dntail = ctlr->dnr;
  462. ctlr->dnq = 0;
  463. }
  464. static Block*
  465. rbpalloc(Block* (*f)(int))
  466. {
  467. Block *bp;
  468. ulong addr;
  469. /*
  470. * The receive buffers must be on a 32-byte
  471. * boundary for EISA busmastering.
  472. */
  473. if(bp = f(ROUNDUP(sizeof(Etherpkt), 4) + 31)){
  474. addr = (ulong)bp->base;
  475. addr = ROUNDUP(addr, 32);
  476. bp->rp = (uchar*)addr;
  477. }
  478. return bp;
  479. }
  480. static uchar*
  481. startdma(Ether* ether, ulong address)
  482. {
  483. int port, status, w;
  484. uchar *wp;
  485. port = ether->port;
  486. w = (STATUS(port)>>13) & 0x07;
  487. COMMAND(port, SelectRegisterWindow, Wmaster);
  488. wp = KADDR(inl(port+MasterAddress));
  489. status = ins(port+MasterStatus);
  490. if(status & (masterInProgress|targetAbort|masterAbort))
  491. print("#l%d: BM status 0x%uX\n", ether->ctlrno, status);
  492. outs(port+MasterStatus, masterMask);
  493. outl(port+MasterAddress, address);
  494. outs(port+MasterLen, sizeof(Etherpkt));
  495. COMMAND(port, StartDma, Upload);
  496. COMMAND(port, SelectRegisterWindow, w);
  497. return wp;
  498. }
  499. /* On the 575B and C, interrupts need to be acknowledged in CardBus memory space */
  500. static void
  501. intrackcb(ulong *cbfn)
  502. {
  503. cbfn[1] = 0x8000;
  504. }
  505. static void
  506. attach(Ether* ether)
  507. {
  508. int port, x;
  509. Ctlr *ctlr;
  510. ctlr = ether->ctlr;
  511. ilock(&ctlr->wlock);
  512. if(ctlr->attached){
  513. iunlock(&ctlr->wlock);
  514. return;
  515. }
  516. port = ether->port;
  517. COMMAND(port, SetRxFilter, receiveIndividual/*|receiveBroadcast*/);
  518. x = interruptMask;
  519. if(ctlr->busmaster == 1)
  520. x &= ~(rxEarly|rxComplete);
  521. else{
  522. if(ctlr->dnenabled)
  523. x &= ~transferInt;
  524. if(ctlr->upenabled)
  525. x &= ~(rxEarly|rxComplete);
  526. }
  527. COMMAND(port, SetIndicationEnable, x);
  528. COMMAND(port, SetInterruptEnable, x);
  529. COMMAND(port, RxEnable, 0);
  530. COMMAND(port, TxEnable, 0);
  531. /*
  532. * If this is a CardBus card, acknowledge any interrupts.
  533. */
  534. if(ctlr->cbfn != nil)
  535. intrackcb(ctlr->cbfn);
  536. /*
  537. * Prime the busmaster channel for receiving directly into a
  538. * receive packet buffer if necessary.
  539. */
  540. if(ctlr->busmaster == 1)
  541. startdma(ether, PADDR(ctlr->rbp->rp));
  542. else{
  543. if(ctlr->upenabled)
  544. outl(port+UpListPtr, PADDR(&ctlr->uphead->np));
  545. }
  546. ctlr->attached = 1;
  547. iunlock(&ctlr->wlock);
  548. }
  549. static void
  550. statistics(Ether* ether)
  551. {
  552. int port, i, u, w;
  553. Ctlr *ctlr;
  554. port = ether->port;
  555. ctlr = ether->ctlr;
  556. /*
  557. * 3C59[27] require a read between a PIO write and
  558. * reading a statistics register.
  559. */
  560. w = (STATUS(port)>>13) & 0x07;
  561. COMMAND(port, SelectRegisterWindow, Wstatistics);
  562. STATUS(port);
  563. for(i = 0; i < UpperFramesOk; i++)
  564. ctlr->stats[i] += inb(port+i) & 0xFF;
  565. u = inb(port+UpperFramesOk) & 0xFF;
  566. ctlr->stats[FramesXmittedOk] += (u & 0x30)<<4;
  567. ctlr->stats[FramesRcvdOk] += (u & 0x03)<<8;
  568. ctlr->stats[BytesRcvdOk] += ins(port+BytesRcvdOk) & 0xFFFF;
  569. ctlr->stats[BytesRcvdOk+1] += ins(port+BytesXmittedOk) & 0xFFFF;
  570. switch(ctlr->xcvr){
  571. case xcvrMii:
  572. case xcvr100BaseTX:
  573. case xcvr100BaseFX:
  574. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  575. STATUS(port);
  576. ctlr->stats[BytesRcvdOk+2] += inb(port+BadSSD);
  577. break;
  578. }
  579. COMMAND(port, SelectRegisterWindow, w);
  580. }
  581. static void
  582. txstart(Ether* ether)
  583. {
  584. int port, len;
  585. Ctlr *ctlr;
  586. RingBuf *tb;
  587. port = ether->port;
  588. ctlr = ether->ctlr;
  589. /*
  590. * Attempt to top-up the transmit FIFO. If there's room simply
  591. * stuff in the packet length (unpadded to a dword boundary), the
  592. * packet data (padded) and remove the packet from the queue.
  593. * If there's no room post an interrupt for when there is.
  594. * This routine is called both from the top level and from interrupt
  595. * level and expects to be called with ctlr->wlock already locked
  596. * and the correct register window (Wop) in place.
  597. */
  598. for(tb = &ether->tb[ether->ti]; tb->owner == Interface; tb = &ether->tb[ether->ti]){
  599. len = ROUNDUP(tb->len, 4);
  600. if(len+4 <= ins(port+TxFree)){
  601. outl(port+Fifo, tb->len);
  602. outsl(port+Fifo, tb->pkt, len/4);
  603. tb->owner = Host;
  604. ether->ti = NEXT(ether->ti, ether->ntb);
  605. }
  606. else{
  607. if(ctlr->txbusy == 0){
  608. ctlr->txbusy = 1;
  609. COMMAND(port, SetTxAvailableThresh, len>>ctlr->ts);
  610. }
  611. break;
  612. }
  613. }
  614. }
  615. static void
  616. txstart905(Ether* ether)
  617. {
  618. Ctlr *ctlr;
  619. int port, stalled, timeo;
  620. RingBuf *tb;
  621. Pd *pd;
  622. ctlr = ether->ctlr;
  623. port = ether->port;
  624. /*
  625. * Free any completed packets.
  626. */
  627. pd = ctlr->dntail;
  628. while(ctlr->dnq){
  629. if(PADDR(&pd->np) == inl(port+DnListPtr))
  630. break;
  631. ctlr->dnq--;
  632. pd = pd->next;
  633. }
  634. ctlr->dntail = pd;
  635. stalled = 0;
  636. while(ctlr->dnq < (ctlr->ndn-1)){
  637. tb = &ether->tb[ether->ti];
  638. if(tb->owner != Interface)
  639. break;
  640. pd = ctlr->dnhead->next;
  641. pd->np = 0;
  642. pd->control = dnIndicate|tb->len;
  643. memmove(pd->vaddr, tb->pkt, tb->len);
  644. pd->len = updnLastFrag|tb->len;
  645. tb->owner = Host;
  646. ether->ti = NEXT(ether->ti, ether->ntb);
  647. if(stalled == 0 && ctlr->dnq && inl(port+DnListPtr)){
  648. COMMAND(port, Stall, dnStall);
  649. for(timeo = 100; (STATUS(port) & commandInProgress) && timeo; timeo--)
  650. ;
  651. if(timeo == 0)
  652. print("#l%d: dnstall %d\n", ether->ctlrno, timeo);
  653. stalled = 1;
  654. }
  655. coherence();
  656. ctlr->dnhead->np = PADDR(&pd->np);
  657. ctlr->dnhead->control &= ~dnIndicate;
  658. ctlr->dnhead = pd;
  659. if(ctlr->dnq == 0)
  660. ctlr->dntail = pd;
  661. ctlr->dnq++;
  662. ctlr->dnqueued++;
  663. }
  664. if(ctlr->dnq > ctlr->dnqmax)
  665. ctlr->dnqmax = ctlr->dnq;
  666. /*
  667. * If the adapter is not currently processing anything
  668. * and there is something on the queue, start it processing.
  669. */
  670. if(inl(port+DnListPtr) == 0 && ctlr->dnq)
  671. outl(port+DnListPtr, PADDR(&ctlr->dnhead->np));
  672. if(stalled)
  673. COMMAND(port, Stall, dnUnStall);
  674. }
  675. static void
  676. transmit(Ether* ether)
  677. {
  678. Ctlr *ctlr;
  679. int port, w;
  680. port = ether->port;
  681. ctlr = ether->ctlr;
  682. ilock(&ctlr->wlock);
  683. if(ctlr->dnenabled)
  684. txstart905(ether);
  685. else{
  686. w = (STATUS(port)>>13) & 0x07;
  687. COMMAND(port, SelectRegisterWindow, Wop);
  688. txstart(ether);
  689. COMMAND(port, SelectRegisterWindow, w);
  690. }
  691. iunlock(&ctlr->wlock);
  692. }
  693. static void
  694. receive905(Ether* ether)
  695. {
  696. Ctlr *ctlr;
  697. int len, port, q;
  698. Pd *pd;
  699. RingBuf *rb;
  700. ctlr = ether->ctlr;
  701. port = ether->port;
  702. if(inl(port+UpPktStatus) & upStalled)
  703. ctlr->upstalls++;
  704. q = 0;
  705. for(pd = ctlr->uphead; pd->control & upPktComplete; pd = pd->next){
  706. if(!(pd->control & upError)){
  707. rb = &ether->rb[ether->ri];
  708. if (rb->owner == Interface) {
  709. len = pd->control & rxBytes;
  710. rb->len = len;
  711. memmove(rb->pkt, pd->vaddr, len);
  712. rb->owner = Host;
  713. ether->ri = NEXT(ether->ri, ether->nrb);
  714. }
  715. }
  716. pd->control = 0;
  717. COMMAND(port, Stall, upUnStall);
  718. q++;
  719. }
  720. ctlr->uphead = pd;
  721. ctlr->upqueued += q;
  722. if(q > ctlr->upqmax)
  723. ctlr->upqmax = q;
  724. }
  725. static void
  726. receive(Ether* ether)
  727. {
  728. int len, port, rxstatus;
  729. RingBuf *rb;
  730. Ctlr *ctlr;
  731. port = ether->port;
  732. ctlr = ether->ctlr;
  733. while(((rxstatus = ins(port+RxStatus)) & rxIncomplete) == 0){
  734. if(ctlr->busmaster == 1 && (STATUS(port) & busMasterInProgress))
  735. break;
  736. /*
  737. * If there was an error, log it and continue.
  738. * Unfortunately the 3C5[078]9 has the error info in the status register
  739. * and the 3C59[0257] implement a separate RxError register.
  740. */
  741. if((rxstatus & rxError) == 0){
  742. /*
  743. * Packet received. Read it into the next free
  744. * ring buffer, if any. Must read len bytes padded
  745. * to a doubleword, can be picked out 32-bits at
  746. * a time. The CRC is already stripped off.
  747. */
  748. rb = &ether->rb[ether->ri];
  749. if(rb->owner == Interface){
  750. len = (rxstatus & rxBytes9);
  751. rb->len = len;
  752. insl(port+Fifo, rb->pkt, HOWMANY(len, 4));
  753. rb->owner = Host;
  754. ether->ri = NEXT(ether->ri, ether->nrb);
  755. }else
  756. if(debug) print("toss...");
  757. }
  758. else
  759. if(debug) print("error...");
  760. /*
  761. * All done, discard the packet.
  762. */
  763. COMMAND(port, RxDiscard, 0);
  764. while(STATUS(port) & commandInProgress)
  765. ;
  766. }
  767. }
  768. static void
  769. interrupt(Ureg*, void* arg)
  770. {
  771. Ether *ether;
  772. int port, status, s, txstatus, w, x;
  773. Ctlr *ctlr;
  774. ether = arg;
  775. port = ether->port;
  776. ctlr = ether->ctlr;
  777. ilock(&ctlr->wlock);
  778. status = STATUS(port);
  779. if(!(status & (interruptMask|interruptLatch))){
  780. iunlock(&ctlr->wlock);
  781. return;
  782. }
  783. w = (status>>13) & 0x07;
  784. COMMAND(port, SelectRegisterWindow, Wop);
  785. ctlr->interrupts++;
  786. if(ctlr->busmaster == 2)
  787. ctlr->timer[0] += inb(port+Timer905) & 0xFF;
  788. else
  789. ctlr->timer[0] += inb(port+Timer) & 0xFF;
  790. do{
  791. if(status & hostError){
  792. /*
  793. * Adapter failure, try to find out why, reset if
  794. * necessary. What happens if Tx is active and a reset
  795. * occurs, need to retransmit? This probably isn't right.
  796. */
  797. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  798. x = ins(port+FifoDiagnostic);
  799. COMMAND(port, SelectRegisterWindow, Wop);
  800. print("#l%d: status 0x%uX, diag 0x%uX\n",
  801. ether->ctlrno, status, x);
  802. if(x & txOverrun){
  803. if(ctlr->busmaster == 0)
  804. COMMAND(port, TxReset, 0);
  805. else
  806. COMMAND(port, TxReset, (updnReset|dmaReset));
  807. COMMAND(port, TxEnable, 0);
  808. }
  809. if(x & rxUnderrun){
  810. /*
  811. * This shouldn't happen...
  812. * Reset the receiver and restore the filter and RxEarly
  813. * threshold before re-enabling.
  814. * Need to restart any busmastering?
  815. */
  816. COMMAND(port, SelectRegisterWindow, Wstate);
  817. s = (port+RxFilter) & 0x000F;
  818. COMMAND(port, SelectRegisterWindow, Wop);
  819. COMMAND(port, RxReset, 0);
  820. while(STATUS(port) & commandInProgress)
  821. ;
  822. COMMAND(port, SetRxFilter, s);
  823. COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts);
  824. COMMAND(port, RxEnable, 0);
  825. }
  826. status &= ~hostError;
  827. }
  828. if(status & (transferInt|rxComplete)){
  829. receive(ether);
  830. status &= ~(transferInt|rxComplete);
  831. }
  832. if(status & (upComplete)){
  833. COMMAND(port, AcknowledgeInterrupt, upComplete);
  834. receive905(ether);
  835. status &= ~upComplete;
  836. ctlr->upinterrupts++;
  837. }
  838. if(status & txComplete){
  839. /*
  840. * Pop the TxStatus stack, accumulating errors.
  841. * Adjust the TX start threshold if there was an underrun.
  842. * If there was a Jabber or Underrun error, reset
  843. * the transmitter, taking care not to reset the dma logic
  844. * as a busmaster receive may be in progress.
  845. * For all conditions enable the transmitter.
  846. */
  847. if(ctlr->busmaster == 2)
  848. txstatus = port+TxStatus905;
  849. else
  850. txstatus = port+TxStatus;
  851. s = 0;
  852. do{
  853. if(x = inb(txstatus))
  854. outb(txstatus, 0);
  855. s |= x;
  856. }while(STATUS(port) & txComplete);
  857. if(s & txUnderrun){
  858. if(ctlr->dnenabled){
  859. while(inl(port+PktStatus) & dnInProg)
  860. ;
  861. }
  862. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  863. while(ins(port+MediaStatus) & txInProg)
  864. ;
  865. COMMAND(port, SelectRegisterWindow, Wop);
  866. if(ctlr->txthreshold < ETHERMAXTU)
  867. ctlr->txthreshold += ETHERMINTU;
  868. }
  869. /*
  870. * According to the manual, maxCollisions does not require
  871. * a TxReset, merely a TxEnable. However, evidence points to
  872. * it being necessary on the 3C905. The jury is still out.
  873. * On busy or badly configured networks maxCollisions can
  874. * happen frequently enough for messages to be annoying so
  875. * keep quiet about them by popular request.
  876. */
  877. if(s & (txJabber|txUnderrun|maxCollisions)){
  878. if(ctlr->busmaster == 0)
  879. COMMAND(port, TxReset, 0);
  880. else
  881. COMMAND(port, TxReset, (updnReset|dmaReset));
  882. while(STATUS(port) & commandInProgress)
  883. ;
  884. COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);
  885. if(ctlr->busmaster == 2)
  886. outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
  887. if(ctlr->dnenabled)
  888. status |= dnComplete;
  889. }
  890. if(s & ~(txStatusComplete|maxCollisions))
  891. print("#l%d: txstatus 0x%uX, threshold %d\n",
  892. ether->ctlrno, s, ctlr->txthreshold);
  893. COMMAND(port, TxEnable, 0);
  894. status &= ~txComplete;
  895. status |= txAvailable;
  896. }
  897. if(status & txAvailable){
  898. COMMAND(port, AcknowledgeInterrupt, txAvailable);
  899. ctlr->txbusy = 0;
  900. txstart(ether);
  901. status &= ~txAvailable;
  902. }
  903. if(status & dnComplete){
  904. COMMAND(port, AcknowledgeInterrupt, dnComplete);
  905. txstart905(ether);
  906. status &= ~dnComplete;
  907. ctlr->dninterrupts++;
  908. }
  909. if(status & updateStats){
  910. statistics(ether);
  911. status &= ~updateStats;
  912. }
  913. /*
  914. * Currently, this shouldn't happen.
  915. */
  916. if(status & rxEarly){
  917. COMMAND(port, AcknowledgeInterrupt, rxEarly);
  918. status &= ~rxEarly;
  919. }
  920. /*
  921. * Panic if there are any interrupts not dealt with.
  922. */
  923. if(status & interruptMask)
  924. panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);
  925. COMMAND(port, AcknowledgeInterrupt, interruptLatch);
  926. if(ctlr->cbfn != nil)
  927. intrackcb(ctlr->cbfn);
  928. }while((status = STATUS(port)) & (interruptMask|interruptLatch));
  929. if(ctlr->busmaster == 2)
  930. ctlr->timer[1] += inb(port+Timer905) & 0xFF;
  931. else
  932. ctlr->timer[1] += inb(port+Timer) & 0xFF;
  933. COMMAND(port, SelectRegisterWindow, w);
  934. iunlock(&ctlr->wlock);
  935. }
  936. static void
  937. txrxreset(int port)
  938. {
  939. while(STATUS(port) & commandInProgress)
  940. ;
  941. COMMAND(port, RxReset, 0);
  942. while(STATUS(port) & commandInProgress)
  943. ;
  944. }
  945. static Ctlr*
  946. tcmadapter(int port, int irq, Pcidev* pcidev)
  947. {
  948. Ctlr *ctlr;
  949. ctlr = malloc(sizeof(Ctlr));
  950. ctlr->port = port;
  951. ctlr->irq = irq;
  952. ctlr->pcidev = pcidev;
  953. ctlr->eepromcmd = EepromReadRegister;
  954. if(ctlrhead != nil)
  955. ctlrtail->next = ctlr;
  956. else
  957. ctlrhead = ctlr;
  958. ctlrtail = ctlr;
  959. return ctlr;
  960. }
  961. /*
  962. * Write two 0 bytes to identify the IDport and then reset the
  963. * ID sequence. Then send the ID sequence to the card to get
  964. * the card into command state.
  965. */
  966. static void
  967. idseq(void)
  968. {
  969. int i;
  970. uchar al;
  971. static int reset, untag;
  972. /*
  973. * One time only:
  974. * reset any adapters listening
  975. */
  976. if(reset == 0){
  977. outb(IDport, 0);
  978. outb(IDport, 0);
  979. outb(IDport, 0xC0);
  980. delay(20);
  981. reset = 1;
  982. }
  983. outb(IDport, 0);
  984. outb(IDport, 0);
  985. for(al = 0xFF, i = 0; i < 255; i++){
  986. outb(IDport, al);
  987. if(al & 0x80){
  988. al <<= 1;
  989. al ^= 0xCF;
  990. }
  991. else
  992. al <<= 1;
  993. }
  994. /*
  995. * One time only:
  996. * write ID sequence to get the attention of all adapters;
  997. * untag all adapters.
  998. * If a global reset is done here on all adapters it will confuse
  999. * any ISA cards configured for EISA mode.
  1000. */
  1001. if(untag == 0){
  1002. outb(IDport, 0xD0);
  1003. untag = 1;
  1004. }
  1005. }
  1006. static ulong
  1007. activate(void)
  1008. {
  1009. int i;
  1010. ushort x, acr;
  1011. /*
  1012. * Do the little configuration dance:
  1013. *
  1014. * 2. write the ID sequence to get to command state.
  1015. */
  1016. idseq();
  1017. /*
  1018. * 3. Read the Manufacturer ID from the EEPROM.
  1019. * This is done by writing the IDPort with 0x87 (0x80
  1020. * is the 'read EEPROM' command, 0x07 is the offset of
  1021. * the Manufacturer ID field in the EEPROM).
  1022. * The data comes back 1 bit at a time.
  1023. * A delay seems necessary between reading the bits.
  1024. *
  1025. * If the ID doesn't match, there are no more adapters.
  1026. */
  1027. outb(IDport, 0x87);
  1028. delay(20);
  1029. for(x = 0, i = 0; i < 16; i++){
  1030. delay(20);
  1031. x <<= 1;
  1032. x |= inb(IDport) & 0x01;
  1033. }
  1034. if(x != 0x6D50)
  1035. return 0;
  1036. /*
  1037. * 3. Read the Address Configuration from the EEPROM.
  1038. * The Address Configuration field is at offset 0x08 in the EEPROM).
  1039. */
  1040. outb(IDport, 0x88);
  1041. for(acr = 0, i = 0; i < 16; i++){
  1042. delay(20);
  1043. acr <<= 1;
  1044. acr |= inb(IDport) & 0x01;
  1045. }
  1046. return (acr & 0x1F)*0x10 + 0x200;
  1047. }
  1048. static void
  1049. tcm509isa(void)
  1050. {
  1051. int irq, port;
  1052. /*
  1053. * Attempt to activate all adapters. If adapter is set for
  1054. * EISA mode (0x3F0), tag it and ignore. Otherwise, activate
  1055. * it fully.
  1056. */
  1057. while(port = activate()){
  1058. /*
  1059. * 6. Tag the adapter so it won't respond in future.
  1060. */
  1061. outb(IDport, 0xD1);
  1062. if(port == 0x3F0)
  1063. continue;
  1064. /*
  1065. * 6. Activate the adapter by writing the Activate command
  1066. * (0xFF).
  1067. */
  1068. outb(IDport, 0xFF);
  1069. delay(20);
  1070. /*
  1071. * 8. Can now talk to the adapter's I/O base addresses.
  1072. * Use the I/O base address from the acr just read.
  1073. *
  1074. * Enable the adapter and clear out any lingering status
  1075. * and interrupts.
  1076. */
  1077. while(STATUS(port) & commandInProgress)
  1078. ;
  1079. COMMAND(port, SelectRegisterWindow, Wsetup);
  1080. outs(port+ConfigControl, Ena);
  1081. txrxreset(port);
  1082. COMMAND(port, AcknowledgeInterrupt, 0xFF);
  1083. irq = (ins(port+ResourceConfig)>>12) & 0x0F;
  1084. tcmadapter(port, irq, nil);
  1085. }
  1086. }
  1087. static void
  1088. tcm5XXeisa(void)
  1089. {
  1090. ushort x;
  1091. int irq, port, slot;
  1092. /*
  1093. * Check if this is an EISA machine.
  1094. * If not, nothing to do.
  1095. */
  1096. if(strncmp((char*)KADDR(0xFFFD9), "EISA", 4))
  1097. return;
  1098. /*
  1099. * Continue through the EISA slots looking for a match on both
  1100. * 3COM as the manufacturer and 3C579-* or 3C59[27]-* as the product.
  1101. * If an adapter is found, select window 0, enable it and clear
  1102. * out any lingering status and interrupts.
  1103. */
  1104. for(slot = 1; slot < MaxEISA; slot++){
  1105. port = slot*0x1000;
  1106. if(ins(port+0xC80+ManufacturerID) != 0x6D50)
  1107. continue;
  1108. x = ins(port+0xC80+ProductID);
  1109. if((x & 0xF0FF) != 0x9050 && (x & 0xFF00) != 0x5900)
  1110. continue;
  1111. COMMAND(port, SelectRegisterWindow, Wsetup);
  1112. outs(port+ConfigControl, Ena);
  1113. txrxreset(port);
  1114. COMMAND(port, AcknowledgeInterrupt, 0xFF);
  1115. irq = (ins(port+ResourceConfig)>>12) & 0x0F;
  1116. tcmadapter(port, irq, nil);
  1117. }
  1118. }
  1119. static void
  1120. tcm59Xpci(void)
  1121. {
  1122. Pcidev *p;
  1123. Ctlr *ctlr;
  1124. int irq, port;
  1125. p = nil;
  1126. while(p = pcimatch(p, 0x10B7, 0)){
  1127. if(p->ccrb != 0x02 || p->ccru != 0)
  1128. continue;
  1129. /*
  1130. * Not prepared to deal with memory-mapped
  1131. * devices yet.
  1132. */
  1133. if(!(p->mem[0].bar & 0x01))
  1134. continue;
  1135. port = p->mem[0].bar & ~0x01;
  1136. irq = p->intl;
  1137. txrxreset(port);
  1138. COMMAND(port, AcknowledgeInterrupt, 0xFF);
  1139. ctlr = tcmadapter(port, irq, p);
  1140. switch(p->did){
  1141. default:
  1142. break;
  1143. case 0x5157:
  1144. ctlr->eepromcmd = EepromRead8bRegister;
  1145. ctlr->cbfnpa = p->mem[2].bar&~0x0F;
  1146. ctlr->cbfn = KADDR(ctlr->cbfnpa);
  1147. break;
  1148. case 0x6056:
  1149. ctlr->eepromcmd = EepromReadOffRegister;
  1150. ctlr->cbfnpa = p->mem[2].bar&~0x0F;
  1151. ctlr->cbfn = KADDR(ctlr->cbfnpa);
  1152. break;
  1153. }
  1154. pcisetbme(p);
  1155. }
  1156. }
  1157. static char* tcmpcmcia[] = {
  1158. "3C589", /* 3COM 589[ABCD] */
  1159. "3C562", /* 3COM 562 */
  1160. "589E", /* 3COM Megahertz 589E */
  1161. nil,
  1162. };
  1163. static Ctlr*
  1164. tcm5XXpcmcia(Ether* ether)
  1165. {
  1166. int i;
  1167. Ctlr *ctlr;
  1168. if(ether->type == nil)
  1169. return nil;
  1170. for(i = 0; tcmpcmcia[i] != nil; i++){
  1171. if(cistrcmp(ether->type, tcmpcmcia[i]))
  1172. continue;
  1173. ctlr = tcmadapter(ether->port, ether->irq, nil);
  1174. ctlr->active = 1;
  1175. return ctlr;
  1176. }
  1177. return nil;
  1178. }
  1179. static void
  1180. setxcvr(Ctlr* ctlr, int xcvr)
  1181. {
  1182. int port, x;
  1183. port = ctlr->port;
  1184. if(ctlr->rxstatus9){
  1185. COMMAND(port, SelectRegisterWindow, Wsetup);
  1186. x = ins(port+AddressConfig) & ~xcvrMask9;
  1187. x |= (xcvr>>20)<<14;
  1188. outs(port+AddressConfig, x);
  1189. }
  1190. else{
  1191. COMMAND(port, SelectRegisterWindow, Wfifo);
  1192. x = inl(port+InternalConfig) & ~xcvrMask;
  1193. x |= xcvr;
  1194. outl(port+InternalConfig, x);
  1195. }
  1196. txrxreset(port);
  1197. }
  1198. static void
  1199. setfullduplex(int port)
  1200. {
  1201. int x;
  1202. COMMAND(port, SelectRegisterWindow, Wfifo);
  1203. x = ins(port+MacControl);
  1204. outs(port+MacControl, fullDuplexEnable|x);
  1205. txrxreset(port);
  1206. }
  1207. static int
  1208. miimdi(int port, int n)
  1209. {
  1210. int data, i;
  1211. /*
  1212. * Read n bits from the MII Management Register.
  1213. */
  1214. data = 0;
  1215. for(i = n-1; i >= 0; i--){
  1216. if(ins(port) & mgmtData)
  1217. data |= (1<<i);
  1218. microdelay(1);
  1219. outs(port, mgmtClk);
  1220. microdelay(1);
  1221. outs(port, 0);
  1222. microdelay(1);
  1223. }
  1224. return data;
  1225. }
  1226. static void
  1227. miimdo(int port, int bits, int n)
  1228. {
  1229. int i, mdo;
  1230. /*
  1231. * Write n bits to the MII Management Register.
  1232. */
  1233. for(i = n-1; i >= 0; i--){
  1234. if(bits & (1<<i))
  1235. mdo = mgmtDir|mgmtData;
  1236. else
  1237. mdo = mgmtDir;
  1238. outs(port, mdo);
  1239. microdelay(1);
  1240. outs(port, mdo|mgmtClk);
  1241. microdelay(1);
  1242. outs(port, mdo);
  1243. microdelay(1);
  1244. }
  1245. }
  1246. static int
  1247. miir(int port, int phyad, int regad)
  1248. {
  1249. int data, w;
  1250. w = (STATUS(port)>>13) & 0x07;
  1251. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  1252. port += PhysicalMgmt;
  1253. /*
  1254. * Preamble;
  1255. * ST+OP+PHYAD+REGAD;
  1256. * TA + 16 data bits.
  1257. */
  1258. miimdo(port, 0xFFFFFFFF, 32);
  1259. miimdo(port, 0x1800|(phyad<<5)|regad, 14);
  1260. data = miimdi(port, 18);
  1261. port -= PhysicalMgmt;
  1262. COMMAND(port, SelectRegisterWindow, w);
  1263. if(data & 0x10000)
  1264. return -1;
  1265. return data & 0xFFFF;
  1266. }
  1267. static int
  1268. scanphy(int port)
  1269. {
  1270. int i, x;
  1271. for(i = 0; i < 32; i++){
  1272. if((x = miir(port, i, 2)) == -1 || x == 0)
  1273. continue;
  1274. x <<= 6;
  1275. x |= miir(port, i, 3)>>10;
  1276. XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(port, i, 1));
  1277. USED(x);
  1278. return i;
  1279. }
  1280. return 24;
  1281. }
  1282. #ifdef notdef
  1283. static struct xxx {
  1284. int available;
  1285. int next;
  1286. } xxx[8] = {
  1287. { base10TAvailable, 1, }, /* xcvr10BaseT -> xcvrAui */
  1288. { auiAvailable, 3, }, /* xcvrAui -> xcvr10Base2 */
  1289. { 0, -1, },
  1290. { coaxAvailable, -1, }, /* xcvr10Base2 -> nowhere */
  1291. { baseTXAvailable, 5, }, /* xcvr100BaseTX-> xcvr100BaseFX */
  1292. { baseFXAvailable, -1, }, /* xcvr100BaseFX-> nowhere */
  1293. { miiConnector, -1, }, /* xcvrMii -> nowhere */
  1294. { 0, -1, },
  1295. };
  1296. #endif /* notdef */
  1297. static struct {
  1298. char *name;
  1299. int avail;
  1300. int xcvr;
  1301. } media[] = {
  1302. "10BaseT", base10TAvailable, xcvr10BaseT,
  1303. "10Base2", coaxAvailable, xcvr10Base2,
  1304. "100BaseTX", baseTXAvailable, xcvr100BaseTX,
  1305. "100BaseFX", baseFXAvailable, xcvr100BaseFX,
  1306. "aui", auiAvailable, xcvrAui,
  1307. "mii", miiConnector, xcvrMii
  1308. };
  1309. static int
  1310. autoselect(Ctlr* ctlr)
  1311. {
  1312. int media, port, x;
  1313. /*
  1314. * Pathetic attempt at automatic media selection.
  1315. * Really just to get the Fast Etherlink 10BASE-T/100BASE-TX
  1316. * cards operational.
  1317. * It's a bonus if it works for anything else.
  1318. */
  1319. port = ctlr->port;
  1320. if(ctlr->rxstatus9){
  1321. COMMAND(port, SelectRegisterWindow, Wsetup);
  1322. x = ins(port+ConfigControl);
  1323. media = 0;
  1324. if(x & base10TAvailable9)
  1325. media |= base10TAvailable;
  1326. if(x & coaxAvailable9)
  1327. media |= coaxAvailable;
  1328. if(x & auiAvailable9)
  1329. media |= auiAvailable;
  1330. }
  1331. else{
  1332. COMMAND(port, SelectRegisterWindow, Wfifo);
  1333. media = ins(port+ResetOptions);
  1334. }
  1335. XCVRDEBUG("autoselect: media %uX\n", media);
  1336. if(media & miiConnector)
  1337. return xcvrMii;
  1338. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  1339. XCVRDEBUG("autoselect: media status %uX\n", ins(port+MediaStatus));
  1340. if(media & baseTXAvailable){
  1341. /*
  1342. * Must have InternalConfig register.
  1343. */
  1344. setxcvr(ctlr, xcvr100BaseTX);
  1345. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  1346. x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
  1347. outs(port+MediaStatus, linkBeatEnable|x);
  1348. delay(10);
  1349. if(ins(port+MediaStatus) & linkBeatDetect)
  1350. return xcvr100BaseTX;
  1351. outs(port+MediaStatus, x);
  1352. }
  1353. if(media & base10TAvailable){
  1354. setxcvr(ctlr, xcvr10BaseT);
  1355. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  1356. x = ins(port+MediaStatus) & ~dcConverterEnabled;
  1357. outs(port+MediaStatus, linkBeatEnable|jabberGuardEnable|x);
  1358. delay(100);
  1359. XCVRDEBUG("autoselect: 10BaseT media status %uX\n", ins(port+MediaStatus));
  1360. if(ins(port+MediaStatus) & linkBeatDetect)
  1361. return xcvr10BaseT;
  1362. outs(port+MediaStatus, x);
  1363. }
  1364. /*
  1365. * Botch.
  1366. */
  1367. return autoSelect;
  1368. }
  1369. static int
  1370. eepromdata(Ctlr* ctlr, int offset)
  1371. {
  1372. int port;
  1373. port = ctlr->port;
  1374. COMMAND(port, SelectRegisterWindow, Wsetup);
  1375. while(EEPROMBUSY(port))
  1376. ;
  1377. EEPROMCMD(port, ctlr->eepromcmd, offset);
  1378. while(EEPROMBUSY(port))
  1379. ;
  1380. return EEPROMDATA(port);
  1381. }
  1382. static void
  1383. resetctlr(Ctlr *ctlr)
  1384. {
  1385. int port, x;
  1386. port = ctlr->port;
  1387. txrxreset(port);
  1388. x = ins(port+ResetOp905B);
  1389. XCVRDEBUG("905[BC] reset ops 0x%uX\n", x);
  1390. x &= ~0x4010;
  1391. if(ctlr->did == 0x5157){
  1392. x |= 0x0010; /* Invert LED */
  1393. outs(port+ResetOp905B, x);
  1394. }
  1395. if(ctlr->did == 0x6056){
  1396. x |= 0x4000;
  1397. outs(port+ResetOp905B, x);
  1398. COMMAND(port, SelectRegisterWindow, Wsetup);
  1399. outs(port, 0x0800);
  1400. }
  1401. }
  1402. int
  1403. elnk3reset(Ether* ether)
  1404. {
  1405. char *p;
  1406. Ctlr *ctlr;
  1407. uchar ea[Eaddrlen];
  1408. static int scandone;
  1409. int anar, anlpar, i, j, phyaddr, phystat, port, timeo, x;
  1410. /*
  1411. * Scan for adapter on PCI, EISA and finally
  1412. * using the little ISA configuration dance.
  1413. */
  1414. if(scandone == 0){
  1415. tcm59Xpci();
  1416. tcm5XXeisa();
  1417. tcm509isa();
  1418. scandone = 1;
  1419. }
  1420. /*
  1421. * Any adapter matches if no ether->port is supplied,
  1422. * otherwise the ports must match.
  1423. */
  1424. for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
  1425. if(ctlr->active)
  1426. continue;
  1427. if(ether->port == 0 || ether->port == ctlr->port){
  1428. ctlr->active = 1;
  1429. break;
  1430. }
  1431. }
  1432. if(ctlr == nil && (ctlr = tcm5XXpcmcia(ether)) == 0)
  1433. return -1;
  1434. ether->ctlr = ctlr;
  1435. port = ctlr->port;
  1436. ether->port = port;
  1437. ether->irq = ctlr->irq;
  1438. if(ctlr->pcidev != nil)
  1439. ether->tbdf = ctlr->pcidev->tbdf;
  1440. else
  1441. ether->tbdf = BUSUNKNOWN;
  1442. /*
  1443. * Read the DeviceID from the EEPROM, it's at offset 0x03,
  1444. * and do something depending on capabilities.
  1445. */
  1446. switch(ctlr->did = eepromdata(ctlr, 0x03)){
  1447. case 0x5157: /* 3C575 Cyclone */
  1448. case 0x6056:
  1449. /*FALLTHROUGH*/
  1450. case 0x4500: /* 3C450 HomePNA Tornado */
  1451. case 0x7646: /* 3CSOHO100-TX */
  1452. case 0x9055: /* 3C905B-TX */
  1453. case 0x9200: /* 3C905C-TX */
  1454. case 0x9201: /* 3C920 */
  1455. case 0x9805: /* 3C9805: 3C980-TX Python-T 10/100baseTX */
  1456. /*FALLTHROUGH*/
  1457. case 0x9000: /* 3C900-TPO */
  1458. case 0x9001: /* 3C900-COMBO */
  1459. case 0x9005: /* 3C900B-COMBO */
  1460. case 0x9050: /* 3C905-TX */
  1461. case 0x9051: /* 3C905-T4 */
  1462. if(BUSTYPE(ether->tbdf) != BusPCI)
  1463. goto buggery;
  1464. ctlr->busmaster = 2;
  1465. goto vortex;
  1466. case 0x5900: /* 3C590-[TP|COMBO|TPO] */
  1467. case 0x5920: /* 3C592-[TP|COMBO|TPO] */
  1468. case 0x5950: /* 3C595-TX */
  1469. case 0x5951: /* 3C595-T4 */
  1470. case 0x5952: /* 3C595-MII */
  1471. case 0x5970: /* 3C597-TX */
  1472. case 0x5971: /* 3C597-T4 */
  1473. case 0x5972: /* 3C597-MII */
  1474. ctlr->busmaster = 1;
  1475. vortex:
  1476. COMMAND(port, SelectRegisterWindow, Wfifo);
  1477. ctlr->xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask);
  1478. ctlr->rxearly = 8188;
  1479. ctlr->rxstatus9 = 0;
  1480. break;
  1481. buggery:
  1482. default:
  1483. ctlr->busmaster = 0;
  1484. COMMAND(port, SelectRegisterWindow, Wsetup);
  1485. x = ins(port+AddressConfig);
  1486. ctlr->xcvr = ((x & xcvrMask9)>>14)<<20;
  1487. if(x & autoSelect9)
  1488. ctlr->xcvr |= autoSelect;
  1489. ctlr->rxearly = 2044;
  1490. ctlr->rxstatus9 = 1;
  1491. break;
  1492. }
  1493. if(ctlr->rxearly >= 2048)
  1494. ctlr->ts = 2;
  1495. /*
  1496. * Check if the adapter's station address is to be overridden.
  1497. * If not, read it from the EEPROM and set in ether->ea prior to
  1498. * loading the station address in Wstation.
  1499. * The EEPROM returns 16-bits at a time.
  1500. */
  1501. memset(ea, 0, Eaddrlen);
  1502. if(memcmp(ea, ether->ea, Eaddrlen) == 0){
  1503. for(i = 0; i < Eaddrlen/2; i++){
  1504. x = eepromdata(ctlr, i);
  1505. ether->ea[2*i] = x>>8;
  1506. ether->ea[2*i+1] = x;
  1507. }
  1508. }
  1509. COMMAND(port, SelectRegisterWindow, Wstation);
  1510. for(i = 0; i < Eaddrlen; i++)
  1511. outb(port+i, ether->ea[i]);
  1512. /*
  1513. * Enable the transceiver if necessary and determine whether
  1514. * busmastering can be used. Due to bugs in the first revision
  1515. * of the 3C59[05], don't use busmastering at 10Mbps.
  1516. */
  1517. XCVRDEBUG("reset: xcvr %uX\n", ctlr->xcvr);
  1518. /*
  1519. * Allow user to specify desired media in plan9.ini
  1520. */
  1521. for(i = 0; i < ether->nopt; i++){
  1522. if(cistrncmp(ether->opt[i], "media=", 6) != 0)
  1523. continue;
  1524. p = ether->opt[i]+6;
  1525. for(j = 0; j < nelem(media); j++)
  1526. if(cistrcmp(p, media[j].name) == 0)
  1527. ctlr->xcvr = media[j].xcvr;
  1528. }
  1529. /*
  1530. * forgive me, but i am weak
  1531. */
  1532. switch(ctlr->did){
  1533. default:
  1534. if(ctlr->xcvr & autoSelect)
  1535. ctlr->xcvr = autoselect(ctlr);
  1536. break;
  1537. case 0x5157:
  1538. case 0x6056:
  1539. case 0x4500:
  1540. case 0x7646:
  1541. case 0x9055:
  1542. case 0x9200:
  1543. case 0x9201:
  1544. case 0x9805:
  1545. ctlr->xcvr = xcvrMii;
  1546. resetctlr(ctlr);
  1547. break;
  1548. }
  1549. XCVRDEBUG("xcvr selected: %uX, did 0x%uX\n", ctlr->xcvr, ctlr->did);
  1550. switch(ctlr->xcvr){
  1551. case xcvrMii:
  1552. /*
  1553. * Quick hack.
  1554. */
  1555. if(ctlr->did == 0x5157)
  1556. phyaddr = 0;
  1557. else if(ctlr->did == 0x6056)
  1558. phyaddr = scanphy(port);
  1559. else
  1560. phyaddr = 24;
  1561. for(i = 0; i < 7; i++)
  1562. XCVRDEBUG(" %2.2uX", miir(port, phyaddr, i));
  1563. XCVRDEBUG("\n");
  1564. for(timeo = 0; timeo < 30; timeo++){
  1565. phystat = miir(port, phyaddr, 0x01);
  1566. if(phystat & 0x20)
  1567. break;
  1568. XCVRDEBUG(" %2.2uX", phystat);
  1569. delay(100);
  1570. }
  1571. XCVRDEBUG(" %2.2uX", miir(port, phyaddr, 0x01));
  1572. XCVRDEBUG("\n");
  1573. anar = miir(port, phyaddr, 0x04);
  1574. anlpar = miir(port, phyaddr, 0x05) & 0x03E0;
  1575. anar &= anlpar;
  1576. miir(port, phyaddr, 0x00);
  1577. XCVRDEBUG("mii an: %uX anlp: %uX r0:%uX r1:%uX\n",
  1578. anar, anlpar, miir(port, phyaddr, 0x00),
  1579. miir(port, phyaddr, 0x01));
  1580. for(i = 0; i < ether->nopt; i++){
  1581. if(cistrcmp(ether->opt[i], "fullduplex") == 0)
  1582. anar |= 0x0100;
  1583. else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
  1584. anar |= 0x0100;
  1585. else if(cistrcmp(ether->opt[i], "force100") == 0)
  1586. anar |= 0x0080;
  1587. }
  1588. XCVRDEBUG("mii anar: %uX\n", anar);
  1589. if(anar & 0x0100){ /* 100BASE-TXFD */
  1590. //ether->mbps = 100;
  1591. setfullduplex(port);
  1592. }
  1593. else if(anar & 0x0200){ /* 100BASE-T4 */
  1594. /* nothing to do */
  1595. }
  1596. else if(anar & 0x0080){ /* 100BASE-TX */
  1597. //ether->mbps = 100;
  1598. }
  1599. else if(anar & 0x0040) /* 10BASE-TFD */
  1600. setfullduplex(port);
  1601. else{ /* 10BASE-T */
  1602. /* nothing to do */;
  1603. }
  1604. break;
  1605. case xcvr100BaseTX:
  1606. case xcvr100BaseFX:
  1607. COMMAND(port, SelectRegisterWindow, Wfifo);
  1608. x = inl(port+InternalConfig) & ~ramPartitionMask;
  1609. outl(port+InternalConfig, x|ramPartition1to1);
  1610. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  1611. x = ins(port+MediaStatus) & ~(dcConverterEnabled|jabberGuardEnable);
  1612. x |= linkBeatEnable;
  1613. outs(port+MediaStatus, x);
  1614. //if(x & dataRate100)
  1615. // ether->mbps = 100;
  1616. break;
  1617. case xcvr10BaseT:
  1618. /*
  1619. * Enable Link Beat and Jabber to start the
  1620. * transceiver.
  1621. */
  1622. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  1623. x = ins(port+MediaStatus) & ~dcConverterEnabled;
  1624. x |= linkBeatEnable|jabberGuardEnable;
  1625. outs(port+MediaStatus, x);
  1626. if((ctlr->did & 0xFF00) == 0x5900)
  1627. ctlr->busmaster = 0;
  1628. break;
  1629. case xcvr10Base2:
  1630. COMMAND(port, SelectRegisterWindow, Wdiagnostic);
  1631. x = ins(port+MediaStatus) & ~(linkBeatEnable|jabberGuardEnable);
  1632. outs(port+MediaStatus, x);
  1633. /*
  1634. * Start the DC-DC converter.
  1635. * Wait > 800 microseconds.
  1636. */
  1637. COMMAND(port, EnableDcConverter, 0);
  1638. delay(1);
  1639. break;
  1640. }
  1641. /*
  1642. * Wop is the normal operating register set.
  1643. * The 3C59[0257] adapters allow access to more than one register window
  1644. * at a time, but there are situations where switching still needs to be
  1645. * done, so just do it.
  1646. * Clear out any lingering Tx status.
  1647. */
  1648. COMMAND(port, SelectRegisterWindow, Wop);
  1649. if(ctlr->busmaster == 2)
  1650. x = port+TxStatus905;
  1651. else
  1652. x = port+TxStatus;
  1653. while(inb(x))
  1654. outb(x, 0);
  1655. /*
  1656. * Clear out the
  1657. * adapter statistics, clear the statistics logged into ctlr.
  1658. */
  1659. ilock(&ctlr->wlock);
  1660. statistics(ether);
  1661. memset(ctlr->stats, 0, sizeof(ctlr->stats));
  1662. //COMMAND(port, StatisticsEnable, 0);
  1663. /*
  1664. * Allocate any receive buffers.
  1665. */
  1666. if (ctlr->busmaster == 2) {
  1667. ctlr->dnenabled = 1;
  1668. /*
  1669. * 10MUpldBug.
  1670. * Disabling is too severe, can use receive busmastering at
  1671. * 100Mbps OK, but how to tell which rate is actually being used -
  1672. * the 3c905 always seems to have dataRate100 set?
  1673. * Believe the bug doesn't apply if upRxEarlyEnable is set
  1674. * and the threshold is set such that uploads won't start
  1675. * until the whole packet has been received.
  1676. */
  1677. ctlr->upenabled = 1;
  1678. x = eepromdata(ctlr, 0x0F);
  1679. if(!(x & 0x01))
  1680. outl(port+PktStatus, upRxEarlyEnable);
  1681. ctlr->nup = Nup;
  1682. ctlr->ndn = Ndn;
  1683. init905(ctlr);
  1684. outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
  1685. }
  1686. /*
  1687. * Set a base TxStartThresh which will be incremented
  1688. * if any txUnderrun errors occur and ensure no RxEarly
  1689. * interrupts happen.
  1690. */
  1691. ctlr->txthreshold = ETHERMAXTU/2;
  1692. COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);
  1693. COMMAND(port, SetRxEarlyThresh, ctlr->rxearly>>ctlr->ts);
  1694. iunlock(&ctlr->wlock);
  1695. /*
  1696. * Linkage to the generic ethernet driver.
  1697. */
  1698. ether->attach = attach;
  1699. ether->transmit = transmit;
  1700. ether->interrupt = interrupt;
  1701. return 0;
  1702. }