etherelnk3.c 42 KB

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