etherdp83820.c 30 KB

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