etherelnk3.c 43 KB

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