etherdp83820.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. /*
  2. * boot driver for
  3. * National Semiconductor DP83820
  4. * 10/100/1000 Mb/s Ethernet Network Interface Controller
  5. * (Gig-NIC).
  6. * Driver assumes little-endian and 32-bit host throughout.
  7. */
  8. #include "u.h"
  9. #include "lib.h"
  10. #include "mem.h"
  11. #include "dat.h"
  12. #include "fns.h"
  13. #include "io.h"
  14. #include "etherif.h"
  15. #include "ethermii.h"
  16. #define iprint print
  17. #define waserror() (0)
  18. #define poperror()
  19. enum { /* Registers */
  20. Cr = 0x00, /* Command */
  21. Cfg = 0x04, /* Configuration and Media Status */
  22. Mear = 0x08, /* MII/EEPROM Access */
  23. Ptscr = 0x0C, /* PCI Test Control */
  24. Isr = 0x10, /* Interrupt Status */
  25. Imr = 0x14, /* Interrupt Mask */
  26. Ier = 0x18, /* Interrupt Enable */
  27. Ihr = 0x1C, /* Interrupt Holdoff */
  28. Txdp = 0x20, /* Transmit Descriptor Pointer */
  29. Txdphi = 0x24, /* Transmit Descriptor Pointer Hi */
  30. Txcfg = 0x28, /* Transmit Configuration */
  31. Gpior = 0x2C, /* General Purpose I/O Control */
  32. Rxdp = 0x30, /* Receive Descriptor Pointer */
  33. Rxdphi = 0x34, /* Receive Descriptor Pointer Hi */
  34. Rxcfg = 0x38, /* Receive Configuration */
  35. Pqcr = 0x3C, /* Priority Queueing Control */
  36. Wcsr = 0x40, /* Wake on LAN Control/Status */
  37. Pcr = 0x44, /* Pause Control/Status */
  38. Rfcr = 0x48, /* Receive Filter/Match Control */
  39. Rfdr = 0x4C, /* Receive Filter/Match Data */
  40. Brar = 0x50, /* Boot ROM Address */
  41. Brdr = 0x54, /* Boot ROM Data */
  42. Srr = 0x58, /* Silicon Revision */
  43. Mibc = 0x5C, /* MIB Control */
  44. Mibd = 0x60, /* MIB Data */
  45. Txdp1 = 0xA0, /* Txdp Priority 1 */
  46. Txdp2 = 0xA4, /* Txdp Priority 2 */
  47. Txdp3 = 0xA8, /* Txdp Priority 3 */
  48. Rxdp1 = 0xB0, /* Rxdp Priority 1 */
  49. Rxdp2 = 0xB4, /* Rxdp Priority 2 */
  50. Rxdp3 = 0xB8, /* Rxdp Priority 3 */
  51. Vrcr = 0xBC, /* VLAN/IP Receive Control */
  52. Vtcr = 0xC0, /* VLAN/IP Transmit Control */
  53. Vdr = 0xC4, /* VLAN Data */
  54. Ccsr = 0xCC, /* Clockrun Control/Status */
  55. Tbicr = 0xE0, /* TBI Control */
  56. Tbisr = 0xE4, /* TBI Status */
  57. Tanar = 0xE8, /* TBI ANAR */
  58. Tanlpar = 0xEC, /* TBI ANLPAR */
  59. Taner = 0xF0, /* TBI ANER */
  60. Tesr = 0xF4, /* TBI ESR */
  61. };
  62. enum { /* Cr */
  63. Txe = 0x00000001, /* Transmit Enable */
  64. Txd = 0x00000002, /* Transmit Disable */
  65. Rxe = 0x00000004, /* Receiver Enable */
  66. Rxd = 0x00000008, /* Receiver Disable */
  67. Txr = 0x00000010, /* Transmitter Reset */
  68. Rxr = 0x00000020, /* Receiver Reset */
  69. Swien = 0x00000080, /* Software Interrupt Enable */
  70. Rst = 0x00000100, /* Reset */
  71. TxpriSHFT = 9, /* Tx Priority Queue Select */
  72. TxpriMASK = 0x00001E00,
  73. RxpriSHFT = 13, /* Rx Priority Queue Select */
  74. RxpriMASK = 0x0001E000,
  75. };
  76. enum { /* Configuration and Media Status */
  77. Bem = 0x00000001, /* Big Endian Mode */
  78. Ext125 = 0x00000002, /* External 125MHz reference Select */
  79. Bromdis = 0x00000004, /* Disable Boot ROM interface */
  80. Pesel = 0x00000008, /* Parity Error Detection Action */
  81. Exd = 0x00000010, /* Excessive Deferral Abort */
  82. Pow = 0x00000020, /* Program Out of Window Timer */
  83. Sb = 0x00000040, /* Single Back-off */
  84. Reqalg = 0x00000080, /* PCI Bus Request Algorithm */
  85. Extstsen = 0x00000100, /* Extended Status Enable */
  86. Phydis = 0x00000200, /* Disable PHY */
  87. Phyrst = 0x00000400, /* Reset PHY */
  88. M64addren = 0x00000800, /* Master 64-bit Addressing Enable */
  89. Data64en = 0x00001000, /* 64-bit Data Enable */
  90. Pci64det = 0x00002000, /* PCI 64-bit Bus Detected */
  91. T64addren = 0x00004000, /* Target 64-bit Addressing Enable */
  92. Mwidis = 0x00008000, /* MWI Disable */
  93. Mrmdis = 0x00010000, /* MRM Disable */
  94. Tmrtest = 0x00020000, /* Timer Test Mode */
  95. Spdstsien = 0x00040000, /* PHY Spdsts Interrupt Enable */
  96. Lnkstsien = 0x00080000, /* PHY Lnksts Interrupt Enable */
  97. Dupstsien = 0x00100000, /* PHY Dupsts Interrupt Enable */
  98. Mode1000 = 0x00400000, /* 1000Mb/s Mode Control */
  99. Tbien = 0x01000000, /* Ten-Bit Interface Enable */
  100. Dupsts = 0x10000000, /* Full Duplex Status */
  101. Spdsts100 = 0x20000000, /* SPEED100 Input Pin Status */
  102. Spdsts1000 = 0x40000000, /* SPEED1000 Input Pin Status */
  103. Lnksts = 0x80000000, /* Link Status */
  104. };
  105. enum { /* MII/EEPROM Access */
  106. Eedi = 0x00000001, /* EEPROM Data In */
  107. Eedo = 0x00000002, /* EEPROM Data Out */
  108. Eeclk = 0x00000004, /* EEPROM Serial Clock */
  109. Eesel = 0x00000008, /* EEPROM Chip Select */
  110. Mdio = 0x00000010, /* MII Management Data */
  111. Mddir = 0x00000020, /* MII Management Direction */
  112. Mdc = 0x00000040, /* MII Management Clock */
  113. };
  114. enum { /* Interrupts */
  115. Rxok = 0x00000001, /* Rx OK */
  116. Rxdesc = 0x00000002, /* Rx Descriptor */
  117. Rxerr = 0x00000004, /* Rx Packet Error */
  118. Rxearly = 0x00000008, /* Rx Early Threshold */
  119. Rxidle = 0x00000010, /* Rx Idle */
  120. Rxorn = 0x00000020, /* Rx Overrun */
  121. Txok = 0x00000040, /* Tx Packet OK */
  122. Txdesc = 0x00000080, /* Tx Descriptor */
  123. Txerr = 0x00000100, /* Tx Packet Error */
  124. Txidle = 0x00000200, /* Tx Idle */
  125. Txurn = 0x00000400, /* Tx Underrun */
  126. Mib = 0x00000800, /* MIB Service */
  127. Swi = 0x00001000, /* Software Interrupt */
  128. Pme = 0x00002000, /* Power Management Event */
  129. Phy = 0x00004000, /* PHY Interrupt */
  130. Hibint = 0x00008000, /* High Bits Interrupt Set */
  131. Rxsovr = 0x00010000, /* Rx Status FIFO Overrun */
  132. Rtabt = 0x00020000, /* Received Target Abort */
  133. Rmabt = 0x00040000, /* Received Master Abort */
  134. Sserr = 0x00080000, /* Signalled System Error */
  135. Dperr = 0x00100000, /* Detected Parity Error */
  136. Rxrcmp = 0x00200000, /* Receive Reset Complete */
  137. Txrcmp = 0x00400000, /* Transmit Reset Complete */
  138. Rxdesc0 = 0x00800000, /* Rx Descriptor for Priority Queue 0 */
  139. Rxdesc1 = 0x01000000, /* Rx Descriptor for Priority Queue 1 */
  140. Rxdesc2 = 0x02000000, /* Rx Descriptor for Priority Queue 2 */
  141. Rxdesc3 = 0x04000000, /* Rx Descriptor for Priority Queue 3 */
  142. Txdesc0 = 0x08000000, /* Tx Descriptor for Priority Queue 0 */
  143. Txdesc1 = 0x10000000, /* Tx Descriptor for Priority Queue 1 */
  144. Txdesc2 = 0x20000000, /* Tx Descriptor for Priority Queue 2 */
  145. Txdesc3 = 0x40000000, /* Tx Descriptor for Priority Queue 3 */
  146. };
  147. enum { /* Interrupt Enable */
  148. Ien = 0x00000001, /* Interrupt Enable */
  149. };
  150. enum { /* Interrupt Holdoff */
  151. IhSHFT = 0, /* Interrupt Holdoff */
  152. IhMASK = 0x000000FF,
  153. Ihctl = 0x00000100, /* Interrupt Holdoff Control */
  154. };
  155. enum { /* Transmit Configuration */
  156. TxdrthSHFT = 0, /* Tx Drain Threshold */
  157. TxdrthMASK = 0x000000FF,
  158. FlthSHFT = 16, /* Tx Fill Threshold */
  159. FlthMASK = 0x0000FF00,
  160. Brstdis = 0x00080000, /* 1000Mb/s Burst Disable */
  161. MxdmaSHFT = 20, /* Max Size per Tx DMA Burst */
  162. MxdmaMASK = 0x00700000,
  163. Ecretryen = 0x00800000, /* Excessive Collision Retry Enable */
  164. Atp = 0x10000000, /* Automatic Transmit Padding */
  165. Mlb = 0x20000000, /* MAC Loopback */
  166. Hbi = 0x40000000, /* Heartbeat Ignore */
  167. Csi = 0x80000000, /* Carrier Sense Ignore */
  168. };
  169. enum { /* Receive Configuration */
  170. RxdrthSHFT = 1, /* Rx Drain Threshold */
  171. RxdrthMASK = 0x0000003E,
  172. Airl = 0x04000000, /* Accept In-Range Length Errored */
  173. Alp = 0x08000000, /* Accept Long Packets */
  174. Rxfd = 0x10000000, /* Receive Full Duplex */
  175. Stripcrc = 0x20000000, /* Strip CRC */
  176. Arp = 0x40000000, /* Accept Runt Packets */
  177. Aep = 0x80000000, /* Accept Errored Packets */
  178. };
  179. enum { /* Priority Queueing Control */
  180. Txpqen = 0x00000001, /* Transmit Priority Queuing Enable */
  181. Txfairen = 0x00000002, /* Transmit Fairness Enable */
  182. RxpqenSHFT = 2, /* Receive Priority Queue Enable */
  183. RxpqenMASK = 0x0000000C,
  184. };
  185. enum { /* Pause Control/Status */
  186. PscntSHFT = 0, /* Pause Counter Value */
  187. PscntMASK = 0x0000FFFF,
  188. Pstx = 0x00020000, /* Transmit Pause Frame */
  189. PsffloSHFT = 18, /* Rx Data FIFO Lo Threshold */
  190. PsffloMASK = 0x000C0000,
  191. PsffhiSHFT = 20, /* Rx Data FIFO Hi Threshold */
  192. PsffhiMASK = 0x00300000,
  193. PsstloSHFT = 22, /* Rx Stat FIFO Hi Threshold */
  194. PsstloMASK = 0x00C00000,
  195. PssthiSHFT = 24, /* Rx Stat FIFO Hi Threshold */
  196. PssthiMASK = 0x03000000,
  197. Psrcvd = 0x08000000, /* Pause Frame Received */
  198. Psact = 0x10000000, /* Pause Active */
  199. Psda = 0x20000000, /* Pause on Destination Address */
  200. Psmcast = 0x40000000, /* Pause on Multicast */
  201. Psen = 0x80000000, /* Pause Enable */
  202. };
  203. enum { /* Receive Filter/Match Control */
  204. RfaddrSHFT = 0, /* Extended Register Address */
  205. RfaddrMASK = 0x000003FF,
  206. Ulm = 0x00080000, /* U/L bit mask */
  207. Uhen = 0x00100000, /* Unicast Hash Enable */
  208. Mhen = 0x00200000, /* Multicast Hash Enable */
  209. Aarp = 0x00400000, /* Accept ARP Packets */
  210. ApatSHFT = 23, /* Accept on Pattern Match */
  211. ApatMASK = 0x07800000,
  212. Apm = 0x08000000, /* Accept on Perfect Match */
  213. Aau = 0x10000000, /* Accept All Unicast */
  214. Aam = 0x20000000, /* Accept All Multicast */
  215. Aab = 0x40000000, /* Accept All Broadcast */
  216. Rfen = 0x80000000, /* Rx Filter Enable */
  217. };
  218. enum { /* Receive Filter/Match Data */
  219. RfdataSHFT = 0, /* Receive Filter Data */
  220. RfdataMASK = 0x0000FFFF,
  221. BmaskSHFT = 16, /* Byte Mask */
  222. BmaskMASK = 0x00030000,
  223. };
  224. enum { /* MIB Control */
  225. Wrn = 0x00000001, /* Warning Test Indicator */
  226. Frz = 0x00000002, /* Freeze All Counters */
  227. Aclr = 0x00000004, /* Clear All Counters */
  228. Mibs = 0x00000008, /* MIB Counter Strobe */
  229. };
  230. enum { /* MIB Data */
  231. Nmibd = 11, /* Number of MIB Data Registers */
  232. };
  233. enum { /* VLAN/IP Receive Control */
  234. Vtden = 0x00000001, /* VLAN Tag Detection Enable */
  235. Vtren = 0x00000002, /* VLAN Tag Removal Enable */
  236. Dvtf = 0x00000004, /* Discard VLAN Tagged Frames */
  237. Dutf = 0x00000008, /* Discard Untagged Frames */
  238. Ipen = 0x00000010, /* IP Checksum Enable */
  239. Ripe = 0x00000020, /* Reject IP Checksum Errors */
  240. Rtcpe = 0x00000040, /* Reject TCP Checksum Errors */
  241. Rudpe = 0x00000080, /* Reject UDP Checksum Errors */
  242. };
  243. enum { /* VLAN/IP Transmit Control */
  244. Vgti = 0x00000001, /* VLAN Global Tag Insertion */
  245. Vppti = 0x00000002, /* VLAN Per-Packet Tag Insertion */
  246. Gchk = 0x00000004, /* Global Checksum Generation */
  247. Ppchk = 0x00000008, /* Per-Packet Checksum Generation */
  248. };
  249. enum { /* VLAN Data */
  250. VtypeSHFT = 0, /* VLAN Type Field */
  251. VtypeMASK = 0x0000FFFF,
  252. VtciSHFT = 16, /* VLAN Tag Control Information */
  253. VtciMASK = 0xFFFF0000,
  254. };
  255. enum { /* Clockrun Control/Status */
  256. Clkrunen = 0x00000001, /* CLKRUN Enable */
  257. Pmeen = 0x00000100, /* PME Enable */
  258. Pmests = 0x00008000, /* PME Status */
  259. };
  260. typedef struct {
  261. u32int link; /* Link to the next descriptor */
  262. u32int bufptr; /* pointer to data Buffer */
  263. int cmdsts; /* Command/Status */
  264. int extsts; /* optional Extended Status */
  265. Block* bp; /* Block containing bufptr */
  266. u32int unused; /* pad to 64-bit */
  267. } Desc;
  268. enum { /* Common cmdsts bits */
  269. SizeMASK = 0x0000FFFF, /* Descriptor Byte Count */
  270. SizeSHFT = 0,
  271. Ok = 0x08000000, /* Packet OK */
  272. Crc = 0x10000000, /* Suppress/Include CRC */
  273. Intr = 0x20000000, /* Interrupt on ownership transfer */
  274. More = 0x40000000, /* not last descriptor in a packet */
  275. Own = 0x80000000, /* Descriptor Ownership */
  276. };
  277. enum { /* Transmit cmdsts bits */
  278. CcntMASK = 0x000F0000, /* Collision Count */
  279. CcntSHFT = 16,
  280. Ec = 0x00100000, /* Excessive Collisions */
  281. Owc = 0x00200000, /* Out of Window Collision */
  282. Ed = 0x00400000, /* Excessive Deferral */
  283. Td = 0x00800000, /* Transmit Deferred */
  284. Crs = 0x01000000, /* Carrier Sense Lost */
  285. Tfu = 0x02000000, /* Transmit FIFO Underrun */
  286. Txa = 0x04000000, /* Transmit Abort */
  287. };
  288. enum { /* Receive cmdsts bits */
  289. Irl = 0x00010000, /* In-Range Length Error */
  290. Lbp = 0x00020000, /* Loopback Packet */
  291. Fae = 0x00040000, /* Frame Alignment Error */
  292. Crce = 0x00080000, /* CRC Error */
  293. Ise = 0x00100000, /* Invalid Symbol Error */
  294. Runt = 0x00200000, /* Runt Packet Received */
  295. Long = 0x00400000, /* Too Long Packet Received */
  296. DestMASK = 0x01800000, /* Destination Class */
  297. DestSHFT = 23,
  298. Rxo = 0x02000000, /* Receive Overrun */
  299. Rxa = 0x04000000, /* Receive Aborted */
  300. };
  301. enum { /* extsts bits */
  302. EvtciMASK = 0x0000FFFF, /* VLAN Tag Control Information */
  303. EvtciSHFT = 0,
  304. Vpkt = 0x00010000, /* VLAN Packet */
  305. Ippkt = 0x00020000, /* IP Packet */
  306. Iperr = 0x00040000, /* IP Checksum Error */
  307. Tcppkt = 0x00080000, /* TCP Packet */
  308. Tcperr = 0x00100000, /* TCP Checksum Error */
  309. Udppkt = 0x00200000, /* UDP Packet */
  310. Udperr = 0x00400000, /* UDP Checksum Error */
  311. };
  312. enum {
  313. Nrd = 32, /* was 256 */
  314. Nrbf = 4*Nrd,
  315. Rbsz = ROUNDUP(sizeof(Etherpkt)+8, 8),
  316. Ntd = 8, /* was 128 */
  317. };
  318. typedef struct Ctlr Ctlr;
  319. struct Ctlr {
  320. int port;
  321. Pcidev* pcidev;
  322. Ctlr* next;
  323. int active;
  324. int id;
  325. int eepromsz; /* address size in bits */
  326. ushort* eeprom;
  327. int* nic;
  328. int cfg;
  329. int imr;
  330. Lock alock; /* attach */
  331. Lock ilock; /* init */
  332. void* alloc; /* base of per-Ctlr allocated data */
  333. Mii* mii;
  334. Lock rdlock; /* receive */
  335. Desc* rd;
  336. int nrd;
  337. int nrb;
  338. int rdx;
  339. int rxcfg;
  340. Lock tlock; /* transmit */
  341. Desc* td;
  342. int ntd;
  343. int tdh;
  344. int tdt;
  345. int ntq;
  346. int txcfg;
  347. int rxidle;
  348. uint mibd[Nmibd];
  349. int ec;
  350. int owc;
  351. int ed;
  352. int crs;
  353. int tfu;
  354. int txa;
  355. };
  356. #define csr32r(c, r) (*((c)->nic+((r)/4)))
  357. #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
  358. static Ctlr* dp83820ctlrhead;
  359. static Ctlr* dp83820ctlrtail;
  360. static Lock dp83820rblock; /* free receive Blocks */
  361. static Block* dp83820rbpool;
  362. static char* dp83820mibs[Nmibd] = {
  363. "RXErroredPkts",
  364. "RXFCSErrors",
  365. "RXMsdPktErrors",
  366. "RXFAErrors",
  367. "RXSymbolErrors",
  368. "RXFrameToLong",
  369. "RXIRLErrors",
  370. "RXBadOpcodes",
  371. "RXPauseFrames",
  372. "TXPauseFrames",
  373. "TXSQEErrors",
  374. };
  375. static int
  376. mdior(Ctlr* ctlr, int n)
  377. {
  378. int data, i, mear, r;
  379. mear = csr32r(ctlr, Mear);
  380. r = ~(Mdc|Mddir) & mear;
  381. data = 0;
  382. for(i = n-1; i >= 0; i--){
  383. if(csr32r(ctlr, Mear) & Mdio)
  384. data |= (1<<i);
  385. csr32w(ctlr, Mear, Mdc|r);
  386. csr32w(ctlr, Mear, r);
  387. }
  388. csr32w(ctlr, Mear, mear);
  389. return data;
  390. }
  391. static void
  392. mdiow(Ctlr* ctlr, int bits, int n)
  393. {
  394. int i, mear, r;
  395. mear = csr32r(ctlr, Mear);
  396. r = Mddir|(~Mdc & mear);
  397. for(i = n-1; i >= 0; i--){
  398. if(bits & (1<<i))
  399. r |= Mdio;
  400. else
  401. r &= ~Mdio;
  402. csr32w(ctlr, Mear, r);
  403. csr32w(ctlr, Mear, Mdc|r);
  404. }
  405. csr32w(ctlr, Mear, mear);
  406. }
  407. static int
  408. dp83820miimir(Mii* mii, int pa, int ra)
  409. {
  410. int data;
  411. Ctlr *ctlr;
  412. ctlr = mii->ctlr;
  413. /*
  414. * MII Management Interface Read.
  415. *
  416. * Preamble;
  417. * ST+OP+PA+RA;
  418. * LT + 16 data bits.
  419. */
  420. mdiow(ctlr, 0xFFFFFFFF, 32);
  421. mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
  422. data = mdior(ctlr, 18);
  423. if(data & 0x10000)
  424. return -1;
  425. return data & 0xFFFF;
  426. }
  427. static int
  428. dp83820miimiw(Mii* mii, int pa, int ra, int data)
  429. {
  430. Ctlr *ctlr;
  431. ctlr = mii->ctlr;
  432. /*
  433. * MII Management Interface Write.
  434. *
  435. * Preamble;
  436. * ST+OP+PA+RA+LT + 16 data bits;
  437. * Z.
  438. */
  439. mdiow(ctlr, 0xFFFFFFFF, 32);
  440. data &= 0xFFFF;
  441. data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
  442. mdiow(ctlr, data, 32);
  443. return 0;
  444. }
  445. static Block *
  446. dp83820rballoc(Desc* desc)
  447. {
  448. Block *bp;
  449. if(desc->bp == nil){
  450. ilock(&dp83820rblock);
  451. if((bp = dp83820rbpool) == nil){
  452. iunlock(&dp83820rblock);
  453. desc->bp = nil;
  454. desc->cmdsts = Own;
  455. return nil;
  456. }
  457. dp83820rbpool = bp->next;
  458. bp->next = nil;
  459. iunlock(&dp83820rblock);
  460. desc->bufptr = PCIWADDR(bp->rp);
  461. desc->bp = bp;
  462. }
  463. else{
  464. bp = desc->bp;
  465. bp->rp = bp->lim - Rbsz;
  466. bp->wp = bp->rp;
  467. }
  468. coherence();
  469. desc->cmdsts = Intr|Rbsz;
  470. return bp;
  471. }
  472. static void
  473. dp83820rbfree(Block *bp)
  474. {
  475. bp->rp = bp->lim - Rbsz;
  476. bp->wp = bp->rp;
  477. ilock(&dp83820rblock);
  478. bp->next = dp83820rbpool;
  479. dp83820rbpool = bp;
  480. iunlock(&dp83820rblock);
  481. }
  482. static void
  483. dp83820halt(Ctlr* ctlr)
  484. {
  485. int i, timeo;
  486. ilock(&ctlr->ilock);
  487. csr32w(ctlr, Imr, 0);
  488. csr32w(ctlr, Ier, 0);
  489. csr32w(ctlr, Cr, Rxd|Txd);
  490. for(timeo = 0; timeo < 1000; timeo++){
  491. if(!(csr32r(ctlr, Cr) & (Rxe|Txe)))
  492. break;
  493. microdelay(1);
  494. }
  495. csr32w(ctlr, Mibc, Frz);
  496. iunlock(&ctlr->ilock);
  497. if(ctlr->rd != nil){
  498. for(i = 0; i < ctlr->nrd; i++){
  499. if(ctlr->rd[i].bp == nil)
  500. continue;
  501. freeb(ctlr->rd[i].bp);
  502. ctlr->rd[i].bp = nil;
  503. }
  504. }
  505. if(ctlr->td != nil){
  506. for(i = 0; i < ctlr->ntd; i++){
  507. if(ctlr->td[i].bp == nil)
  508. continue;
  509. freeb(ctlr->td[i].bp);
  510. ctlr->td[i].bp = nil;
  511. }
  512. }
  513. }
  514. static void
  515. dp83820cfg(Ctlr* ctlr)
  516. {
  517. int cfg;
  518. /*
  519. * Don't know how to deal with a TBI yet.
  520. */
  521. if(ctlr->mii == nil)
  522. return;
  523. /*
  524. * The polarity of these bits is at the mercy
  525. * of the board designer.
  526. * The correct answer for all speed and duplex questions
  527. * should be to query the phy.
  528. */
  529. cfg = csr32r(ctlr, Cfg);
  530. if(!(cfg & Dupsts)){
  531. ctlr->rxcfg |= Rxfd;
  532. ctlr->txcfg |= Csi|Hbi;
  533. iprint("83820: full duplex, ");
  534. }
  535. else{
  536. ctlr->rxcfg &= ~Rxfd;
  537. ctlr->txcfg &= ~(Csi|Hbi);
  538. iprint("83820: half duplex, ");
  539. }
  540. csr32w(ctlr, Rxcfg, ctlr->rxcfg);
  541. csr32w(ctlr, Txcfg, ctlr->txcfg);
  542. switch(cfg & (Spdsts1000|Spdsts100)){
  543. case Spdsts1000: /* 100Mbps */
  544. default: /* 10Mbps */
  545. ctlr->cfg &= ~Mode1000;
  546. if((cfg & (Spdsts1000|Spdsts100)) == Spdsts1000)
  547. iprint("100Mb/s\n");
  548. else
  549. iprint("10Mb/s\n");
  550. break;
  551. case Spdsts100: /* 1Gbps */
  552. ctlr->cfg |= Mode1000;
  553. iprint("1Gb/s\n");
  554. break;
  555. }
  556. csr32w(ctlr, Cfg, ctlr->cfg);
  557. }
  558. static void
  559. dp83820init(Ether* edev)
  560. {
  561. int i;
  562. Ctlr *ctlr;
  563. Desc *desc;
  564. uchar *alloc;
  565. ctlr = edev->ctlr;
  566. dp83820halt(ctlr);
  567. /*
  568. * Receiver
  569. */
  570. alloc = (uchar*)ROUNDUP((ulong)ctlr->alloc, 8);
  571. ctlr->rd = (Desc*)alloc;
  572. alloc += ctlr->nrd*sizeof(Desc);
  573. memset(ctlr->rd, 0, ctlr->nrd*sizeof(Desc));
  574. ctlr->rdx = 0;
  575. for(i = 0; i < ctlr->nrd; i++){
  576. desc = &ctlr->rd[i];
  577. desc->link = PCIWADDR(&ctlr->rd[NEXT(i, ctlr->nrd)]);
  578. if(dp83820rballoc(desc) == nil)
  579. continue;
  580. }
  581. csr32w(ctlr, Rxdphi, 0);
  582. csr32w(ctlr, Rxdp, PCIWADDR(ctlr->rd));
  583. for(i = 0; i < Eaddrlen; i += 2){
  584. csr32w(ctlr, Rfcr, i);
  585. csr32w(ctlr, Rfdr, (edev->ea[i+1]<<8)|edev->ea[i]);
  586. }
  587. csr32w(ctlr, Rfcr, Rfen|Aab|Aam|Apm);
  588. ctlr->rxcfg = Stripcrc|(((2*(ETHERMINTU+4))/8)<<RxdrthSHFT);
  589. ctlr->imr |= Rxorn|Rxidle|Rxearly|Rxdesc|Rxok;
  590. /*
  591. * Transmitter.
  592. */
  593. ctlr->td = (Desc*)alloc;
  594. memset(ctlr->td, 0, ctlr->ntd*sizeof(Desc));
  595. ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
  596. for(i = 0; i < ctlr->ntd; i++){
  597. desc = &ctlr->td[i];
  598. desc->link = PCIWADDR(&ctlr->td[NEXT(i, ctlr->ntd)]);
  599. }
  600. csr32w(ctlr, Txdphi, 0);
  601. csr32w(ctlr, Txdp, PCIWADDR(ctlr->td));
  602. ctlr->txcfg = Atp|(((2*(ETHERMINTU+4))/32)<<FlthSHFT)|((4096/32)<<TxdrthSHFT);
  603. ctlr->imr |= Txurn|Txidle|Txdesc|Txok;
  604. ilock(&ctlr->ilock);
  605. dp83820cfg(ctlr);
  606. csr32w(ctlr, Mibc, Aclr);
  607. ctlr->imr |= Mib;
  608. csr32w(ctlr, Imr, ctlr->imr);
  609. /* try coalescing adjacent interrupts; use hold-off interval of 100µs */
  610. csr32w(ctlr, Ihr, Ihctl|(1<<IhSHFT));
  611. csr32w(ctlr, Ier, Ien);
  612. csr32w(ctlr, Cr, Rxe|Txe);
  613. iunlock(&ctlr->ilock);
  614. }
  615. static void
  616. dp83820attach(Ether* edev)
  617. {
  618. Block *bp;
  619. Ctlr *ctlr;
  620. ctlr = edev->ctlr;
  621. lock(&ctlr->alock);
  622. if(ctlr->alloc != nil){
  623. unlock(&ctlr->alock);
  624. return;
  625. }
  626. if(waserror()){
  627. err:
  628. if(ctlr->mii != nil){
  629. free(ctlr->mii);
  630. ctlr->mii = nil;
  631. }
  632. if(ctlr->alloc != nil){
  633. free(ctlr->alloc);
  634. ctlr->alloc = nil;
  635. }
  636. unlock(&ctlr->alock);
  637. return;
  638. }
  639. if(!(ctlr->cfg & Tbien)){
  640. if((ctlr->mii = malloc(sizeof(Mii))) == nil)
  641. goto err;
  642. ctlr->mii->ctlr = ctlr;
  643. ctlr->mii->mir = dp83820miimir;
  644. ctlr->mii->miw = dp83820miimiw;
  645. if(mii(ctlr->mii, ~0) == 0)
  646. goto err;
  647. ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien;
  648. ctlr->imr |= Phy;
  649. }
  650. ctlr->nrd = Nrd;
  651. ctlr->nrb = Nrbf;
  652. ctlr->ntd = Ntd;
  653. ctlr->alloc = mallocz((ctlr->nrd+ctlr->ntd)*sizeof(Desc) + 7, 0);
  654. if(ctlr->alloc == nil)
  655. goto err;
  656. /*
  657. * the Bill Paul bsd drivers claim that receive buffers must be aligned
  658. * on 8-byte boundaries.
  659. */
  660. for(ctlr->nrb = 0; ctlr->nrb < Nrbf; ctlr->nrb++){
  661. if((bp = allocb(Rbsz+8-1)) == nil)
  662. break;
  663. bp->rp += 8 - (uintptr)bp->rp % 8;
  664. bp->wp = bp->rp;
  665. // bp->free = dp83820rbfree; /* TODO: fix */
  666. dp83820rbfree(bp);
  667. }
  668. dp83820init(edev);
  669. unlock(&ctlr->alock);
  670. poperror();
  671. }
  672. /*
  673. * free a list of blocks
  674. */
  675. static void
  676. freeblist(Block *b)
  677. {
  678. Block *next;
  679. for(; b != 0; b = next){
  680. next = b->next;
  681. b->next = 0;
  682. freeb(b);
  683. }
  684. }
  685. static void
  686. toringbuf(Ether *ether, Block *bp)
  687. {
  688. RingBuf *rb = &ether->rb[ether->ri];
  689. if (rb->owner == Interface) {
  690. rb->len = BLEN(bp);
  691. memmove(rb->pkt, bp->rp, rb->len);
  692. rb->owner = Host;
  693. ether->ri = NEXT(ether->ri, ether->nrb);
  694. }
  695. /* else no one is expecting packets from the network */
  696. }
  697. static Block *
  698. fromringbuf(Ether *ether)
  699. {
  700. RingBuf *tb = &ether->tb[ether->ti];
  701. Block *bp = allocb(tb->len);
  702. memmove(bp->wp, tb->pkt, tb->len);
  703. memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
  704. bp->wp += tb->len;
  705. return bp;
  706. }
  707. static void
  708. dp83820transmit(Ether* edev)
  709. {
  710. Block *bp;
  711. Ctlr *ctlr;
  712. Desc *desc;
  713. RingBuf *tb;
  714. int cmdsts, r, x;
  715. ctlr = edev->ctlr;
  716. ilock(&ctlr->tlock);
  717. bp = nil;
  718. for(x = ctlr->tdh; ctlr->ntq; x = NEXT(x, ctlr->ntd)){
  719. desc = &ctlr->td[x];
  720. if((cmdsts = desc->cmdsts) & Own)
  721. break;
  722. if(!(cmdsts & Ok)){
  723. if(cmdsts & Ec)
  724. ctlr->ec++;
  725. if(cmdsts & Owc)
  726. ctlr->owc++;
  727. if(cmdsts & Ed)
  728. ctlr->ed++;
  729. if(cmdsts & Crs)
  730. ctlr->crs++;
  731. if(cmdsts & Tfu)
  732. ctlr->tfu++;
  733. if(cmdsts & Txa)
  734. ctlr->txa++;
  735. }
  736. desc->bp->next = bp;
  737. bp = desc->bp;
  738. desc->bp = nil;
  739. ctlr->ntq--;
  740. }
  741. ctlr->tdh = x;
  742. if(bp != nil)
  743. freeblist(bp);
  744. x = ctlr->tdt;
  745. // tb = &edev->tb[edev->ti];
  746. while(ctlr->ntq < ctlr->ntd - 1 /* && tb->owner == Interface */ ){
  747. bp = fromringbuf(edev);
  748. if (bp == nil)
  749. break;
  750. /* transmit packet from bp */
  751. desc = &ctlr->td[x];
  752. desc->bufptr = PCIWADDR(bp->rp);
  753. desc->bp = bp;
  754. ctlr->ntq++;
  755. coherence();
  756. desc->cmdsts = Own|Intr|BLEN(bp); /* kick transmitter */
  757. //print("t");
  758. tb = &edev->tb[edev->ti];
  759. tb->owner = Host; /* give descriptor back */
  760. edev->ti = NEXT(edev->ti, edev->ntb);
  761. x = NEXT(x, ctlr->ntd);
  762. }
  763. if(x != ctlr->tdt){
  764. ctlr->tdt = x;
  765. r = csr32r(ctlr, Cr);
  766. csr32w(ctlr, Cr, Txe|r);
  767. }
  768. iunlock(&ctlr->tlock);
  769. }
  770. static void
  771. dp83820interrupt(Ureg*, void* arg)
  772. {
  773. Block *bp;
  774. Ctlr *ctlr;
  775. Desc *desc;
  776. Ether *edev;
  777. int cmdsts, i, isr, r, x;
  778. edev = arg;
  779. ctlr = edev->ctlr;
  780. for(isr = csr32r(ctlr, Isr); isr & ctlr->imr; isr = csr32r(ctlr, Isr)){
  781. if(isr & (Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok)){
  782. x = ctlr->rdx;
  783. desc = &ctlr->rd[x];
  784. while((cmdsts = desc->cmdsts) & Own){
  785. if((cmdsts & Ok) && desc->bp != nil){
  786. /* receive a packet into desc->bp */
  787. bp = desc->bp;
  788. desc->bp = nil;
  789. // bp->rp = desc->bufptr;
  790. bp->wp += cmdsts & SizeMASK;
  791. toringbuf(edev, bp);
  792. //print("r");
  793. }
  794. dp83820rballoc(desc);
  795. x = NEXT(x, ctlr->nrd);
  796. desc = &ctlr->rd[x];
  797. }
  798. ctlr->rdx = x;
  799. if(isr & Rxidle){
  800. r = csr32r(ctlr, Cr);
  801. csr32w(ctlr, Cr, Rxe|r);
  802. ctlr->rxidle++;
  803. }
  804. isr &= ~(Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok);
  805. }
  806. if(isr & Txurn){
  807. x = (ctlr->txcfg & TxdrthMASK)>>TxdrthSHFT;
  808. r = (ctlr->txcfg & FlthMASK)>>FlthSHFT;
  809. if(x < ((TxdrthMASK)>>TxdrthSHFT)
  810. && x < (2048/32 - r)){
  811. ctlr->txcfg &= ~TxdrthMASK;
  812. x++;
  813. ctlr->txcfg |= x<<TxdrthSHFT;
  814. csr32w(ctlr, Txcfg, ctlr->txcfg);
  815. }
  816. }
  817. if(isr & (Txurn|Txidle|Txdesc|Txok)){
  818. dp83820transmit(edev);
  819. isr &= ~(Txurn|Txidle|Txdesc|Txok);
  820. }
  821. if(isr & Mib){
  822. for(i = 0; i < Nmibd; i++){
  823. r = csr32r(ctlr, Mibd+(i*sizeof(int)));
  824. ctlr->mibd[i] += r & 0xFFFF;
  825. }
  826. isr &= ~Mib;
  827. }
  828. if((isr & Phy) && ctlr->mii != nil){
  829. ctlr->mii->mir(ctlr->mii, 1, Bmsr);
  830. print("phy: cfg %8.8uX bmsr %4.4uX\n",
  831. csr32r(ctlr, Cfg),
  832. ctlr->mii->mir(ctlr->mii, 1, Bmsr));
  833. dp83820cfg(ctlr);
  834. isr &= ~Phy;
  835. }
  836. // TODO fix if(isr)
  837. // TODO fix iprint("dp83820: isr %8.8uX\n", isr);
  838. USED(isr);
  839. }
  840. }
  841. static int
  842. dp83820detach(Ctlr* ctlr)
  843. {
  844. /*
  845. * Soft reset the controller.
  846. */
  847. csr32w(ctlr, Cr, Rst);
  848. delay(1);
  849. while(csr32r(ctlr, Cr) & Rst)
  850. delay(1);
  851. return 0;
  852. }
  853. static void
  854. dp83820shutdown(Ether* ether)
  855. {
  856. print("dp83820shutdown\n");
  857. dp83820detach(ether->ctlr);
  858. }
  859. static int
  860. atc93c46r(Ctlr* ctlr, int address)
  861. {
  862. int data, i, mear, r, size;
  863. /*
  864. * Analog Technology, Inc. ATC93C46
  865. * or equivalent serial EEPROM.
  866. */
  867. mear = csr32r(ctlr, Mear);
  868. mear &= ~(Eesel|Eeclk|Eedo|Eedi);
  869. r = Eesel|mear;
  870. reread:
  871. csr32w(ctlr, Mear, r);
  872. data = 0x06;
  873. for(i = 3-1; i >= 0; i--){
  874. if(data & (1<<i))
  875. r |= Eedi;
  876. else
  877. r &= ~Eedi;
  878. csr32w(ctlr, Mear, r);
  879. csr32w(ctlr, Mear, Eeclk|r);
  880. microdelay(1);
  881. csr32w(ctlr, Mear, r);
  882. microdelay(1);
  883. }
  884. /*
  885. * First time through must work out the EEPROM size.
  886. */
  887. if((size = ctlr->eepromsz) == 0)
  888. size = 8;
  889. for(size = size-1; size >= 0; size--){
  890. if(address & (1<<size))
  891. r |= Eedi;
  892. else
  893. r &= ~Eedi;
  894. csr32w(ctlr, Mear, r);
  895. microdelay(1);
  896. csr32w(ctlr, Mear, Eeclk|r);
  897. microdelay(1);
  898. csr32w(ctlr, Mear, r);
  899. microdelay(1);
  900. if(!(csr32r(ctlr, Mear) & Eedo))
  901. break;
  902. }
  903. r &= ~Eedi;
  904. data = 0;
  905. for(i = 16-1; i >= 0; i--){
  906. csr32w(ctlr, Mear, Eeclk|r);
  907. microdelay(1);
  908. if(csr32r(ctlr, Mear) & Eedo)
  909. data |= (1<<i);
  910. csr32w(ctlr, Mear, r);
  911. microdelay(1);
  912. }
  913. csr32w(ctlr, Mear, mear);
  914. if(ctlr->eepromsz == 0){
  915. ctlr->eepromsz = 8-size;
  916. ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
  917. goto reread;
  918. }
  919. return data;
  920. }
  921. static int
  922. dp83820reset(Ctlr* ctlr)
  923. {
  924. int i, r;
  925. unsigned char sum;
  926. /*
  927. * Soft reset the controller;
  928. * read the EEPROM to get the initial settings
  929. * of the Cfg and Gpior bits which should be cleared by
  930. * the reset.
  931. */
  932. csr32w(ctlr, Cr, Rst);
  933. delay(1);
  934. while(csr32r(ctlr, Cr) & Rst)
  935. delay(1);
  936. atc93c46r(ctlr, 0);
  937. if(ctlr->eeprom == nil) {
  938. print("dp83820reset: no eeprom\n");
  939. return -1;
  940. }
  941. sum = 0;
  942. for(i = 0; i < 0x0E; i++){
  943. r = atc93c46r(ctlr, i);
  944. ctlr->eeprom[i] = r;
  945. sum += r;
  946. sum += r>>8;
  947. }
  948. if(sum != 0){
  949. print("dp83820reset: bad EEPROM checksum\n");
  950. return -1;
  951. }
  952. #ifdef notdef
  953. csr32w(ctlr, Gpior, ctlr->eeprom[4]);
  954. cfg = Extstsen|Exd;
  955. r = csr32r(ctlr, Cfg);
  956. if(ctlr->eeprom[5] & 0x0001)
  957. cfg |= Ext125;
  958. if(ctlr->eeprom[5] & 0x0002)
  959. cfg |= M64addren;
  960. if((ctlr->eeprom[5] & 0x0004) && (r & Pci64det))
  961. cfg |= Data64en;
  962. if(ctlr->eeprom[5] & 0x0008)
  963. cfg |= T64addren;
  964. if(!(pcicfgr16(ctlr->pcidev, PciPCR) & 0x10))
  965. cfg |= Mwidis;
  966. if(ctlr->eeprom[5] & 0x0020)
  967. cfg |= Mrmdis;
  968. if(ctlr->eeprom[5] & 0x0080)
  969. cfg |= Mode1000;
  970. if(ctlr->eeprom[5] & 0x0200)
  971. cfg |= Tbien|Mode1000;
  972. /*
  973. * What about RO bits we might have destroyed with Rst?
  974. * What about Exd, Tmrtest, Extstsen, Pintctl?
  975. * Why does it think it has detected a 64-bit bus when
  976. * it hasn't?
  977. */
  978. #else
  979. //r = csr32r(ctlr, Cfg);
  980. //r &= ~(Mode1000|T64addren|Data64en|M64addren);
  981. //csr32w(ctlr, Cfg, r);
  982. //csr32w(ctlr, Cfg, 0x2000);
  983. #endif /* notdef */
  984. ctlr->cfg = csr32r(ctlr, Cfg);
  985. print("cfg %8.8uX pcicfg %8.8uX\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR));
  986. ctlr->cfg &= ~(T64addren|Data64en|M64addren);
  987. csr32w(ctlr, Cfg, ctlr->cfg);
  988. csr32w(ctlr, Mibc, Aclr|Frz);
  989. return 0;
  990. }
  991. static void
  992. dp83820pci(void)
  993. {
  994. int port;
  995. Pcidev *p;
  996. Ctlr *ctlr;
  997. p = nil;
  998. while(p = pcimatch(p, 0, 0)){
  999. if(p->ccrb != 0x02 || p->ccru != 0)
  1000. continue;
  1001. switch((p->did<<16)|p->vid){
  1002. default:
  1003. continue;
  1004. case (0x0022<<16)|0x100B: /* DP83820 (Gig-NIC) */
  1005. break;
  1006. }
  1007. port = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
  1008. if(port == 0){
  1009. print("dp83820: can't map %d @ 0x%8.8luX\n",
  1010. p->mem[1].size, p->mem[1].bar);
  1011. continue;
  1012. }
  1013. ctlr = malloc(sizeof(Ctlr));
  1014. ctlr->port = port;
  1015. ctlr->pcidev = p;
  1016. ctlr->id = p->did<<16 | p->vid;
  1017. ctlr->nic = KADDR(ctlr->port);
  1018. if(dp83820reset(ctlr)){
  1019. free(ctlr);
  1020. continue;
  1021. }
  1022. pcisetbme(p);
  1023. if(dp83820ctlrhead != nil)
  1024. dp83820ctlrtail->next = ctlr;
  1025. else
  1026. dp83820ctlrhead = ctlr;
  1027. dp83820ctlrtail = ctlr;
  1028. }
  1029. }
  1030. int
  1031. dp83820pnp(Ether* edev)
  1032. {
  1033. int i;
  1034. Ctlr *ctlr;
  1035. uchar ea[Eaddrlen];
  1036. if(dp83820ctlrhead == nil)
  1037. dp83820pci();
  1038. /*
  1039. * Any adapter matches if no edev->port is supplied,
  1040. * otherwise the ports must match.
  1041. */
  1042. for(ctlr = dp83820ctlrhead; ctlr != nil; ctlr = ctlr->next){
  1043. if(ctlr->active)
  1044. continue;
  1045. if(edev->port == 0 || edev->port == ctlr->port){
  1046. ctlr->active = 1;
  1047. break;
  1048. }
  1049. }
  1050. if(ctlr == nil)
  1051. return -1;
  1052. edev->ctlr = ctlr;
  1053. edev->port = ctlr->port;
  1054. edev->irq = ctlr->pcidev->intl;
  1055. edev->tbdf = ctlr->pcidev->tbdf;
  1056. /*
  1057. * Check if the adapter's station address is to be overridden.
  1058. * If not, read it from the EEPROM and set in ether->ea prior to
  1059. * loading the station address in the hardware.
  1060. */
  1061. memset(ea, 0, Eaddrlen);
  1062. if(memcmp(ea, edev->ea, Eaddrlen) == 0)
  1063. for(i = 0; i < Eaddrlen/2; i++){
  1064. edev->ea[2*i] = ctlr->eeprom[0x0C-i];
  1065. edev->ea[2*i+1] = ctlr->eeprom[0x0C-i]>>8;
  1066. }
  1067. edev->attach = dp83820attach;
  1068. edev->transmit = dp83820transmit;
  1069. edev->interrupt = dp83820interrupt;
  1070. edev->detach = dp83820shutdown;
  1071. return 0;
  1072. }