ether8169.c 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. /*
  2. * Realtek RTL8110S/8169S.
  3. * Mostly there. There are some magic register values used
  4. * which are not described in any datasheet or driver but seem
  5. * to be necessary.
  6. * No tuning has been done. Only tested on an RTL8110S, there
  7. * are slight differences between the chips in the series so some
  8. * tweaks may be needed.
  9. */
  10. #include "u.h"
  11. #include "../port/lib.h"
  12. #include "mem.h"
  13. #include "dat.h"
  14. #include "fns.h"
  15. #include "io.h"
  16. #include "../port/error.h"
  17. #include "../port/netif.h"
  18. #include "etherif.h"
  19. #include "ethermii.h"
  20. enum { /* registers */
  21. Idr0 = 0x00, /* MAC address */
  22. Mar0 = 0x08, /* Multicast address */
  23. Dtccr = 0x10, /* Dump Tally Counter Command */
  24. Tnpds = 0x20, /* Transmit Normal Priority Descriptors */
  25. Thpds = 0x28, /* Transmit High Priority Descriptors */
  26. Flash = 0x30, /* Flash Memory Read/Write */
  27. Erbcr = 0x34, /* Early Receive Byte Count */
  28. Ersr = 0x36, /* Early Receive Status */
  29. Cr = 0x37, /* Command Register */
  30. Tppoll = 0x38, /* Transmit Priority Polling */
  31. Imr = 0x3C, /* Interrupt Mask */
  32. Isr = 0x3E, /* Interrupt Status */
  33. Tcr = 0x40, /* Transmit Configuration */
  34. Rcr = 0x44, /* Receive Configuration */
  35. Tctr = 0x48, /* Timer Count */
  36. Mpc = 0x4C, /* Missed Packet Counter */
  37. Cr9346 = 0x50, /* 9346 Command Register */
  38. Config0 = 0x51, /* Configuration Register 0 */
  39. Config1 = 0x52, /* Configuration Register 1 */
  40. Config2 = 0x53, /* Configuration Register 2 */
  41. Config3 = 0x54, /* Configuration Register 3 */
  42. Config4 = 0x55, /* Configuration Register 4 */
  43. Config5 = 0x56, /* Configuration Register 5 */
  44. Timerint = 0x58, /* Timer Interrupt */
  45. Mulint = 0x5C, /* Multiple Interrupt Select */
  46. Phyar = 0x60, /* PHY Access */
  47. Tbicsr0 = 0x64, /* TBI Control and Status */
  48. Tbianar = 0x68, /* TBI Auto-Negotiation Advertisment */
  49. Tbilpar = 0x6A, /* TBI Auto-Negotiation Link Partner */
  50. Phystatus = 0x6C, /* PHY Status */
  51. Rms = 0xDA, /* Receive Packet Maximum Size */
  52. Cplusc = 0xE0, /* C+ Command */
  53. Rdsar = 0xE4, /* Receive Descriptor Start Address */
  54. Mtps = 0xEC, /* Max. Transmit Packet Size */
  55. };
  56. enum { /* Dtccr */
  57. Cmd = 0x00000008, /* Command */
  58. };
  59. enum { /* Cr */
  60. Te = 0x04, /* Transmitter Enable */
  61. Re = 0x08, /* Receiver Enable */
  62. Rst = 0x10, /* Software Reset */
  63. };
  64. enum { /* Tppoll */
  65. Fswint = 0x01, /* Forced Software Interrupt */
  66. Npq = 0x40, /* Normal Priority Queue polling */
  67. Hpq = 0x80, /* High Priority Queue polling */
  68. };
  69. enum { /* Imr/Isr */
  70. Rok = 0x0001, /* Receive OK */
  71. Rer = 0x0002, /* Receive Error */
  72. Tok = 0x0004, /* Transmit OK */
  73. Ter = 0x0008, /* Transmit Error */
  74. Rdu = 0x0010, /* Receive Descriptor Unavailable */
  75. Punlc = 0x0020, /* Packet Underrun or Link Change */
  76. Fovw = 0x0040, /* Receive FIFO Overflow */
  77. Tdu = 0x0080, /* Transmit Descriptor Unavailable */
  78. Swint = 0x0100, /* Software Interrupt */
  79. Timeout = 0x4000, /* Timer */
  80. Serr = 0x8000, /* System Error */
  81. };
  82. enum { /* Tcr */
  83. MtxdmaSHIFT = 8, /* Max. DMA Burst Size */
  84. MtxdmaMASK = 0x00000700,
  85. Mtxdmaunlimited = 0x00000700,
  86. Acrc = 0x00010000, /* Append CRC (not) */
  87. Lbk0 = 0x00020000, /* Loopback Test 0 */
  88. Lbk1 = 0x00040000, /* Loopback Test 1 */
  89. Ifg2 = 0x00080000, /* Interframe Gap 2 */
  90. HwveridSHIFT = 23, /* Hardware Version ID */
  91. HwveridMASK = 0x7C800000,
  92. Ifg0 = 0x01000000, /* Interframe Gap 0 */
  93. Ifg1 = 0x02000000, /* Interframe Gap 1 */
  94. };
  95. enum { /* Rcr */
  96. Aap = 0x00000001, /* Accept All Packets */
  97. Apm = 0x00000002, /* Accept Physical Match */
  98. Am = 0x00000004, /* Accept Multicast */
  99. Ab = 0x00000008, /* Accept Broadcast */
  100. Ar = 0x00000010, /* Accept Runt */
  101. Aer = 0x00000020, /* Accept Error */
  102. Sel9356 = 0x00000040, /* 9356 EEPROM used */
  103. MrxdmaSHIFT = 8, /* Max. DMA Burst Size */
  104. MrxdmaMASK = 0x00000700,
  105. Mrxdmaunlimited = 0x00000700,
  106. RxfthSHIFT = 13, /* Receive Buffer Length */
  107. RxfthMASK = 0x0000E000,
  108. Rxfth256 = 0x00008000,
  109. Rxfthnone = 0x0000E000,
  110. Rer8 = 0x00010000, /* Accept Error Packets > 8 bytes */
  111. MulERINT = 0x01000000, /* Multiple Early Interrupt Select */
  112. };
  113. enum { /* Cr9346 */
  114. Eedo = 0x01, /* */
  115. Eedi = 0x02, /* */
  116. Eesk = 0x04, /* */
  117. Eecs = 0x08, /* */
  118. Eem0 = 0x40, /* Operating Mode */
  119. Eem1 = 0x80,
  120. };
  121. enum { /* Phyar */
  122. DataMASK = 0x0000FFFF, /* 16-bit GMII/MII Register Data */
  123. DataSHIFT = 0,
  124. RegaddrMASK = 0x001F0000, /* 5-bit GMII/MII Register Address */
  125. RegaddrSHIFT = 16,
  126. Flag = 0x80000000, /* */
  127. };
  128. enum { /* Phystatus */
  129. Fd = 0x01, /* Full Duplex */
  130. Linksts = 0x02, /* Link Status */
  131. Speed10 = 0x04, /* */
  132. Speed100 = 0x08, /* */
  133. Speed1000 = 0x10, /* */
  134. Rxflow = 0x20, /* */
  135. Txflow = 0x40, /* */
  136. Entbi = 0x80, /* */
  137. };
  138. enum { /* Cplusc */
  139. Mulrw = 0x0008, /* PCI Multiple R/W Enable */
  140. Dac = 0x0010, /* PCI Dual Address Cycle Enable */
  141. Rxchksum = 0x0020, /* Receive Checksum Offload Enable */
  142. Rxvlan = 0x0040, /* Receive VLAN De-tagging Enable */
  143. Endian = 0x0200, /* Endian Mode */
  144. };
  145. typedef struct D D; /* Transmit/Receive Descriptor */
  146. struct D {
  147. u32int control;
  148. u32int vlan;
  149. u32int addrlo;
  150. u32int addrhi;
  151. };
  152. enum { /* Transmit Descriptor control */
  153. TxflMASK = 0x0000FFFF, /* Transmit Frame Length */
  154. TxflSHIFT = 0,
  155. Tcps = 0x00010000, /* TCP Checksum Offload */
  156. Udpcs = 0x00020000, /* UDP Checksum Offload */
  157. Ipcs = 0x00040000, /* IP Checksum Offload */
  158. Lgsen = 0x08000000, /* Large Send */
  159. };
  160. enum { /* Receive Descriptor control */
  161. RxflMASK = 0x00003FFF, /* Receive Frame Length */
  162. RxflSHIFT = 0,
  163. Tcpf = 0x00004000, /* TCP Checksum Failure */
  164. Udpf = 0x00008000, /* UDP Checksum Failure */
  165. Ipf = 0x00010000, /* IP Checksum Failure */
  166. Pid0 = 0x00020000, /* Protocol ID0 */
  167. Pid1 = 0x00040000, /* Protocol ID1 */
  168. Crce = 0x00080000, /* CRC Error */
  169. Runt = 0x00100000, /* Runt Packet */
  170. Res = 0x00200000, /* Receive Error Summary */
  171. Rwt = 0x00400000, /* Receive Watchdog Timer Expired */
  172. Fovf = 0x00800000, /* FIFO Overflow */
  173. Bovf = 0x01000000, /* Buffer Overflow */
  174. Bar = 0x02000000, /* Broadcast Address Received */
  175. Pam = 0x04000000, /* Physical Address Matched */
  176. Mar = 0x08000000, /* Multicast Address Received */
  177. };
  178. enum { /* General Descriptor control */
  179. Ls = 0x10000000, /* Last Segment Descriptor */
  180. Fs = 0x20000000, /* First Segment Descriptor */
  181. Eor = 0x40000000, /* End of Descriptor Ring */
  182. Own = 0x80000000, /* Ownership */
  183. };
  184. /*
  185. */
  186. enum { /* Ring sizes (<= 1024) */
  187. Ntd = 128, /* Transmit Ring */
  188. Nrd = 64, /* Receive Ring */
  189. Mps = ROUNDUP(ETHERMAXTU+4, 128),
  190. };
  191. typedef struct Dtcc Dtcc;
  192. struct Dtcc {
  193. u64int txok;
  194. u64int rxok;
  195. u64int txer;
  196. u32int rxer;
  197. u16int misspkt;
  198. u16int fae;
  199. u32int tx1col;
  200. u32int txmcol;
  201. u64int rxokph;
  202. u64int rxokbrd;
  203. u32int rxokmu;
  204. u16int txabt;
  205. u16int txundrn;
  206. };
  207. typedef struct Ctlr Ctlr;
  208. typedef struct Ctlr {
  209. int port;
  210. Pcidev* pcidev;
  211. Ctlr* next;
  212. int active;
  213. uint id;
  214. QLock alock; /* attach */
  215. Lock ilock; /* init */
  216. int init; /* */
  217. Mii* mii;
  218. Lock tlock; /* transmit */
  219. D* td; /* descriptor ring */
  220. Block** tb; /* transmit buffers */
  221. int ntd;
  222. int tdh; /* head - producer index (host) */
  223. int tdt; /* tail - consumer index (NIC) */
  224. int ntdfree;
  225. int ntq;
  226. int mtps; /* Max. Transmit Packet Size */
  227. Lock rlock; /* receive */
  228. D* rd; /* descriptor ring */
  229. Block** rb; /* receive buffers */
  230. int nrd;
  231. int rdh; /* head - producer index (NIC) */
  232. int rdt; /* tail - consumer index (host) */
  233. int nrdfree;
  234. int tcr; /* transmit configuration register */
  235. int rcr; /* receive configuration register */
  236. QLock slock; /* statistics */
  237. Dtcc* dtcc;
  238. uint txdu;
  239. uint tcpf;
  240. uint udpf;
  241. uint ipf;
  242. uint fovf;
  243. uint ierrs;
  244. uint rer;
  245. uint rdu;
  246. uint punlc;
  247. uint fovw;
  248. } Ctlr;
  249. static Ctlr* ctlrhead;
  250. static Ctlr* ctlrtail;
  251. #define csr8r(c, r) (inb((c)->port+(r)))
  252. #define csr16r(c, r) (ins((c)->port+(r)))
  253. #define csr32r(c, r) (inl((c)->port+(r)))
  254. #define csr8w(c, r, b) (outb((c)->port+(r), (int)(b)))
  255. #define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
  256. #define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
  257. static int
  258. rtl8169miimir(Mii* mii, int pa, int ra)
  259. {
  260. uint r;
  261. int timeo;
  262. Ctlr *ctlr;
  263. if(pa != 1)
  264. return -1;
  265. ctlr = mii->ctlr;
  266. r = (ra<<16) & RegaddrMASK;
  267. csr32w(ctlr, Phyar, r);
  268. delay(1);
  269. for(timeo = 0; timeo < 2000; timeo++){
  270. if((r = csr32r(ctlr, Phyar)) & Flag)
  271. break;
  272. microdelay(100);
  273. }
  274. if(!(r & Flag))
  275. return -1;
  276. return (r & DataMASK)>>DataSHIFT;
  277. }
  278. static int
  279. rtl8169miimiw(Mii* mii, int pa, int ra, int data)
  280. {
  281. uint r;
  282. int timeo;
  283. Ctlr *ctlr;
  284. if(pa != 1)
  285. return -1;
  286. ctlr = mii->ctlr;
  287. r = Flag|((ra<<16) & RegaddrMASK)|((data<<DataSHIFT) & DataMASK);
  288. csr32w(ctlr, Phyar, r);
  289. delay(1);
  290. for(timeo = 0; timeo < 2000; timeo++){
  291. if(!((r = csr32r(ctlr, Phyar)) & Flag))
  292. break;
  293. microdelay(100);
  294. }
  295. if(r & Flag)
  296. return -1;
  297. return 0;
  298. }
  299. static int
  300. rtl8169mii(Ctlr* ctlr)
  301. {
  302. MiiPhy *phy;
  303. /*
  304. * Link management.
  305. */
  306. if((ctlr->mii = malloc(sizeof(Mii))) == nil)
  307. return -1;
  308. ctlr->mii->mir = rtl8169miimir;
  309. ctlr->mii->miw = rtl8169miimiw;
  310. ctlr->mii->ctlr = ctlr;
  311. rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000); /* magic */
  312. if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
  313. free(ctlr->mii);
  314. ctlr->mii = nil;
  315. return -1;
  316. }
  317. print("oui %X phyno %d\n", phy->oui, phy->phyno);
  318. miiane(ctlr->mii, ~0, ~0, ~0);
  319. return 0;
  320. }
  321. static void
  322. rtl8169promiscuous(void* arg, int on)
  323. {
  324. Ether *edev;
  325. Ctlr * ctlr;
  326. edev = arg;
  327. ctlr = edev->ctlr;
  328. ilock(&ctlr->ilock);
  329. if(on)
  330. ctlr->rcr |= Aap;
  331. else
  332. ctlr->rcr &= ~Aap;
  333. csr32w(ctlr, Rcr, ctlr->rcr);
  334. iunlock(&ctlr->ilock);
  335. }
  336. static long
  337. rtl8169ifstat(Ether* edev, void* a, long n, ulong offset)
  338. {
  339. char *p;
  340. Ctlr *ctlr;
  341. Dtcc *dtcc;
  342. int i, l, r, timeo;
  343. ctlr = edev->ctlr;
  344. qlock(&ctlr->slock);
  345. p = nil;
  346. if(waserror()){
  347. qunlock(&ctlr->slock);
  348. free(p);
  349. nexterror();
  350. }
  351. csr32w(ctlr, Dtccr+4, 0);
  352. csr32w(ctlr, Dtccr, PCIWADDR(ctlr->dtcc)|Cmd);
  353. for(timeo = 0; timeo < 1000; timeo++){
  354. if(!(csr32r(ctlr, Dtccr) & Cmd))
  355. break;
  356. delay(1);
  357. }
  358. if(csr32r(ctlr, Dtccr) & Cmd)
  359. error(Eio);
  360. dtcc = ctlr->dtcc;
  361. edev->oerrs = dtcc->txer;
  362. edev->crcs = dtcc->rxer;
  363. edev->frames = dtcc->fae;
  364. edev->buffs = dtcc->misspkt;
  365. edev->overflows = ctlr->txdu+ctlr->rdu;
  366. if(n == 0){
  367. qunlock(&ctlr->slock);
  368. poperror();
  369. return 0;
  370. }
  371. if((p = malloc(READSTR)) == nil)
  372. error(Enomem);
  373. l = snprint(p, READSTR, "TxOk: %llud\n", dtcc->txok);
  374. l += snprint(p+l, READSTR-l, "RxOk: %llud\n", dtcc->rxok);
  375. l += snprint(p+l, READSTR-l, "TxEr: %llud\n", dtcc->txer);
  376. l += snprint(p+l, READSTR-l, "RxEr: %ud\n", dtcc->rxer);
  377. l += snprint(p+l, READSTR-l, "MissPkt: %ud\n", dtcc->misspkt);
  378. l += snprint(p+l, READSTR-l, "FAE: %ud\n", dtcc->fae);
  379. l += snprint(p+l, READSTR-l, "Tx1Col: %ud\n", dtcc->tx1col);
  380. l += snprint(p+l, READSTR-l, "TxMCol: %ud\n", dtcc->txmcol);
  381. l += snprint(p+l, READSTR-l, "RxOkPh: %llud\n", dtcc->rxokph);
  382. l += snprint(p+l, READSTR-l, "RxOkBrd: %llud\n", dtcc->rxokbrd);
  383. l += snprint(p+l, READSTR-l, "RxOkMu: %ud\n", dtcc->rxokmu);
  384. l += snprint(p+l, READSTR-l, "TxAbt: %ud\n", dtcc->txabt);
  385. l += snprint(p+l, READSTR-l, "TxUndrn: %ud\n", dtcc->txundrn);
  386. l += snprint(p+l, READSTR-l, "txdu: %ud\n", ctlr->txdu);
  387. l += snprint(p+l, READSTR-l, "tcpf: %ud\n", ctlr->tcpf);
  388. l += snprint(p+l, READSTR-l, "udpf: %ud\n", ctlr->udpf);
  389. l += snprint(p+l, READSTR-l, "ipf: %ud\n", ctlr->ipf);
  390. l += snprint(p+l, READSTR-l, "fovf: %ud\n", ctlr->fovf);
  391. l += snprint(p+l, READSTR-l, "ierrs: %ud\n", ctlr->ierrs);
  392. l += snprint(p+l, READSTR-l, "rer: %ud\n", ctlr->rer);
  393. l += snprint(p+l, READSTR-l, "rdu: %ud\n", ctlr->rdu);
  394. l += snprint(p+l, READSTR-l, "punlc: %ud\n", ctlr->punlc);
  395. l += snprint(p+l, READSTR-l, "fovw: %ud\n", ctlr->fovw);
  396. l += snprint(p+l, READSTR-l, "tcr: %8.8uX\n", ctlr->tcr);
  397. l += snprint(p+l, READSTR-l, "rcr: %8.8uX\n", ctlr->rcr);
  398. if(ctlr->mii != nil && ctlr->mii->curphy != nil){
  399. l += snprint(p+l, READSTR, "phy: ");
  400. for(i = 0; i < NMiiPhyr; i++){
  401. if(i && ((i & 0x07) == 0))
  402. l += snprint(p+l, READSTR-l, "\n ");
  403. r = miimir(ctlr->mii, i);
  404. l += snprint(p+l, READSTR-l, " %4.4uX", r);
  405. }
  406. snprint(p+l, READSTR-l, "\n");
  407. }
  408. n = readstr(offset, a, n, p);
  409. qunlock(&ctlr->slock);
  410. poperror();
  411. free(p);
  412. return n;
  413. }
  414. static int
  415. rtl8169reset(Ctlr* ctlr)
  416. {
  417. int timeo;
  418. /*
  419. * Soft reset the controller.
  420. */
  421. csr8w(ctlr, Cr, Rst);
  422. for(timeo = 0; timeo < 1000; timeo++){
  423. if(!(csr8r(ctlr, Cr) & Rst))
  424. return 0;
  425. delay(1);
  426. }
  427. return -1;
  428. }
  429. static void
  430. rtl8169halt(Ctlr* ctlr)
  431. {
  432. csr8w(ctlr, Cr, 0);
  433. csr16w(ctlr, Imr, 0);
  434. csr16w(ctlr, Isr, ~0);
  435. }
  436. static void
  437. rtl8169replenish(Ctlr* ctlr)
  438. {
  439. D *d;
  440. int rdt;
  441. Block *bp;
  442. rdt = ctlr->rdt;
  443. while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
  444. d = &ctlr->rd[rdt];
  445. if(ctlr->rb[rdt] == nil){
  446. /*
  447. * simple allocation for now
  448. */
  449. bp = iallocb(Mps);
  450. if(bp == nil){
  451. iprint("no available buffers\n");
  452. break;
  453. }
  454. ctlr->rb[rdt] = bp;
  455. d->addrlo = PCIWADDR(bp->rp);
  456. d->addrhi = 0;
  457. }
  458. coherence();
  459. d->control |= Own|Mps;
  460. rdt = NEXT(rdt, ctlr->nrd);
  461. ctlr->nrdfree++;
  462. }
  463. ctlr->rdt = rdt;
  464. }
  465. static void
  466. rtl8169init(Ether* edev)
  467. {
  468. int i;
  469. uint r;
  470. Block *bp;
  471. Ctlr *ctlr;
  472. ctlr = edev->ctlr;
  473. ilock(&ctlr->ilock);
  474. rtl8169halt(ctlr);
  475. /*
  476. * Setting Mulrw in Cplusc disables the Tx/Rx DMA burst settings
  477. * in Tcr/Rcr.
  478. */
  479. csr16w(ctlr, Cplusc, (1<<14)|Rxchksum|Mulrw); /* magic (1<<14) */
  480. /*
  481. * MAC Address.
  482. * Must put chip into config register write enable mode.
  483. */
  484. csr8w(ctlr, Cr9346, Eem1|Eem0);
  485. r = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0];
  486. csr32w(ctlr, Idr0, r);
  487. r = (edev->ea[5]<<8)|edev->ea[4];
  488. csr32w(ctlr, Idr0+4, r);
  489. /*
  490. * Enable receiver/transmitter.
  491. * Need to do this first or some of the settings below
  492. * won't take.
  493. */
  494. csr8w(ctlr, Cr, Te|Re);
  495. /*
  496. * Transmitter.
  497. * Mtps is in units of 128.
  498. */
  499. memset(ctlr->td, 0, sizeof(D)*ctlr->ntd);
  500. ctlr->tdh = ctlr->tdt = 0;
  501. ctlr->td[ctlr->ntd-1].control = Eor;
  502. ctlr->mtps = HOWMANY(Mps, 128);
  503. /*
  504. * Receiver.
  505. */
  506. memset(ctlr->rd, 0, sizeof(D)*ctlr->nrd);
  507. ctlr->rdh = ctlr->rdt = 0;
  508. ctlr->rd[ctlr->nrd-1].control = Eor;
  509. for(i = 0; i < ctlr->nrd; i++){
  510. if((bp = ctlr->rb[i]) != nil){
  511. ctlr->rb[i] = nil;
  512. freeb(bp);
  513. }
  514. }
  515. rtl8169replenish(ctlr);
  516. ctlr->rcr = Rxfth256|Mrxdmaunlimited|Ab|Apm;
  517. /*
  518. * Interrupts.
  519. * Disable Tdu|Tok for now, the transmit routine will tidy.
  520. * Tdu means the NIC ran out of descritors to send, so it
  521. * doesn't really need to ever be on.
  522. */
  523. csr32w(ctlr, Timerint, 0);
  524. csr16w(ctlr, Imr, Serr|Timeout/*|Tdu*/|Fovw|Punlc|Rdu|Ter/*|Tok*/|Rer|Rok);
  525. /*
  526. * Clear missed-packet counter;
  527. * initial early transmit threshold value;
  528. * set the descriptor ring base addresses;
  529. * set the maximum receive packet size - if it is
  530. * larger than 8191 the Rwt|Res bits may be set
  531. * in the receive descriptor control info even if
  532. * the packet is good;
  533. * no early-receive interrupts.
  534. */
  535. csr32w(ctlr, Mpc, 0);
  536. csr8w(ctlr, Mtps, ctlr->mtps);
  537. csr32w(ctlr, Tnpds+4, 0);
  538. csr32w(ctlr, Tnpds, PCIWADDR(ctlr->td));
  539. csr32w(ctlr, Rdsar+4, 0);
  540. csr32w(ctlr, Rdsar, PCIWADDR(ctlr->rd));
  541. csr16w(ctlr, Rms, Mps);
  542. csr16w(ctlr, Mulint, 0);
  543. /*
  544. * Set configuration.
  545. */
  546. csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
  547. ctlr->tcr = csr32r(ctlr, Tcr);
  548. csr32w(ctlr, Rcr, ctlr->rcr);
  549. csr16w(ctlr, 0xE2, 0); /* magic */
  550. csr8w(ctlr, Cr9346, 0);
  551. iunlock(&ctlr->ilock);
  552. // rtl8169mii(ctlr);
  553. }
  554. static void
  555. rtl8169attach(Ether* edev)
  556. {
  557. Ctlr *ctlr;
  558. ctlr = edev->ctlr;
  559. qlock(&ctlr->alock);
  560. if(ctlr->init == 0){
  561. /*
  562. * Handle allocation/init errors here.
  563. */
  564. ctlr->td = mallocalign(sizeof(D)*Ntd, 256, 0, 0);
  565. ctlr->tb = malloc(Ntd*sizeof(Block*));
  566. ctlr->ntd = Ntd;
  567. ctlr->rd = mallocalign(sizeof(D)*Nrd, 256, 0, 0);
  568. ctlr->rb = malloc(Nrd*sizeof(Block*));
  569. ctlr->nrd = Nrd;
  570. ctlr->dtcc = mallocalign(sizeof(Dtcc), 64, 0, 0);
  571. rtl8169init(edev);
  572. ctlr->init = 1;
  573. }
  574. qunlock(&ctlr->alock);
  575. /*
  576. * Should wait for link to be ready here.
  577. */
  578. }
  579. static void
  580. rtl8169link(Ether* edev)
  581. {
  582. uint r;
  583. int limit;
  584. Ctlr *ctlr;
  585. ctlr = edev->ctlr;
  586. /*
  587. * Maybe the link changed - do we care very much?
  588. * Could stall transmits if no link, maybe?
  589. */
  590. if(!((r = csr8r(ctlr, Phystatus)) & Linksts))
  591. return;
  592. limit = 256*1024;
  593. if(r & Speed10){
  594. edev->mbps = 10;
  595. limit = 65*1024;
  596. }
  597. else if(r & Speed100)
  598. edev->mbps = 100;
  599. else if(r & Speed1000)
  600. edev->mbps = 1000;
  601. if(edev->oq != nil)
  602. qsetlimit(edev->oq, limit);
  603. }
  604. static void
  605. rtl8169transmit(Ether* edev)
  606. {
  607. D *d;
  608. Block *bp;
  609. Ctlr *ctlr;
  610. int control, x;
  611. ctlr = edev->ctlr;
  612. ilock(&ctlr->tlock);
  613. for(x = ctlr->tdh; ctlr->ntq > 0; x = NEXT(x, ctlr->ntd)){
  614. d = &ctlr->td[x];
  615. if((control = d->control) & Own)
  616. break;
  617. /*
  618. * Check errors and log here.
  619. */
  620. USED(control);
  621. /*
  622. * Free it up.
  623. * Need to clean the descriptor here? Not really.
  624. * Simple freeb for now (no chain and freeblist).
  625. * Use ntq count for now.
  626. */
  627. freeb(ctlr->tb[x]);
  628. ctlr->tb[x] = nil;
  629. d->control &= Eor;
  630. ctlr->ntq--;
  631. }
  632. ctlr->tdh = x;
  633. x = ctlr->tdt;
  634. while(ctlr->ntq < (ctlr->ntd-1)){
  635. if((bp = qget(edev->oq)) == nil)
  636. break;
  637. d = &ctlr->td[x];
  638. d->addrlo = PCIWADDR(bp->rp);
  639. d->addrhi = 0;
  640. ctlr->tb[x] = bp;
  641. coherence();
  642. d->control |= Own|Fs|Ls|((BLEN(bp)<<TxflSHIFT) & TxflMASK);
  643. x = NEXT(x, ctlr->ntd);
  644. ctlr->ntq++;
  645. }
  646. if(x != ctlr->tdt){
  647. ctlr->tdt = x;
  648. csr8w(ctlr, Tppoll, Npq);
  649. }
  650. else if(ctlr->ntq >= (ctlr->ntd-1))
  651. ctlr->txdu++;
  652. iunlock(&ctlr->tlock);
  653. }
  654. static void
  655. rtl8169receive(Ether* edev)
  656. {
  657. D *d;
  658. int rdh;
  659. Block *bp;
  660. Ctlr *ctlr;
  661. u32int control;
  662. ctlr = edev->ctlr;
  663. rdh = ctlr->rdh;
  664. for(;;){
  665. d = &ctlr->rd[rdh];
  666. if(d->control & Own)
  667. break;
  668. control = d->control;
  669. if((control & (Fs|Ls|Res)) == (Fs|Ls)){
  670. bp = ctlr->rb[rdh];
  671. ctlr->rb[rdh] = nil;
  672. bp->wp = bp->rp + ((control & RxflMASK)>>RxflSHIFT) - 4;
  673. bp->next = nil;
  674. if(control & Fovf)
  675. ctlr->fovf++;
  676. switch(control & (Pid1|Pid0)){
  677. default:
  678. break;
  679. case Pid0:
  680. if(control & Tcpf){
  681. ctlr->tcpf++;
  682. break;
  683. }
  684. bp->flag |= Btcpck;
  685. break;
  686. case Pid1:
  687. if(control & Udpf){
  688. ctlr->udpf++;
  689. break;
  690. }
  691. bp->flag |= Budpck;
  692. break;
  693. case Pid1|Pid0:
  694. if(control & Ipf){
  695. ctlr->ipf++;
  696. break;
  697. }
  698. bp->flag |= Bipck;
  699. break;
  700. }
  701. etheriq(edev, bp, 1);
  702. }
  703. else{
  704. /*
  705. * Error stuff here.
  706. print("control %8.8uX\n", control);
  707. */
  708. }
  709. d->control &= Eor;
  710. ctlr->nrdfree--;
  711. rdh = NEXT(rdh, ctlr->nrd);
  712. }
  713. ctlr->rdh = rdh;
  714. if(ctlr->nrdfree < ctlr->nrd/2)
  715. rtl8169replenish(ctlr);
  716. }
  717. static void
  718. rtl8169interrupt(Ureg*, void* arg)
  719. {
  720. Ctlr *ctlr;
  721. Ether *edev;
  722. u32int isr;
  723. edev = arg;
  724. ctlr = edev->ctlr;
  725. while((isr = csr16r(ctlr, Isr)) != 0){
  726. csr16w(ctlr, Isr, isr);
  727. if(isr & (Fovw|Punlc|Rdu|Rer|Rok)){
  728. rtl8169receive(edev);
  729. if(!(isr & (Punlc|Rok)))
  730. ctlr->ierrs++;
  731. if(isr & Rer)
  732. ctlr->rer++;
  733. if(isr & Rdu)
  734. ctlr->rdu++;
  735. if(isr & Punlc)
  736. ctlr->punlc++;
  737. if(isr & Fovw)
  738. ctlr->fovw++;
  739. isr &= ~(Fovw|Rdu|Rer|Rok);
  740. }
  741. if(isr & (Tdu|Ter|Tok)){
  742. rtl8169transmit(edev);
  743. isr &= ~(Tdu|Ter|Tok);
  744. }
  745. if(isr & Punlc){
  746. rtl8169link(edev);
  747. isr &= ~Punlc;
  748. }
  749. /*
  750. * Some of the reserved bits get set sometimes...
  751. */
  752. if(isr & (Serr|Timeout|Tdu|Fovw|Punlc|Rdu|Ter|Tok|Rer|Rok))
  753. panic("rtl8169interrupt: imr %4.4uX isr %4.4uX\n",
  754. csr16r(ctlr, Imr), isr);
  755. }
  756. }
  757. static Ctlr*
  758. rtl8169match(Ether* edev, int id)
  759. {
  760. Pcidev *p;
  761. Ctlr *ctlr;
  762. int i, port;
  763. /*
  764. * Any adapter matches if no edev->port is supplied,
  765. * otherwise the ports must match.
  766. */
  767. for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
  768. if(ctlr->active)
  769. continue;
  770. p = ctlr->pcidev;
  771. if(((p->did<<16)|p->vid) != id)
  772. continue;
  773. port = p->mem[0].bar & ~0x01;
  774. if(edev->port != 0 && edev->port != port)
  775. continue;
  776. if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
  777. print("rtl8169: port 0x%uX in use\n", port);
  778. continue;
  779. }
  780. if(pcigetpms(p) > 0){
  781. pcisetpms(p, 0);
  782. for(i = 0; i < 6; i++)
  783. pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
  784. pcicfgw8(p, PciINTL, p->intl);
  785. pcicfgw8(p, PciLTR, p->ltr);
  786. pcicfgw8(p, PciCLS, p->cls);
  787. pcicfgw16(p, PciPCR, p->pcr);
  788. }
  789. ctlr->port = port;
  790. if(rtl8169reset(ctlr))
  791. continue;
  792. csr8w(ctlr, 0x82, 1); /* magic */
  793. rtl8169mii(ctlr);
  794. pcisetbme(p);
  795. ctlr->active = 1;
  796. return ctlr;
  797. }
  798. return nil;
  799. }
  800. static struct {
  801. char* name;
  802. int id;
  803. } rtl8169pci[] = {
  804. { "rtl8169", (0x8169<<16)|0x10EC, }, /* generic */
  805. { "CG-LAPCIGT", (0xC107<<16)|0x1259, }, /* Corega CG-LAPCIGT */
  806. { nil },
  807. };
  808. static int
  809. rtl8169pnp(Ether* edev)
  810. {
  811. Pcidev *p;
  812. Ctlr *ctlr;
  813. int i, id;
  814. uchar ea[Eaddrlen];
  815. /*
  816. * Make a list of all ethernet controllers
  817. * if not already done.
  818. */
  819. if(ctlrhead == nil){
  820. p = nil;
  821. while(p = pcimatch(p, 0, 0)){
  822. if(p->ccrb != 0x02 || p->ccru != 0)
  823. continue;
  824. ctlr = malloc(sizeof(Ctlr));
  825. ctlr->pcidev = p;
  826. ctlr->id = (p->did<<16)|p->vid;
  827. if(ctlrhead != nil)
  828. ctlrtail->next = ctlr;
  829. else
  830. ctlrhead = ctlr;
  831. ctlrtail = ctlr;
  832. }
  833. }
  834. /*
  835. * Is it an RTL8169 under a different name?
  836. * Normally a search is made through all the found controllers
  837. * for one which matches any of the known vid+did pairs.
  838. * If a vid+did pair is specified a search is made for that
  839. * specific controller only.
  840. */
  841. id = 0;
  842. for(i = 0; i < edev->nopt; i++){
  843. if(cistrncmp(edev->opt[i], "id=", 3) == 0)
  844. id = strtol(&edev->opt[i][3], nil, 0);
  845. }
  846. ctlr = nil;
  847. if(id != 0)
  848. ctlr = rtl8169match(edev, id);
  849. else for(i = 0; rtl8169pci[i].name; i++){
  850. if((ctlr = rtl8169match(edev, rtl8169pci[i].id)) != nil)
  851. break;
  852. }
  853. if(ctlr == nil)
  854. return -1;
  855. edev->ctlr = ctlr;
  856. edev->port = ctlr->port;
  857. edev->irq = ctlr->pcidev->intl;
  858. edev->tbdf = ctlr->pcidev->tbdf;
  859. /*
  860. * Check if the adapter's station address is to be overridden.
  861. * If not, read it from the device and set in edev->ea.
  862. */
  863. memset(ea, 0, Eaddrlen);
  864. if(memcmp(ea, edev->ea, Eaddrlen) == 0){
  865. i = csr32r(ctlr, Idr0);
  866. edev->ea[0] = i;
  867. edev->ea[1] = i>>8;
  868. edev->ea[2] = i>>16;
  869. edev->ea[3] = i>>24;
  870. i = csr32r(ctlr, Idr0+4);
  871. edev->ea[4] = i;
  872. edev->ea[5] = i>>8;
  873. }
  874. edev->attach = rtl8169attach;
  875. edev->transmit = rtl8169transmit;
  876. edev->interrupt = rtl8169interrupt;
  877. edev->ifstat = rtl8169ifstat;
  878. edev->arg = edev;
  879. edev->promiscuous = rtl8169promiscuous;
  880. rtl8169link(edev);
  881. return 0;
  882. }
  883. void
  884. ether8169link(void)
  885. {
  886. addethercard("rtl8169", rtl8169pnp);
  887. }