ethervt6102.c 22 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. /*
  2. * VIA VT6102 Fast Ethernet Controller (Rhine II).
  3. * To do:
  4. * cache-line size alignments - done
  5. * reduce tx interrupts
  6. * use 2 descriptors on tx for alignment - done
  7. * reorganise initialisation/shutdown/reset
  8. * adjust Tx FIFO threshold on underflow - untested
  9. * why does the link status never cause an interrupt?
  10. * use the lproc as a periodic timer for stalls, etc.
  11. */
  12. #include "u.h"
  13. #include "../port/lib.h"
  14. #include "mem.h"
  15. #include "dat.h"
  16. #include "fns.h"
  17. #include "io.h"
  18. #include "../port/error.h"
  19. #include "../port/netif.h"
  20. #include "etherif.h"
  21. #include "ethermii.h"
  22. enum {
  23. Par0 = 0x00, /* Ethernet Address */
  24. Rcr = 0x06, /* Receive Configuration */
  25. Tcr = 0x07, /* Transmit Configuration */
  26. Cr = 0x08, /* Control */
  27. Isr = 0x0C, /* Interrupt Status */
  28. Imr = 0x0E, /* Interrupt Mask */
  29. Mcfilt0 = 0x10, /* Multicast Filter 0 */
  30. Mcfilt1 = 0x14, /* Multicast Filter 1 */
  31. Rxdaddr = 0x18, /* Current Rx Descriptor Address */
  32. Txdaddr = 0x1C, /* Current Tx Descriptor Address */
  33. Phyadr = 0x6C, /* Phy Address */
  34. Miisr = 0x6D, /* MII Status */
  35. Bcr0 = 0x6E, /* Bus Control */
  36. Bcr1 = 0x6F,
  37. Miicr = 0x70, /* MII Control */
  38. Miiadr = 0x71, /* MII Address */
  39. Miidata = 0x72, /* MII Data */
  40. Eecsr = 0x74, /* EEPROM Control and Status */
  41. };
  42. enum { /* Rcr */
  43. Sep = 0x01, /* Accept Error Packets */
  44. Ar = 0x02, /* Accept Small Packets */
  45. Am = 0x04, /* Accept Multicast */
  46. Ab = 0x08, /* Accept Broadcast */
  47. Prom = 0x10, /* Accept Physical Address Packets */
  48. RrftMASK = 0xE0, /* Receive FIFO Threshold */
  49. RrftSHIFT = 5,
  50. Rrft64 = 0<<RrftSHIFT,
  51. Rrft32 = 1<<RrftSHIFT,
  52. Rrft128 = 2<<RrftSHIFT,
  53. Rrft256 = 3<<RrftSHIFT,
  54. Rrft512 = 4<<RrftSHIFT,
  55. Rrft768 = 5<<RrftSHIFT,
  56. Rrft1024 = 6<<RrftSHIFT,
  57. RrftSAF = 7<<RrftSHIFT,
  58. };
  59. enum { /* Tcr */
  60. Lb0 = 0x02, /* Loopback Mode */
  61. Lb1 = 0x04,
  62. Ofset = 0x08, /* Back-off Priority Selection */
  63. RtsfMASK = 0xE0, /* Transmit FIFO Threshold */
  64. RtsfSHIFT = 5,
  65. Rtsf128 = 0<<RtsfSHIFT,
  66. Rtsf256 = 1<<RtsfSHIFT,
  67. Rtsf512 = 2<<RtsfSHIFT,
  68. Rtsf1024 = 3<<RtsfSHIFT,
  69. RtsfSAF = 7<<RtsfSHIFT,
  70. };
  71. enum { /* Cr */
  72. Init = 0x0001, /* INIT Process Begin */
  73. Strt = 0x0002, /* Start NIC */
  74. Stop = 0x0004, /* Stop NIC */
  75. Rxon = 0x0008, /* Turn on Receive Process */
  76. Txon = 0x0010, /* Turn on Transmit Process */
  77. Tdmd = 0x0020, /* Transmit Poll Demand */
  78. Rdmd = 0x0040, /* Receive Poll Demand */
  79. Eren = 0x0100, /* Early Receive Enable */
  80. Fdx = 0x0400, /* Set MAC to Full Duplex Mode */
  81. Dpoll = 0x0800, /* Disable Td/Rd Auto Polling */
  82. Tdmd1 = 0x2000, /* Transmit Poll Demand 1 */
  83. Rdmd1 = 0x4000, /* Receive Poll Demand 1 */
  84. Sfrst = 0x8000, /* Software Reset */
  85. };
  86. enum { /* Isr/Imr */
  87. Prx = 0x0001, /* Received Packet Successfully */
  88. Ptx = 0x0002, /* Transmitted Packet Successfully */
  89. Rxe = 0x0004, /* Receive Error */
  90. Txe = 0x0008, /* Transmit Error */
  91. Tu = 0x0010, /* Transmit Buffer Underflow */
  92. Ru = 0x0020, /* Receive Buffer Link Error */
  93. Be = 0x0040, /* PCI Bus Error */
  94. Cnt = 0x0080, /* Counter Overflow */
  95. Eri = 0x0100, /* Early Receive Interrupt */
  96. Udfi = 0x0200, /* Tx FIFO Underflow */
  97. Ovfi = 0x0400, /* Receive FIFO Overflow */
  98. Pktrace = 0x0800, /* Hmmm... */
  99. Norbf = 0x1000, /* No Receive Buffers */
  100. Abti = 0x2000, /* Transmission Abort */
  101. Srci = 0x4000, /* Port State Change */
  102. Geni = 0x8000, /* General Purpose Interrupt */
  103. };
  104. enum { /* Phyadr */
  105. PhyadMASK = 0x1F, /* PHY Address */
  106. PhyadSHIFT = 0,
  107. Mfdc = 0x20, /* Accelerate MDC Speed */
  108. Mpo0 = 0x40, /* MII Polling Timer Interval */
  109. Mpo1 = 0x80,
  110. };
  111. enum { /* Bcr0 */
  112. DmaMASK = 0x07, /* DMA Length */
  113. DmaSHIFT = 0,
  114. Dma32 = 0<<DmaSHIFT,
  115. Dma64 = 1<<DmaSHIFT,
  116. Dma128 = 2<<DmaSHIFT,
  117. Dma256 = 3<<DmaSHIFT,
  118. Dma512 = 4<<DmaSHIFT,
  119. Dma1024 = 5<<DmaSHIFT,
  120. DmaSAF = 7<<DmaSHIFT,
  121. CrftMASK = 0x38, /* Rx FIFO Threshold */
  122. CrftSHIFT = 3,
  123. Crft64 = 1<<CrftSHIFT,
  124. Crft128 = 2<<CrftSHIFT,
  125. Crft256 = 3<<CrftSHIFT,
  126. Crft512 = 4<<CrftSHIFT,
  127. Crft1024 = 5<<CrftSHIFT,
  128. CrftSAF = 7<<CrftSHIFT,
  129. Extled = 0x40, /* Extra LED Support Control */
  130. Med2 = 0x80, /* Medium Select Control */
  131. };
  132. enum { /* Bcr1 */
  133. PotMASK = 0x07, /* Polling Timer Interval */
  134. PotSHIFT = 0,
  135. CtftMASK = 0x38, /* Tx FIFO Threshold */
  136. CtftSHIFT = 3,
  137. Ctft64 = 1<<CtftSHIFT,
  138. Ctft128 = 2<<CtftSHIFT,
  139. Ctft256 = 3<<CtftSHIFT,
  140. Ctft512 = 4<<CtftSHIFT,
  141. Ctft1024 = 5<<CtftSHIFT,
  142. CtftSAF = 7<<CtftSHIFT,
  143. };
  144. enum { /* Miicr */
  145. Mdc = 0x01, /* Clock */
  146. Mdi = 0x02, /* Data In */
  147. Mdo = 0x04, /* Data Out */
  148. Mout = 0x08, /* Output Enable */
  149. Mdpm = 0x10, /* Direct Program Mode Enable */
  150. Wcmd = 0x20, /* Write Enable */
  151. Rcmd = 0x40, /* Read Enable */
  152. Mauto = 0x80, /* Auto Polling Enable */
  153. };
  154. enum { /* Miiadr */
  155. MadMASK = 0x1F, /* MII Port Address */
  156. MadSHIFT = 0,
  157. Mdone = 0x20, /* Accelerate MDC Speed */
  158. Msrcen = 0x40, /* MII Polling Timer Interval */
  159. Midle = 0x80,
  160. };
  161. enum { /* Eecsr */
  162. Edo = 0x01, /* Data Out */
  163. Edi = 0x02, /* Data In */
  164. Eck = 0x04, /* Clock */
  165. Ecs = 0x08, /* Chip Select */
  166. Dpm = 0x10, /* Direct Program Mode Enable */
  167. Autold = 0x20, /* Dynamic Reload */
  168. Embp = 0x40, /* Embedded Program Enable */
  169. Eepr = 0x80, /* Programmed */
  170. };
  171. /*
  172. * Ring descriptor. The space allocated for each
  173. * of these will be rounded up to a cache-line boundary.
  174. * The first 4 elements are known to the hardware.
  175. */
  176. typedef struct Ds Ds;
  177. typedef struct Ds {
  178. uint status;
  179. uint control;
  180. uint addr;
  181. uint branch;
  182. Block* bp;
  183. void* bounce;
  184. Ds* next;
  185. Ds* prev;
  186. } Ds;
  187. enum { /* Rx Ds status */
  188. Rerr = 0x00000001, /* Receiver Error */
  189. Crc = 0x00000002, /* CRC Error */
  190. Fae = 0x00000004, /* Frame Alignment Error */
  191. Fov = 0x00000008, /* FIFO Overflow */
  192. Long = 0x00000010, /* A Long Packet */
  193. Runt = 0x00000020, /* A Runt Packet */
  194. Rxserr = 0x00000040, /* System Error */
  195. Buff = 0x00000080, /* Buffer Underflow Error */
  196. Rxedp = 0x00000100, /* End of Packet Buffer */
  197. Rxstp = 0x00000200, /* Packet Start */
  198. Chn = 0x00000400, /* Chain Buffer */
  199. Phy = 0x00000800, /* Physical Address Packet */
  200. Bar = 0x00001000, /* Broadcast Packet */
  201. Mar = 0x00002000, /* Multicast Packet */
  202. Rxok = 0x00008000, /* Packet Received Successfully */
  203. LengthMASK = 0x07FF0000, /* Received Packet Length */
  204. LengthSHIFT = 16,
  205. Own = 0x80000000, /* Descriptor Owned by NIC */
  206. };
  207. enum { /* Tx Ds status */
  208. NcrMASK = 0x0000000F, /* Collision Retry Count */
  209. NcrSHIFT = 0,
  210. Cols = 0x00000010, /* Experienced Collisions */
  211. Cdh = 0x00000080, /* CD Heartbeat */
  212. Abt = 0x00000100, /* Aborted after Excessive Collisions */
  213. Owc = 0x00000200, /* Out of Window Collision Seen */
  214. Crs = 0x00000400, /* Carrier Sense Lost */
  215. Udf = 0x00000800, /* FIFO Underflow */
  216. Tbuff = 0x00001000, /* Invalid Td */
  217. Txserr = 0x00002000, /* System Error */
  218. Terr = 0x00008000, /* Excessive Collisions */
  219. };
  220. enum { /* Tx Ds control */
  221. TbsMASK = 0x000007FF, /* Tx Buffer Size */
  222. TbsSHIFT = 0,
  223. Chain = 0x00008000, /* Chain Buffer */
  224. Crcdisable = 0x00010000, /* Disable CRC generation */
  225. Stp = 0x00200000, /* Start of Packet */
  226. Edp = 0x00400000, /* End of Packet */
  227. Ic = 0x00800000, /* Assert Interrupt Immediately */
  228. };
  229. enum {
  230. Nrd = 64,
  231. Ntd = 64,
  232. Rdbsz = ROUNDUP(ETHERMAXTU+4, 4),
  233. Nrxstats = 8,
  234. Ntxstats = 9,
  235. Txcopy = 128,
  236. };
  237. typedef struct Ctlr Ctlr;
  238. typedef struct Ctlr {
  239. int port;
  240. Pcidev* pcidev;
  241. Ctlr* next;
  242. int active;
  243. int id;
  244. uchar par[Eaddrlen];
  245. QLock alock; /* attach */
  246. void* alloc; /* receive/transmit descriptors */
  247. int cls; /* alignment */
  248. int nrd;
  249. int ntd;
  250. Ds* rd;
  251. Ds* rdh;
  252. Lock tlock;
  253. Ds* td;
  254. Ds* tdh;
  255. Ds* tdt;
  256. int tdused;
  257. Lock clock; /* */
  258. int cr;
  259. int imr;
  260. int tft; /* Tx threshold */
  261. Mii* mii;
  262. Rendez lrendez;
  263. int lwakeup;
  264. uint rxstats[Nrxstats]; /* statistics */
  265. uint txstats[Ntxstats];
  266. uint intr;
  267. uint lintr;
  268. uint lsleep;
  269. uint rintr;
  270. uint tintr;
  271. uint taligned;
  272. uint tsplit;
  273. uint tcopied;
  274. uint txdw;
  275. } Ctlr;
  276. static Ctlr* vt6102ctlrhead;
  277. static Ctlr* vt6102ctlrtail;
  278. #define csr8r(c, r) (inb((c)->port+(r)))
  279. #define csr16r(c, r) (ins((c)->port+(r)))
  280. #define csr32r(c, r) (inl((c)->port+(r)))
  281. #define csr8w(c, r, b) (outb((c)->port+(r), (int)(b)))
  282. #define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
  283. #define csr32w(c, r, w) (outl((c)->port+(r), (ulong)(w)))
  284. static char* rxstats[Nrxstats] = {
  285. "Receiver Error",
  286. "CRC Error",
  287. "Frame Alignment Error",
  288. "FIFO Overflow",
  289. "Long Packet",
  290. "Runt Packet",
  291. "System Error",
  292. "Buffer Underflow Error",
  293. };
  294. static char* txstats[Ntxstats] = {
  295. "Aborted after Excessive Collisions",
  296. "Out of Window Collision Seen",
  297. "Carrier Sense Lost",
  298. "FIFO Underflow",
  299. "Invalid Td",
  300. "System Error",
  301. nil,
  302. "Excessive Collisions",
  303. };
  304. static long
  305. vt6102ifstat(Ether* edev, void* a, long n, ulong offset)
  306. {
  307. char *p;
  308. Ctlr *ctlr;
  309. int i, l, r;
  310. ctlr = edev->ctlr;
  311. p = malloc(2*READSTR);
  312. l = 0;
  313. for(i = 0; i < Nrxstats; i++){
  314. l += snprint(p+l, 2*READSTR-l, "%s: %ud\n",
  315. rxstats[i], ctlr->rxstats[i]);
  316. }
  317. for(i = 0; i < Ntxstats; i++){
  318. if(txstats[i] == nil)
  319. continue;
  320. l += snprint(p+l, 2*READSTR-l, "%s: %ud\n",
  321. txstats[i], ctlr->txstats[i]);
  322. }
  323. l += snprint(p+l, 2*READSTR-l, "cls: %ud\n", ctlr->cls);
  324. l += snprint(p+l, 2*READSTR-l, "intr: %ud\n", ctlr->intr);
  325. l += snprint(p+l, 2*READSTR-l, "lintr: %ud\n", ctlr->lintr);
  326. l += snprint(p+l, 2*READSTR-l, "lsleep: %ud\n", ctlr->lsleep);
  327. l += snprint(p+l, 2*READSTR-l, "rintr: %ud\n", ctlr->rintr);
  328. l += snprint(p+l, 2*READSTR-l, "tintr: %ud\n", ctlr->tintr);
  329. l += snprint(p+l, 2*READSTR-l, "taligned: %ud\n", ctlr->taligned);
  330. l += snprint(p+l, 2*READSTR-l, "tsplit: %ud\n", ctlr->tsplit);
  331. l += snprint(p+l, 2*READSTR-l, "tcopied: %ud\n", ctlr->tcopied);
  332. l += snprint(p+l, 2*READSTR-l, "txdw: %ud\n", ctlr->txdw);
  333. l += snprint(p+l, 2*READSTR-l, "tft: %ud\n", ctlr->tft);
  334. if(ctlr->mii != nil && ctlr->mii->curphy != nil){
  335. l += snprint(p+l, 2*READSTR, "phy: ");
  336. for(i = 0; i < NMiiPhyr; i++){
  337. if(i && ((i & 0x07) == 0))
  338. l += snprint(p+l, 2*READSTR-l, "\n ");
  339. r = miimir(ctlr->mii, i);
  340. l += snprint(p+l, 2*READSTR-l, " %4.4uX", r);
  341. }
  342. snprint(p+l, 2*READSTR-l, "\n");
  343. }
  344. snprint(p+l, 2*READSTR-l, "\n");
  345. n = readstr(offset, a, n, p);
  346. free(p);
  347. return n;
  348. }
  349. static void
  350. vt6102promiscuous(void* arg, int on)
  351. {
  352. int rcr;
  353. Ctlr *ctlr;
  354. Ether *edev;
  355. edev = arg;
  356. ctlr = edev->ctlr;
  357. rcr = csr8r(ctlr, Rcr);
  358. if(on)
  359. rcr |= Prom;
  360. else
  361. rcr &= ~Prom;
  362. csr8w(ctlr, Rcr, rcr);
  363. }
  364. static void
  365. vt6102multicast(void* arg, uchar* addr, int on)
  366. {
  367. /*
  368. * For now Am is set in Rcr.
  369. * Will need to interlock with promiscuous
  370. * when this gets filled in.
  371. */
  372. USED(arg, addr, on);
  373. }
  374. static int
  375. vt6102wakeup(void* v)
  376. {
  377. return *((int*)v) != 0;
  378. }
  379. static void
  380. vt6102imr(Ctlr* ctlr, int imr)
  381. {
  382. ilock(&ctlr->clock);
  383. ctlr->imr |= imr;
  384. csr16w(ctlr, Imr, ctlr->imr);
  385. iunlock(&ctlr->clock);
  386. }
  387. static void
  388. vt6102lproc(void* arg)
  389. {
  390. Ctlr *ctlr;
  391. Ether *edev;
  392. MiiPhy *phy;
  393. edev = arg;
  394. ctlr = edev->ctlr;
  395. for(;;){
  396. if(ctlr->mii == nil || ctlr->mii->curphy == nil)
  397. break;
  398. if(miistatus(ctlr->mii) < 0)
  399. goto enable;
  400. phy = ctlr->mii->curphy;
  401. ilock(&ctlr->clock);
  402. if(phy->fd)
  403. ctlr->cr |= Fdx;
  404. else
  405. ctlr->cr &= ~Fdx;
  406. csr16w(ctlr, Cr, ctlr->cr);
  407. iunlock(&ctlr->clock);
  408. enable:
  409. ctlr->lwakeup = 0;
  410. vt6102imr(ctlr, Srci);
  411. ctlr->lsleep++;
  412. sleep(&ctlr->lrendez, vt6102wakeup, &ctlr->lwakeup);
  413. }
  414. pexit("vt6102lproc: done", 1);
  415. }
  416. static void
  417. vt6102attach(Ether* edev)
  418. {
  419. int i;
  420. Ctlr *ctlr;
  421. Ds *ds, *prev;
  422. uchar *alloc, *bounce;
  423. char name[KNAMELEN];
  424. ctlr = edev->ctlr;
  425. qlock(&ctlr->alock);
  426. if(ctlr->alloc != nil){
  427. qunlock(&ctlr->alock);
  428. return;
  429. }
  430. /*
  431. * Descriptor and bounce-buffer space.
  432. * Must all be aligned on a 4-byte boundary,
  433. * but try to align on cache-lines.
  434. */
  435. ctlr->nrd = Nrd;
  436. ctlr->ntd = Ntd;
  437. alloc = malloc((ctlr->nrd+ctlr->ntd)*ctlr->cls + ctlr->ntd*Txcopy + ctlr->cls-1);
  438. if(alloc == nil){
  439. qunlock(&ctlr->alock);
  440. return;
  441. }
  442. ctlr->alloc = alloc;
  443. alloc = (uchar*)ROUNDUP((ulong)alloc, ctlr->cls);
  444. ctlr->rd = (Ds*)alloc;
  445. if(waserror()){
  446. ds = ctlr->rd;
  447. for(i = 0; i < ctlr->nrd; i++){
  448. if(ds->bp != nil){
  449. freeb(ds->bp);
  450. ds->bp = nil;
  451. }
  452. if((ds = ds->next) == nil)
  453. break;
  454. }
  455. free(ctlr->alloc);
  456. ctlr->alloc = nil;
  457. qunlock(&ctlr->alock);
  458. nexterror();
  459. }
  460. prev = ctlr->rd + ctlr->nrd-1;
  461. for(i = 0; i < ctlr->nrd; i++){
  462. ds = (Ds*)alloc;
  463. alloc += ctlr->cls;
  464. ds->control = Rdbsz;
  465. ds->branch = PCIWADDR(alloc);
  466. ds->bp = iallocb(Rdbsz+3);
  467. if(ds->bp == nil)
  468. error("vt6102: can't allocate receive ring\n");
  469. ds->bp->rp = (uchar*)ROUNDUP((ulong)ds->bp->rp, 4);
  470. ds->addr = PCIWADDR(ds->bp->rp);
  471. ds->next = (Ds*)alloc;
  472. ds->prev = prev;
  473. prev = ds;
  474. ds->status = Own;
  475. }
  476. prev->branch = 0;
  477. prev->next = ctlr->rd;
  478. prev->status = 0;
  479. ctlr->rdh = ctlr->rd;
  480. ctlr->td = (Ds*)alloc;
  481. prev = ctlr->td + ctlr->ntd-1;
  482. bounce = alloc + ctlr->ntd*ctlr->cls;
  483. for(i = 0; i < ctlr->ntd; i++){
  484. ds = (Ds*)alloc;
  485. alloc += ctlr->cls;
  486. ds->bounce = bounce;
  487. bounce += Txcopy;
  488. ds->next = (Ds*)alloc;
  489. ds->prev = prev;
  490. prev = ds;
  491. }
  492. prev->next = ctlr->td;
  493. ctlr->tdh = ctlr->tdt = ctlr->td;
  494. ctlr->tdused = 0;
  495. ctlr->cr = Dpoll|Rdmd|Txon|Rxon|Strt;
  496. /*Srci|Abti|Norbf|Pktrace|Ovfi|Udfi|Be|Ru|Tu|Txe|Rxe|Ptx|Prx*/
  497. ctlr->imr = Abti|Norbf|Pktrace|Ovfi|Udfi|Be|Ru|Tu|Txe|Rxe|Ptx|Prx;
  498. ilock(&ctlr->clock);
  499. csr32w(ctlr, Rxdaddr, PCIWADDR(ctlr->rd));
  500. csr32w(ctlr, Txdaddr, PCIWADDR(ctlr->td));
  501. csr16w(ctlr, Isr, ~0);
  502. csr16w(ctlr, Imr, ctlr->imr);
  503. csr16w(ctlr, Cr, ctlr->cr);
  504. iunlock(&ctlr->clock);
  505. snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
  506. kproc(name, vt6102lproc, edev);
  507. qunlock(&ctlr->alock);
  508. poperror();
  509. }
  510. static void
  511. vt6102transmit(Ether* edev)
  512. {
  513. Block *bp;
  514. Ctlr *ctlr;
  515. Ds *ds, *next;
  516. int control, i, o, prefix, size, tdused, timeo;
  517. ctlr = edev->ctlr;
  518. ilock(&ctlr->tlock);
  519. /*
  520. * Free any completed packets
  521. */
  522. ds = ctlr->tdh;
  523. for(tdused = ctlr->tdused; tdused > 0; tdused--){
  524. /*
  525. * For some errors the chip will turn the Tx engine
  526. * off. Wait for that to happen.
  527. * Could reset and re-init the chip here if it doesn't
  528. * play fair.
  529. * To do: adjust Tx FIFO threshold on underflow.
  530. */
  531. if(ds->status & (Abt|Tbuff|Udf)){
  532. for(timeo = 0; timeo < 1000; timeo++){
  533. if(!(csr16r(ctlr, Cr) & Txon))
  534. break;
  535. microdelay(1);
  536. }
  537. ds->status = Own;
  538. csr32w(ctlr, Txdaddr, PCIWADDR(ds));
  539. }
  540. if(ds->status & Own)
  541. break;
  542. ds->addr = 0;
  543. ds->branch = 0;
  544. if(ds->bp != nil){
  545. freeb(ds->bp);
  546. ds->bp = nil;
  547. }
  548. for(i = 0; i < Ntxstats-1; i++){
  549. if(ds->status & (1<<i))
  550. ctlr->txstats[i]++;
  551. }
  552. ctlr->txstats[i] += (ds->status & NcrMASK)>>NcrSHIFT;
  553. ds = ds->next;
  554. }
  555. ctlr->tdh = ds;
  556. /*
  557. * Try to fill the ring back up.
  558. */
  559. ds = ctlr->tdt;
  560. while(tdused < ctlr->ntd-2){
  561. if((bp = qget(edev->oq)) == nil)
  562. break;
  563. tdused++;
  564. size = BLEN(bp);
  565. prefix = 0;
  566. if(o = (((int)bp->rp) & 0x03)){
  567. prefix = Txcopy-o;
  568. if(prefix > size)
  569. prefix = size;
  570. memmove(ds->bounce, bp->rp, prefix);
  571. ds->addr = PCIWADDR(ds->bounce);
  572. bp->rp += prefix;
  573. size -= prefix;
  574. }
  575. next = ds->next;
  576. ds->branch = PCIWADDR(ds->next);
  577. if(size){
  578. if(prefix){
  579. next->bp = bp;
  580. next->addr = PCIWADDR(bp->rp);
  581. next->branch = PCIWADDR(next->next);
  582. next->control = Edp|Chain|((size<<TbsSHIFT) & TbsMASK);
  583. control = Stp|Chain|((prefix<<TbsSHIFT) & TbsMASK);
  584. next = next->next;
  585. tdused++;
  586. ctlr->tsplit++;
  587. }
  588. else{
  589. ds->bp = bp;
  590. ds->addr = PCIWADDR(bp->rp);
  591. control = Edp|Stp|((size<<TbsSHIFT) & TbsMASK);
  592. ctlr->taligned++;
  593. }
  594. }
  595. else{
  596. freeb(bp);
  597. control = Edp|Stp|((prefix<<TbsSHIFT) & TbsMASK);
  598. ctlr->tcopied++;
  599. }
  600. ds->control = control;
  601. if(tdused >= ctlr->ntd-2){
  602. ds->control |= Ic;
  603. ctlr->txdw++;
  604. }
  605. coherence();
  606. ds->status = Own;
  607. ds = next;
  608. }
  609. ctlr->tdt = ds;
  610. ctlr->tdused = tdused;
  611. if(ctlr->tdused)
  612. csr16w(ctlr, Cr, Tdmd|ctlr->cr);
  613. iunlock(&ctlr->tlock);
  614. }
  615. static void
  616. vt6102receive(Ether* edev)
  617. {
  618. Ds *ds;
  619. Block *bp;
  620. Ctlr *ctlr;
  621. int i, len;
  622. ctlr = edev->ctlr;
  623. ds = ctlr->rdh;
  624. while(!(ds->status & Own) && ds->status != 0){
  625. if(ds->status & Rerr){
  626. for(i = 0; i < Nrxstats; i++){
  627. if(ds->status & (1<<i))
  628. ctlr->rxstats[i]++;
  629. }
  630. }
  631. else if(bp = iallocb(Rdbsz+3)){
  632. len = ((ds->status & LengthMASK)>>LengthSHIFT)-4;
  633. ds->bp->wp = ds->bp->rp+len;
  634. etheriq(edev, ds->bp, 1);
  635. bp->rp = (uchar*)ROUNDUP((ulong)bp->rp, 4);
  636. ds->addr = PCIWADDR(bp->rp);
  637. ds->bp = bp;
  638. }
  639. ds->control = Rdbsz;
  640. ds->branch = 0;
  641. ds->status = 0;
  642. ds->prev->branch = PCIWADDR(ds);
  643. coherence();
  644. ds->prev->status = Own;
  645. ds = ds->next;
  646. }
  647. ctlr->rdh = ds;
  648. csr16w(ctlr, Cr, ctlr->cr);
  649. }
  650. static void
  651. vt6102interrupt(Ureg*, void* arg)
  652. {
  653. Ctlr *ctlr;
  654. Ether *edev;
  655. int imr, isr, r, timeo;
  656. edev = arg;
  657. ctlr = edev->ctlr;
  658. ilock(&ctlr->clock);
  659. csr16w(ctlr, Imr, 0);
  660. imr = ctlr->imr;
  661. ctlr->intr++;
  662. for(;;){
  663. if((isr = csr16r(ctlr, Isr)) != 0)
  664. csr16w(ctlr, Isr, isr);
  665. if((isr & ctlr->imr) == 0)
  666. break;
  667. if(isr & Srci){
  668. imr &= ~Srci;
  669. ctlr->lwakeup = isr & Srci;
  670. wakeup(&ctlr->lrendez);
  671. isr &= ~Srci;
  672. ctlr->lintr++;
  673. }
  674. if(isr & (Norbf|Pktrace|Ovfi|Ru|Rxe|Prx)){
  675. vt6102receive(edev);
  676. isr &= ~(Norbf|Pktrace|Ovfi|Ru|Rxe|Prx);
  677. ctlr->rintr++;
  678. }
  679. if(isr & (Abti|Udfi|Tu|Txe|Ptx)){
  680. if(isr & (Abti|Udfi|Tu)){
  681. for(timeo = 0; timeo < 1000; timeo++){
  682. if(!(csr16r(ctlr, Cr) & Txon))
  683. break;
  684. microdelay(1);
  685. }
  686. if((isr & Udfi) && ctlr->tft < CtftSAF){
  687. ctlr->tft += 1<<CtftSHIFT;
  688. r = csr8r(ctlr, Bcr1) & ~CtftMASK;
  689. csr8w(ctlr, Bcr1, r|ctlr->tft);
  690. }
  691. }
  692. vt6102transmit(edev);
  693. isr &= ~(Abti|Udfi|Tu|Txe|Ptx);
  694. ctlr->tintr++;
  695. }
  696. if(isr)
  697. panic("vt6102: isr %4.4uX\n", isr);
  698. }
  699. ctlr->imr = imr;
  700. csr16w(ctlr, Imr, ctlr->imr);
  701. iunlock(&ctlr->clock);
  702. }
  703. static int
  704. vt6102miimicmd(Mii* mii, int pa, int ra, int cmd, int data)
  705. {
  706. Ctlr *ctlr;
  707. int r, timeo;
  708. ctlr = mii->ctlr;
  709. csr8w(ctlr, Miicr, 0);
  710. r = csr8r(ctlr, Phyadr);
  711. csr8w(ctlr, Phyadr, (r & ~PhyadMASK)|pa);
  712. csr8w(ctlr, Phyadr, pa);
  713. csr8w(ctlr, Miiadr, ra);
  714. if(cmd == Wcmd)
  715. csr16w(ctlr, Miidata, data);
  716. csr8w(ctlr, Miicr, cmd);
  717. for(timeo = 0; timeo < 10000; timeo++){
  718. if(!(csr8r(ctlr, Miicr) & cmd))
  719. break;
  720. microdelay(1);
  721. }
  722. if(timeo >= 10000)
  723. return -1;
  724. if(cmd == Wcmd)
  725. return 0;
  726. return csr16r(ctlr, Miidata);
  727. }
  728. static int
  729. vt6102miimir(Mii* mii, int pa, int ra)
  730. {
  731. return vt6102miimicmd(mii, pa, ra, Rcmd, 0);
  732. }
  733. static int
  734. vt6102miimiw(Mii* mii, int pa, int ra, int data)
  735. {
  736. return vt6102miimicmd(mii, pa, ra, Wcmd, data);
  737. }
  738. static int
  739. vt6102detach(Ctlr* ctlr)
  740. {
  741. int timeo;
  742. /*
  743. * Soft reset the controller.
  744. */
  745. csr16w(ctlr, Cr, Stop);
  746. csr16w(ctlr, Cr, Stop|Sfrst);
  747. for(timeo = 0; timeo < 10000; timeo++){
  748. if(!(csr16r(ctlr, Cr) & Sfrst))
  749. break;
  750. microdelay(1);
  751. }
  752. if(timeo >= 1000)
  753. return -1;
  754. return 0;
  755. }
  756. static int
  757. vt6102reset(Ctlr* ctlr)
  758. {
  759. MiiPhy *phy;
  760. int i, r, timeo;
  761. if(vt6102detach(ctlr) < 0)
  762. return -1;
  763. /*
  764. * Load the MAC address into the PAR[01]
  765. * registers.
  766. */
  767. r = csr8r(ctlr, Eecsr);
  768. csr8w(ctlr, Eecsr, Autold|r);
  769. for(timeo = 0; timeo < 100; timeo++){
  770. if(!(csr8r(ctlr, Cr) & Autold))
  771. break;
  772. microdelay(1);
  773. }
  774. if(timeo >= 100)
  775. return -1;
  776. for(i = 0; i < Eaddrlen; i++)
  777. ctlr->par[i] = csr8r(ctlr, Par0+i);
  778. /*
  779. * Configure DMA and Rx/Tx thresholds.
  780. * If the Rx/Tx threshold bits in Bcr[01] are 0 then
  781. * the thresholds are determined by Rcr/Tcr.
  782. */
  783. r = csr8r(ctlr, Bcr0) & ~(CrftMASK|DmaMASK);
  784. csr8w(ctlr, Bcr0, r|Crft64|Dma64);
  785. r = csr8r(ctlr, Bcr1) & ~CtftMASK;
  786. csr8w(ctlr, Bcr1, r|ctlr->tft);
  787. r = csr8r(ctlr, Rcr) & ~(RrftMASK|Prom|Ar|Sep);
  788. csr8w(ctlr, Rcr, r|Ab|Am);
  789. csr32w(ctlr, Mcfilt0, ~0UL); /* accept all multicast */
  790. csr32w(ctlr, Mcfilt1, ~0UL);
  791. r = csr8r(ctlr, Tcr) & ~(RtsfMASK|Ofset|Lb1|Lb0);
  792. csr8w(ctlr, Tcr, r);
  793. /*
  794. * Link management.
  795. */
  796. if((ctlr->mii = malloc(sizeof(Mii))) == nil)
  797. return -1;
  798. ctlr->mii->mir = vt6102miimir;
  799. ctlr->mii->miw = vt6102miimiw;
  800. ctlr->mii->ctlr = ctlr;
  801. if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
  802. free(ctlr->mii);
  803. ctlr->mii = nil;
  804. return -1;
  805. }
  806. // print("oui %X phyno %d\n", phy->oui, phy->phyno);
  807. USED(phy);
  808. //miiane(ctlr->mii, ~0, ~0, ~0);
  809. return 0;
  810. }
  811. static void
  812. vt6102pci(void)
  813. {
  814. Pcidev *p;
  815. Ctlr *ctlr;
  816. int cls, port;
  817. p = nil;
  818. while(p = pcimatch(p, 0, 0)){
  819. if(p->ccrb != Pcibcnet || p->ccru != Pciscether)
  820. continue;
  821. switch((p->did<<16)|p->vid){
  822. default:
  823. continue;
  824. case (0x3053<<16)|0x1106: /* Rhine III vt6105m (Soekris) */
  825. case (0x3065<<16)|0x1106: /* Rhine II */
  826. case (0x3106<<16)|0x1106: /* Rhine III */
  827. break;
  828. }
  829. port = p->mem[0].bar & ~0x01;
  830. if(ioalloc(port, p->mem[0].size, 0, "vt6102") < 0){
  831. print("vt6102: port 0x%uX in use\n", port);
  832. continue;
  833. }
  834. ctlr = malloc(sizeof(Ctlr));
  835. ctlr->port = port;
  836. ctlr->pcidev = p;
  837. ctlr->id = (p->did<<16)|p->vid;
  838. if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
  839. cls = 0x10;
  840. ctlr->cls = cls*4;
  841. if(ctlr->cls < sizeof(Ds)){
  842. print("vt6102: cls %d < sizeof(Ds)\n", ctlr->cls);
  843. iofree(port);
  844. free(ctlr);
  845. continue;
  846. }
  847. ctlr->tft = Ctft64;
  848. if(vt6102reset(ctlr)){
  849. iofree(port);
  850. free(ctlr);
  851. continue;
  852. }
  853. pcisetbme(p);
  854. if(vt6102ctlrhead != nil)
  855. vt6102ctlrtail->next = ctlr;
  856. else
  857. vt6102ctlrhead = ctlr;
  858. vt6102ctlrtail = ctlr;
  859. }
  860. }
  861. static int
  862. vt6102pnp(Ether* edev)
  863. {
  864. Ctlr *ctlr;
  865. if(vt6102ctlrhead == nil)
  866. vt6102pci();
  867. /*
  868. * Any adapter matches if no edev->port is supplied,
  869. * otherwise the ports must match.
  870. */
  871. for(ctlr = vt6102ctlrhead; ctlr != nil; ctlr = ctlr->next){
  872. if(ctlr->active)
  873. continue;
  874. if(edev->port == 0 || edev->port == ctlr->port){
  875. ctlr->active = 1;
  876. break;
  877. }
  878. }
  879. if(ctlr == nil)
  880. return -1;
  881. edev->ctlr = ctlr;
  882. edev->port = ctlr->port;
  883. edev->irq = ctlr->pcidev->intl;
  884. edev->tbdf = ctlr->pcidev->tbdf;
  885. edev->mbps = 100;
  886. memmove(edev->ea, ctlr->par, Eaddrlen);
  887. /*
  888. * Linkage to the generic ethernet driver.
  889. */
  890. edev->attach = vt6102attach;
  891. edev->transmit = vt6102transmit;
  892. edev->interrupt = vt6102interrupt;
  893. edev->ifstat = vt6102ifstat;
  894. edev->ctl = nil;
  895. edev->arg = edev;
  896. edev->promiscuous = vt6102promiscuous;
  897. edev->multicast = vt6102multicast;
  898. return 0;
  899. }
  900. void
  901. ethervt6102link(void)
  902. {
  903. addethercard("vt6102", vt6102pnp);
  904. addethercard("rhine", vt6102pnp);
  905. }