etherdp83820.c 29 KB

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