etherdp83820.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247
  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. _xinc(&bp->ref); /* prevent bp from being freed */
  458. iunlock(&dp83820rblock);
  459. desc->bufptr = PCIWADDR(bp->rp);
  460. desc->bp = bp;
  461. }
  462. else{
  463. bp = desc->bp;
  464. bp->rp = bp->lim - Rbsz;
  465. bp->wp = bp->rp;
  466. }
  467. coherence();
  468. desc->cmdsts = Intr|Rbsz;
  469. return bp;
  470. }
  471. static void
  472. dp83820rbfree(Block *bp)
  473. {
  474. bp->rp = bp->lim - Rbsz;
  475. bp->wp = bp->rp;
  476. ilock(&dp83820rblock);
  477. bp->next = dp83820rbpool;
  478. dp83820rbpool = bp;
  479. iunlock(&dp83820rblock);
  480. }
  481. static void
  482. dp83820halt(Ctlr* ctlr)
  483. {
  484. int i, timeo;
  485. ilock(&ctlr->ilock);
  486. csr32w(ctlr, Imr, 0);
  487. csr32w(ctlr, Ier, 0);
  488. csr32w(ctlr, Cr, Rxd|Txd);
  489. for(timeo = 0; timeo < 1000; timeo++){
  490. if(!(csr32r(ctlr, Cr) & (Rxe|Txe)))
  491. break;
  492. microdelay(1);
  493. }
  494. csr32w(ctlr, Mibc, Frz);
  495. iunlock(&ctlr->ilock);
  496. if(ctlr->rd != nil){
  497. for(i = 0; i < ctlr->nrd; i++){
  498. if(ctlr->rd[i].bp == nil)
  499. continue;
  500. freeb(ctlr->rd[i].bp);
  501. ctlr->rd[i].bp = nil;
  502. }
  503. }
  504. if(ctlr->td != nil){
  505. for(i = 0; i < ctlr->ntd; i++){
  506. if(ctlr->td[i].bp == nil)
  507. continue;
  508. freeb(ctlr->td[i].bp);
  509. ctlr->td[i].bp = nil;
  510. }
  511. }
  512. }
  513. static void
  514. dp83820cfg(Ctlr* ctlr)
  515. {
  516. int cfg;
  517. /*
  518. * Don't know how to deal with a TBI yet.
  519. */
  520. if(ctlr->mii == nil)
  521. return;
  522. /*
  523. * The polarity of these bits is at the mercy
  524. * of the board designer.
  525. * The correct answer for all speed and duplex questions
  526. * should be to query the phy.
  527. */
  528. cfg = csr32r(ctlr, Cfg);
  529. if(!(cfg & Dupsts)){
  530. ctlr->rxcfg |= Rxfd;
  531. ctlr->txcfg |= Csi|Hbi;
  532. iprint("83820: full duplex, ");
  533. }
  534. else{
  535. ctlr->rxcfg &= ~Rxfd;
  536. ctlr->txcfg &= ~(Csi|Hbi);
  537. iprint("83820: half duplex, ");
  538. }
  539. csr32w(ctlr, Rxcfg, ctlr->rxcfg);
  540. csr32w(ctlr, Txcfg, ctlr->txcfg);
  541. switch(cfg & (Spdsts1000|Spdsts100)){
  542. case Spdsts1000: /* 100Mbps */
  543. default: /* 10Mbps */
  544. ctlr->cfg &= ~Mode1000;
  545. if((cfg & (Spdsts1000|Spdsts100)) == Spdsts1000)
  546. iprint("100Mb/s\n");
  547. else
  548. iprint("10Mb/s\n");
  549. break;
  550. case Spdsts100: /* 1Gbps */
  551. ctlr->cfg |= Mode1000;
  552. iprint("1Gb/s\n");
  553. break;
  554. }
  555. csr32w(ctlr, Cfg, ctlr->cfg);
  556. }
  557. static void
  558. dp83820init(Ether* edev)
  559. {
  560. int i;
  561. Ctlr *ctlr;
  562. Desc *desc;
  563. uchar *alloc;
  564. ctlr = edev->ctlr;
  565. dp83820halt(ctlr);
  566. /*
  567. * Receiver
  568. */
  569. alloc = (uchar*)ROUNDUP((ulong)ctlr->alloc, 8);
  570. ctlr->rd = (Desc*)alloc;
  571. alloc += ctlr->nrd*sizeof(Desc);
  572. memset(ctlr->rd, 0, ctlr->nrd*sizeof(Desc));
  573. ctlr->rdx = 0;
  574. for(i = 0; i < ctlr->nrd; i++){
  575. desc = &ctlr->rd[i];
  576. desc->link = PCIWADDR(&ctlr->rd[NEXT(i, ctlr->nrd)]);
  577. if(dp83820rballoc(desc) == nil)
  578. continue;
  579. }
  580. csr32w(ctlr, Rxdphi, 0);
  581. csr32w(ctlr, Rxdp, PCIWADDR(ctlr->rd));
  582. for(i = 0; i < Eaddrlen; i += 2){
  583. csr32w(ctlr, Rfcr, i);
  584. csr32w(ctlr, Rfdr, (edev->ea[i+1]<<8)|edev->ea[i]);
  585. }
  586. csr32w(ctlr, Rfcr, Rfen|Aab|Aam|Apm);
  587. ctlr->rxcfg = Stripcrc|(((2*(ETHERMINTU+4))/8)<<RxdrthSHFT);
  588. ctlr->imr |= Rxorn|Rxidle|Rxearly|Rxdesc|Rxok;
  589. /*
  590. * Transmitter.
  591. */
  592. ctlr->td = (Desc*)alloc;
  593. memset(ctlr->td, 0, ctlr->ntd*sizeof(Desc));
  594. ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
  595. for(i = 0; i < ctlr->ntd; i++){
  596. desc = &ctlr->td[i];
  597. desc->link = PCIWADDR(&ctlr->td[NEXT(i, ctlr->ntd)]);
  598. }
  599. csr32w(ctlr, Txdphi, 0);
  600. csr32w(ctlr, Txdp, PCIWADDR(ctlr->td));
  601. ctlr->txcfg = Atp|(((2*(ETHERMINTU+4))/32)<<FlthSHFT)|((4096/32)<<TxdrthSHFT);
  602. ctlr->imr |= Txurn|Txidle|Txdesc|Txok;
  603. ilock(&ctlr->ilock);
  604. dp83820cfg(ctlr);
  605. csr32w(ctlr, Mibc, Aclr);
  606. ctlr->imr |= Mib;
  607. csr32w(ctlr, Imr, ctlr->imr);
  608. /* try coalescing adjacent interrupts; use hold-off interval of 100µs */
  609. csr32w(ctlr, Ihr, Ihctl|(1<<IhSHFT));
  610. csr32w(ctlr, Ier, Ien);
  611. csr32w(ctlr, Cr, Rxe|Txe);
  612. iunlock(&ctlr->ilock);
  613. }
  614. static void
  615. dp83820attach(Ether* edev)
  616. {
  617. Block *bp;
  618. Ctlr *ctlr;
  619. ctlr = edev->ctlr;
  620. qlock(&ctlr->alock);
  621. if(ctlr->alloc != nil){
  622. qunlock(&ctlr->alock);
  623. return;
  624. }
  625. if(waserror()){
  626. if(ctlr->mii != nil){
  627. free(ctlr->mii);
  628. ctlr->mii = nil;
  629. }
  630. if(ctlr->alloc != nil){
  631. free(ctlr->alloc);
  632. ctlr->alloc = nil;
  633. }
  634. qunlock(&ctlr->alock);
  635. nexterror();
  636. }
  637. if(!(ctlr->cfg & Tbien)){
  638. if((ctlr->mii = malloc(sizeof(Mii))) == nil)
  639. error(Enomem);
  640. ctlr->mii->ctlr = ctlr;
  641. ctlr->mii->mir = dp83820miimir;
  642. ctlr->mii->miw = dp83820miimiw;
  643. if(mii(ctlr->mii, ~0) == 0)
  644. error("no PHY");
  645. ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien;
  646. ctlr->imr |= Phy;
  647. }
  648. ctlr->nrd = Nrd;
  649. ctlr->nrb = Nrb;
  650. ctlr->ntd = Ntd;
  651. ctlr->alloc = mallocz((ctlr->nrd+ctlr->ntd)*sizeof(Desc) + 7, 0);
  652. if(ctlr->alloc == nil)
  653. error(Enomem);
  654. for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
  655. if((bp = allocb(Rbsz)) == nil)
  656. break;
  657. bp->free = dp83820rbfree;
  658. dp83820rbfree(bp);
  659. }
  660. dp83820init(edev);
  661. qunlock(&ctlr->alock);
  662. poperror();
  663. }
  664. static void
  665. dp83820transmit(Ether* edev)
  666. {
  667. Block *bp;
  668. Ctlr *ctlr;
  669. Desc *desc;
  670. int cmdsts, r, x;
  671. ctlr = edev->ctlr;
  672. ilock(&ctlr->tlock);
  673. bp = nil;
  674. for(x = ctlr->tdh; ctlr->ntq; x = NEXT(x, ctlr->ntd)){
  675. desc = &ctlr->td[x];
  676. if((cmdsts = desc->cmdsts) & Own)
  677. break;
  678. if(!(cmdsts & Ok)){
  679. if(cmdsts & Ec)
  680. ctlr->ec++;
  681. if(cmdsts & Owc)
  682. ctlr->owc++;
  683. if(cmdsts & Ed)
  684. ctlr->ed++;
  685. if(cmdsts & Crs)
  686. ctlr->crs++;
  687. if(cmdsts & Tfu)
  688. ctlr->tfu++;
  689. if(cmdsts & Txa)
  690. ctlr->txa++;
  691. edev->oerrs++;
  692. }
  693. desc->bp->next = bp;
  694. bp = desc->bp;
  695. desc->bp = nil;
  696. ctlr->ntq--;
  697. }
  698. ctlr->tdh = x;
  699. if(bp != nil)
  700. freeblist(bp);
  701. x = ctlr->tdt;
  702. while(ctlr->ntq < (ctlr->ntd-1)){
  703. if((bp = qget(edev->oq)) == nil)
  704. break;
  705. desc = &ctlr->td[x];
  706. desc->bufptr = PCIWADDR(bp->rp);
  707. desc->bp = bp;
  708. ctlr->ntq++;
  709. coherence();
  710. desc->cmdsts = Own|Intr|BLEN(bp);
  711. x = NEXT(x, ctlr->ntd);
  712. }
  713. if(x != ctlr->tdt){
  714. ctlr->tdt = x;
  715. r = csr32r(ctlr, Cr);
  716. csr32w(ctlr, Cr, Txe|r);
  717. }
  718. iunlock(&ctlr->tlock);
  719. }
  720. static void
  721. dp83820interrupt(Ureg*, void* arg)
  722. {
  723. Block *bp;
  724. Ctlr *ctlr;
  725. Desc *desc;
  726. Ether *edev;
  727. int cmdsts, i, isr, r, x;
  728. edev = arg;
  729. ctlr = edev->ctlr;
  730. for(isr = csr32r(ctlr, Isr); isr & ctlr->imr; isr = csr32r(ctlr, Isr)){
  731. if(isr & (Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok)){
  732. x = ctlr->rdx;
  733. desc = &ctlr->rd[x];
  734. while((cmdsts = desc->cmdsts) & Own){
  735. if((cmdsts & Ok) && desc->bp != nil){
  736. bp = desc->bp;
  737. desc->bp = nil;
  738. bp->wp += cmdsts & SizeMASK;
  739. etheriq(edev, bp, 1);
  740. }
  741. else if(0 && !(cmdsts & Ok)){
  742. iprint("dp83820: rx %8.8uX:", cmdsts);
  743. bp = desc->bp;
  744. for(i = 0; i < 20; i++)
  745. iprint(" %2.2uX", bp->rp[i]);
  746. iprint("\n");
  747. }
  748. dp83820rballoc(desc);
  749. x = NEXT(x, ctlr->nrd);
  750. desc = &ctlr->rd[x];
  751. }
  752. ctlr->rdx = x;
  753. if(isr & Rxidle){
  754. r = csr32r(ctlr, Cr);
  755. csr32w(ctlr, Cr, Rxe|r);
  756. ctlr->rxidle++;
  757. }
  758. isr &= ~(Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok);
  759. }
  760. if(isr & Txurn){
  761. x = (ctlr->txcfg & TxdrthMASK)>>TxdrthSHFT;
  762. r = (ctlr->txcfg & FlthMASK)>>FlthSHFT;
  763. if(x < ((TxdrthMASK)>>TxdrthSHFT)
  764. && x < (2048/32 - r)){
  765. ctlr->txcfg &= ~TxdrthMASK;
  766. x++;
  767. ctlr->txcfg |= x<<TxdrthSHFT;
  768. csr32w(ctlr, Txcfg, ctlr->txcfg);
  769. }
  770. }
  771. if(isr & (Txurn|Txidle|Txdesc|Txok)){
  772. dp83820transmit(edev);
  773. isr &= ~(Txurn|Txidle|Txdesc|Txok);
  774. }
  775. if(isr & Mib){
  776. for(i = 0; i < Nmibd; i++){
  777. r = csr32r(ctlr, Mibd+(i*sizeof(int)));
  778. ctlr->mibd[i] += r & 0xFFFF;
  779. }
  780. isr &= ~Mib;
  781. }
  782. if((isr & Phy) && ctlr->mii != nil){
  783. ctlr->mii->mir(ctlr->mii, 1, Bmsr);
  784. print("phy: cfg %8.8uX bmsr %4.4uX\n",
  785. csr32r(ctlr, Cfg),
  786. ctlr->mii->mir(ctlr->mii, 1, Bmsr));
  787. dp83820cfg(ctlr);
  788. isr &= ~Phy;
  789. }
  790. if(isr)
  791. iprint("dp83820: isr %8.8uX\n", isr);
  792. }
  793. }
  794. static long
  795. dp83820ifstat(Ether* edev, void* a, long n, ulong offset)
  796. {
  797. char *p;
  798. Ctlr *ctlr;
  799. int i, l, r;
  800. ctlr = edev->ctlr;
  801. edev->crcs = ctlr->mibd[Mibd+(1*sizeof(int))];
  802. edev->frames = ctlr->mibd[Mibd+(3*sizeof(int))];
  803. edev->buffs = ctlr->mibd[Mibd+(5*sizeof(int))];
  804. edev->overflows = ctlr->mibd[Mibd+(2*sizeof(int))];
  805. if(n == 0)
  806. return 0;
  807. p = malloc(READSTR);
  808. l = 0;
  809. for(i = 0; i < Nmibd; i++){
  810. r = csr32r(ctlr, Mibd+(i*sizeof(int)));
  811. ctlr->mibd[i] += r & 0xFFFF;
  812. if(ctlr->mibd[i] != 0 && dp83820mibs[i] != nil)
  813. l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
  814. dp83820mibs[i], ctlr->mibd[i], r);
  815. }
  816. l += snprint(p+l, READSTR-l, "rxidle %d\n", ctlr->rxidle);
  817. l += snprint(p+l, READSTR-l, "ec %d\n", ctlr->ec);
  818. l += snprint(p+l, READSTR-l, "owc %d\n", ctlr->owc);
  819. l += snprint(p+l, READSTR-l, "ed %d\n", ctlr->ed);
  820. l += snprint(p+l, READSTR-l, "crs %d\n", ctlr->crs);
  821. l += snprint(p+l, READSTR-l, "tfu %d\n", ctlr->tfu);
  822. l += snprint(p+l, READSTR-l, "txa %d\n", ctlr->txa);
  823. l += snprint(p+l, READSTR, "rom:");
  824. for(i = 0; i < 0x10; i++){
  825. if(i && ((i & 0x07) == 0))
  826. l += snprint(p+l, READSTR-l, "\n ");
  827. l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
  828. }
  829. l += snprint(p+l, READSTR-l, "\n");
  830. if(ctlr->mii != nil && ctlr->mii->curphy != nil){
  831. l += snprint(p+l, READSTR, "phy:");
  832. for(i = 0; i < NMiiPhyr; i++){
  833. if(i && ((i & 0x07) == 0))
  834. l += snprint(p+l, READSTR-l, "\n ");
  835. r = miimir(ctlr->mii, i);
  836. l += snprint(p+l, READSTR-l, " %4.4uX", r);
  837. }
  838. snprint(p+l, READSTR-l, "\n");
  839. }
  840. n = readstr(offset, a, n, p);
  841. free(p);
  842. return n;
  843. }
  844. static void
  845. dp83820promiscuous(void* arg, int on)
  846. {
  847. USED(arg, on);
  848. }
  849. /* multicast already on, don't need to do anything */
  850. static void
  851. dp83820multicast(void*, uchar*, int)
  852. {
  853. }
  854. static int
  855. dp83820detach(Ctlr* ctlr)
  856. {
  857. /*
  858. * Soft reset the controller.
  859. */
  860. csr32w(ctlr, Cr, Rst);
  861. delay(1);
  862. while(csr32r(ctlr, Cr) & Rst)
  863. delay(1);
  864. return 0;
  865. }
  866. static void
  867. dp83820shutdown(Ether* ether)
  868. {
  869. print("dp83820shutdown\n");
  870. dp83820detach(ether->ctlr);
  871. }
  872. static int
  873. atc93c46r(Ctlr* ctlr, int address)
  874. {
  875. int data, i, mear, r, size;
  876. /*
  877. * Analog Technology, Inc. ATC93C46
  878. * or equivalent serial EEPROM.
  879. */
  880. mear = csr32r(ctlr, Mear);
  881. mear &= ~(Eesel|Eeclk|Eedo|Eedi);
  882. r = Eesel|mear;
  883. reread:
  884. csr32w(ctlr, Mear, r);
  885. data = 0x06;
  886. for(i = 3-1; i >= 0; i--){
  887. if(data & (1<<i))
  888. r |= Eedi;
  889. else
  890. r &= ~Eedi;
  891. csr32w(ctlr, Mear, r);
  892. csr32w(ctlr, Mear, Eeclk|r);
  893. microdelay(1);
  894. csr32w(ctlr, Mear, r);
  895. microdelay(1);
  896. }
  897. /*
  898. * First time through must work out the EEPROM size.
  899. */
  900. if((size = ctlr->eepromsz) == 0)
  901. size = 8;
  902. for(size = size-1; size >= 0; size--){
  903. if(address & (1<<size))
  904. r |= Eedi;
  905. else
  906. r &= ~Eedi;
  907. csr32w(ctlr, Mear, r);
  908. microdelay(1);
  909. csr32w(ctlr, Mear, Eeclk|r);
  910. microdelay(1);
  911. csr32w(ctlr, Mear, r);
  912. microdelay(1);
  913. if(!(csr32r(ctlr, Mear) & Eedo))
  914. break;
  915. }
  916. r &= ~Eedi;
  917. data = 0;
  918. for(i = 16-1; i >= 0; i--){
  919. csr32w(ctlr, Mear, Eeclk|r);
  920. microdelay(1);
  921. if(csr32r(ctlr, Mear) & Eedo)
  922. data |= (1<<i);
  923. csr32w(ctlr, Mear, r);
  924. microdelay(1);
  925. }
  926. csr32w(ctlr, Mear, mear);
  927. if(ctlr->eepromsz == 0){
  928. ctlr->eepromsz = 8-size;
  929. ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
  930. goto reread;
  931. }
  932. return data;
  933. }
  934. static int
  935. dp83820reset(Ctlr* ctlr)
  936. {
  937. int i, r;
  938. unsigned char sum;
  939. /*
  940. * Soft reset the controller;
  941. * read the EEPROM to get the initial settings
  942. * of the Cfg and Gpior bits which should be cleared by
  943. * the reset.
  944. */
  945. dp83820detach(ctlr);
  946. atc93c46r(ctlr, 0);
  947. if(ctlr->eeprom == nil) {
  948. print("dp83820reset: no eeprom\n");
  949. return -1;
  950. }
  951. sum = 0;
  952. for(i = 0; i < 0x0E; i++){
  953. r = atc93c46r(ctlr, i);
  954. ctlr->eeprom[i] = r;
  955. sum += r;
  956. sum += r>>8;
  957. }
  958. if(sum != 0){
  959. print("dp83820reset: bad EEPROM checksum\n");
  960. return -1;
  961. }
  962. #ifdef notdef
  963. csr32w(ctlr, Gpior, ctlr->eeprom[4]);
  964. cfg = Extstsen|Exd;
  965. r = csr32r(ctlr, Cfg);
  966. if(ctlr->eeprom[5] & 0x0001)
  967. cfg |= Ext125;
  968. if(ctlr->eeprom[5] & 0x0002)
  969. cfg |= M64addren;
  970. if((ctlr->eeprom[5] & 0x0004) && (r & Pci64det))
  971. cfg |= Data64en;
  972. if(ctlr->eeprom[5] & 0x0008)
  973. cfg |= T64addren;
  974. if(!(pcicfgr16(ctlr->pcidev, PciPCR) & 0x10))
  975. cfg |= Mwidis;
  976. if(ctlr->eeprom[5] & 0x0020)
  977. cfg |= Mrmdis;
  978. if(ctlr->eeprom[5] & 0x0080)
  979. cfg |= Mode1000;
  980. if(ctlr->eeprom[5] & 0x0200)
  981. cfg |= Tbien|Mode1000;
  982. /*
  983. * What about RO bits we might have destroyed with Rst?
  984. * What about Exd, Tmrtest, Extstsen, Pintctl?
  985. * Why does it think it has detected a 64-bit bus when
  986. * it hasn't?
  987. */
  988. #else
  989. // r = csr32r(ctlr, Cfg);
  990. // r &= ~(Mode1000|T64addren|Data64en|M64addren);
  991. // csr32w(ctlr, Cfg, r);
  992. // csr32w(ctlr, Cfg, 0x2000);
  993. #endif /* notdef */
  994. ctlr->cfg = csr32r(ctlr, Cfg);
  995. print("cfg %8.8uX pcicfg %8.8uX\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR));
  996. ctlr->cfg &= ~(T64addren|Data64en|M64addren);
  997. csr32w(ctlr, Cfg, ctlr->cfg);
  998. csr32w(ctlr, Mibc, Aclr|Frz);
  999. return 0;
  1000. }
  1001. static void
  1002. dp83820pci(void)
  1003. {
  1004. void *mem;
  1005. Pcidev *p;
  1006. Ctlr *ctlr;
  1007. p = nil;
  1008. while(p = pcimatch(p, 0, 0)){
  1009. if(p->ccrb != Pcibcnet || p->ccru != Pciscether)
  1010. continue;
  1011. switch((p->did<<16)|p->vid){
  1012. default:
  1013. continue;
  1014. case (0x0022<<16)|0x100B: /* DP83820 (Gig-NIC) */
  1015. break;
  1016. }
  1017. mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
  1018. if(mem == 0){
  1019. print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
  1020. continue;
  1021. }
  1022. ctlr = malloc(sizeof(Ctlr));
  1023. ctlr->port = p->mem[1].bar & ~0x0F;
  1024. ctlr->pcidev = p;
  1025. ctlr->id = (p->did<<16)|p->vid;
  1026. ctlr->nic = mem;
  1027. if(dp83820reset(ctlr)){
  1028. free(ctlr);
  1029. continue;
  1030. }
  1031. pcisetbme(p);
  1032. if(dp83820ctlrhead != nil)
  1033. dp83820ctlrtail->next = ctlr;
  1034. else
  1035. dp83820ctlrhead = ctlr;
  1036. dp83820ctlrtail = ctlr;
  1037. }
  1038. }
  1039. static int
  1040. dp83820pnp(Ether* edev)
  1041. {
  1042. int i;
  1043. Ctlr *ctlr;
  1044. uchar ea[Eaddrlen];
  1045. if(dp83820ctlrhead == nil)
  1046. dp83820pci();
  1047. /*
  1048. * Any adapter matches if no edev->port is supplied,
  1049. * otherwise the ports must match.
  1050. */
  1051. for(ctlr = dp83820ctlrhead; ctlr != nil; ctlr = ctlr->next){
  1052. if(ctlr->active)
  1053. continue;
  1054. if(edev->port == 0 || edev->port == ctlr->port){
  1055. ctlr->active = 1;
  1056. break;
  1057. }
  1058. }
  1059. if(ctlr == nil)
  1060. return -1;
  1061. edev->ctlr = ctlr;
  1062. edev->port = ctlr->port;
  1063. edev->irq = ctlr->pcidev->intl;
  1064. edev->tbdf = ctlr->pcidev->tbdf;
  1065. edev->mbps = 1000;
  1066. /*
  1067. * Check if the adapter's station address is to be overridden.
  1068. * If not, read it from the EEPROM and set in ether->ea prior to
  1069. * loading the station address in the hardware.
  1070. */
  1071. memset(ea, 0, Eaddrlen);
  1072. if(memcmp(ea, edev->ea, Eaddrlen) == 0)
  1073. for(i = 0; i < Eaddrlen/2; i++){
  1074. edev->ea[2*i] = ctlr->eeprom[0x0C-i];
  1075. edev->ea[2*i+1] = ctlr->eeprom[0x0C-i]>>8;
  1076. }
  1077. edev->attach = dp83820attach;
  1078. edev->transmit = dp83820transmit;
  1079. edev->interrupt = dp83820interrupt;
  1080. edev->ifstat = dp83820ifstat;
  1081. edev->arg = edev;
  1082. edev->promiscuous = dp83820promiscuous;
  1083. edev->multicast = dp83820multicast;
  1084. edev->shutdown = dp83820shutdown;
  1085. return 0;
  1086. }
  1087. void
  1088. etherdp83820link(void)
  1089. {
  1090. addethercard("DP83820", dp83820pnp);
  1091. }