ether8390.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. /*
  2. * National Semiconductor DP8390 and clone
  3. * Network Interface Controller.
  4. */
  5. #include "u.h"
  6. #include "lib.h"
  7. #include "mem.h"
  8. #include "dat.h"
  9. #include "fns.h"
  10. #include "io.h"
  11. #include "etherif.h"
  12. #include "ether8390.h"
  13. enum { /* NIC core registers */
  14. Cr = 0x00, /* command register, all pages */
  15. /* Page 0, read */
  16. Clda0 = 0x01, /* current local DMA address 0 */
  17. Clda1 = 0x02, /* current local DMA address 1 */
  18. Bnry = 0x03, /* boundary pointer (R/W) */
  19. Tsr = 0x04, /* transmit status register */
  20. Ncr = 0x05, /* number of collisions register */
  21. Fifo = 0x06, /* FIFO */
  22. Isr = 0x07, /* interrupt status register (R/W) */
  23. Crda0 = 0x08, /* current remote DMA address 0 */
  24. Crda1 = 0x09, /* current remote DMA address 1 */
  25. Rsr = 0x0C, /* receive status register */
  26. Cntr0 = 0x0D, /* frame alignment errors */
  27. Cntr1 = 0x0E, /* CRC errors */
  28. Cntr2 = 0x0F, /* missed packet errors */
  29. /* Page 0, write */
  30. Pstart = 0x01, /* page start register */
  31. Pstop = 0x02, /* page stop register */
  32. Tpsr = 0x04, /* transmit page start address */
  33. Tbcr0 = 0x05, /* transmit byte count register 0 */
  34. Tbcr1 = 0x06, /* transmit byte count register 1 */
  35. Rsar0 = 0x08, /* remote start address register 0 */
  36. Rsar1 = 0x09, /* remote start address register 1 */
  37. Rbcr0 = 0x0A, /* remote byte count register 0 */
  38. Rbcr1 = 0x0B, /* remote byte count register 1 */
  39. Rcr = 0x0C, /* receive configuration register */
  40. Tcr = 0x0D, /* transmit configuration register */
  41. Dcr = 0x0E, /* data configuration register */
  42. Imr = 0x0F, /* interrupt mask */
  43. /* Page 1, read/write */
  44. Par0 = 0x01, /* physical address register 0 */
  45. Curr = 0x07, /* current page register */
  46. Mar0 = 0x08, /* multicast address register 0 */
  47. };
  48. enum { /* Cr */
  49. Stp = 0x01, /* stop */
  50. Sta = 0x02, /* start */
  51. Txp = 0x04, /* transmit packet */
  52. Rd0 = 0x08, /* remote DMA command */
  53. Rd1 = 0x10,
  54. Rd2 = 0x20,
  55. RdREAD = Rd0, /* remote read */
  56. RdWRITE = Rd1, /* remote write */
  57. RdSEND = Rd1|Rd0, /* send packet */
  58. RdABORT = Rd2, /* abort/complete remote DMA */
  59. Ps0 = 0x40, /* page select */
  60. Ps1 = 0x80,
  61. Page0 = 0x00,
  62. Page1 = Ps0,
  63. Page2 = Ps1,
  64. };
  65. enum { /* Isr/Imr */
  66. Prx = 0x01, /* packet received */
  67. Ptx = 0x02, /* packet transmitted */
  68. Rxe = 0x04, /* receive error */
  69. Txe = 0x08, /* transmit error */
  70. Ovw = 0x10, /* overwrite warning */
  71. Cnt = 0x20, /* counter overflow */
  72. Rdc = 0x40, /* remote DMA complete */
  73. Rst = 0x80, /* reset status */
  74. };
  75. enum { /* Dcr */
  76. Wts = 0x01, /* word transfer select */
  77. Bos = 0x02, /* byte order select */
  78. Las = 0x04, /* long address select */
  79. Ls = 0x08, /* loopback select */
  80. Arm = 0x10, /* auto-initialise remote */
  81. Ft0 = 0x20, /* FIFO threshold select */
  82. Ft1 = 0x40,
  83. Ft1WORD = 0x00,
  84. Ft2WORD = Ft0,
  85. Ft4WORD = Ft1,
  86. Ft6WORD = Ft1|Ft0,
  87. };
  88. enum { /* Tcr */
  89. Crc = 0x01, /* inhibit CRC */
  90. Lb0 = 0x02, /* encoded loopback control */
  91. Lb1 = 0x04,
  92. LpbkNORMAL = 0x00, /* normal operation */
  93. LpbkNIC = Lb0, /* internal NIC module loopback */
  94. LpbkENDEC = Lb1, /* internal ENDEC module loopback */
  95. LpbkEXTERNAL = Lb1|Lb0, /* external loopback */
  96. Atd = 0x08, /* auto transmit disable */
  97. Ofst = 0x10, /* collision offset enable */
  98. };
  99. enum { /* Tsr */
  100. Ptxok = 0x01, /* packet transmitted */
  101. Col = 0x04, /* transmit collided */
  102. Abt = 0x08, /* tranmit aborted */
  103. Crs = 0x10, /* carrier sense lost */
  104. Fu = 0x20, /* FIFO underrun */
  105. Cdh = 0x40, /* CD heartbeat */
  106. Owc = 0x80, /* out of window collision */
  107. };
  108. enum { /* Rcr */
  109. Sep = 0x01, /* save errored packets */
  110. Ar = 0x02, /* accept runt packets */
  111. Ab = 0x04, /* accept broadcast */
  112. Am = 0x08, /* accept multicast */
  113. Pro = 0x10, /* promiscuous physical */
  114. Mon = 0x20, /* monitor mode */
  115. };
  116. enum { /* Rsr */
  117. Prxok = 0x01, /* packet received intact */
  118. Crce = 0x02, /* CRC error */
  119. Fae = 0x04, /* frame alignment error */
  120. Fo = 0x08, /* FIFO overrun */
  121. Mpa = 0x10, /* missed packet */
  122. Phy = 0x20, /* physical/multicast address */
  123. Dis = 0x40, /* receiver disabled */
  124. Dfr = 0x80, /* deferring */
  125. };
  126. typedef struct {
  127. uchar status;
  128. uchar next;
  129. uchar len0;
  130. uchar len1;
  131. } Hdr;
  132. void
  133. dp8390getea(Ether* ether, uchar* ea)
  134. {
  135. Dp8390 *ctlr;
  136. uchar cr;
  137. int i;
  138. ctlr = ether->ctlr;
  139. /*
  140. * Get the ethernet address from the chip.
  141. * Take care to restore the command register
  142. * afterwards.
  143. */
  144. ilock(ctlr);
  145. cr = regr(ctlr, Cr) & ~Txp;
  146. regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
  147. for(i = 0; i < Eaddrlen; i++)
  148. ea[i] = regr(ctlr, Par0+i);
  149. regw(ctlr, Cr, cr);
  150. iunlock(ctlr);
  151. }
  152. void
  153. dp8390setea(Ether* ether)
  154. {
  155. int i;
  156. uchar cr;
  157. Dp8390 *ctlr;
  158. ctlr = ether->ctlr;
  159. /*
  160. * Set the ethernet address into the chip.
  161. * Take care to restore the command register
  162. * afterwards. Don't care about multicast
  163. * addresses as multicast is never enabled
  164. * (currently).
  165. */
  166. ilock(ctlr);
  167. cr = regr(ctlr, Cr) & ~Txp;
  168. regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
  169. for(i = 0; i < Eaddrlen; i++)
  170. regw(ctlr, Par0+i, ether->ea[i]);
  171. regw(ctlr, Cr, cr);
  172. iunlock(ctlr);
  173. }
  174. static void*
  175. _dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len)
  176. {
  177. uchar cr;
  178. int timo;
  179. /*
  180. * Read some data at offset 'from' in the card's memory
  181. * using the DP8390 remote DMA facility, and place it at
  182. * 'to' in main memory, via the I/O data port.
  183. */
  184. cr = regr(ctlr, Cr) & ~Txp;
  185. regw(ctlr, Cr, Page0|RdABORT|Sta);
  186. regw(ctlr, Isr, Rdc);
  187. /*
  188. * Set up the remote DMA address and count.
  189. */
  190. len = ROUNDUP(len, ctlr->width);
  191. regw(ctlr, Rbcr0, len & 0xFF);
  192. regw(ctlr, Rbcr1, (len>>8) & 0xFF);
  193. regw(ctlr, Rsar0, from & 0xFF);
  194. regw(ctlr, Rsar1, (from>>8) & 0xFF);
  195. /*
  196. * Start the remote DMA read and suck the data
  197. * out of the I/O port.
  198. */
  199. regw(ctlr, Cr, Page0|RdREAD|Sta);
  200. rdread(ctlr, to, len);
  201. /*
  202. * Wait for the remote DMA to complete. The timeout
  203. * is necessary because this routine may be called on
  204. * a non-existent chip during initialisation and, due
  205. * to the miracles of the bus, it's possible to get this
  206. * far and still be talking to a slot full of nothing.
  207. */
  208. for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--)
  209. ;
  210. regw(ctlr, Isr, Rdc);
  211. regw(ctlr, Cr, cr);
  212. return to;
  213. }
  214. void*
  215. dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len)
  216. {
  217. void *v;
  218. ilock(ctlr);
  219. v = _dp8390read(ctlr, to, from, len);
  220. iunlock(ctlr);
  221. return v;
  222. }
  223. static void*
  224. dp8390write(Dp8390* ctlr, ulong to, void* from, ulong len)
  225. {
  226. ulong crda;
  227. uchar cr;
  228. int timo, width;
  229. /*
  230. * Write some data to offset 'to' in the card's memory
  231. * using the DP8390 remote DMA facility, reading it at
  232. * 'from' in main memory, via the I/O data port.
  233. */
  234. cr = regr(ctlr, Cr) & ~Txp;
  235. regw(ctlr, Cr, Page0|RdABORT|Sta);
  236. regw(ctlr, Isr, Rdc);
  237. len = ROUNDUP(len, ctlr->width);
  238. /*
  239. * Set up the remote DMA address and count.
  240. * This is straight from the DP8390[12D] datasheet,
  241. * hence the initial set up for read.
  242. * Assumption here that the A7000 EtherV card will
  243. * never need a dummyrr.
  244. */
  245. if(ctlr->dummyrr && (ctlr->width == 1 || ctlr->width == 2)){
  246. if(ctlr->width == 2)
  247. width = 1;
  248. else
  249. width = 0;
  250. crda = to-1-width;
  251. regw(ctlr, Rbcr0, (len+1+width) & 0xFF);
  252. regw(ctlr, Rbcr1, ((len+1+width)>>8) & 0xFF);
  253. regw(ctlr, Rsar0, crda & 0xFF);
  254. regw(ctlr, Rsar1, (crda>>8) & 0xFF);
  255. regw(ctlr, Cr, Page0|RdREAD|Sta);
  256. for(;;){
  257. crda = regr(ctlr, Crda0);
  258. crda |= regr(ctlr, Crda1)<<8;
  259. if(crda == to){
  260. /*
  261. * Start the remote DMA write and make sure
  262. * the registers are correct.
  263. */
  264. regw(ctlr, Cr, Page0|RdWRITE|Sta);
  265. crda = regr(ctlr, Crda0);
  266. crda |= regr(ctlr, Crda1)<<8;
  267. if(crda != to)
  268. panic("crda write %d to %d\n", crda, to);
  269. break;
  270. }
  271. }
  272. }
  273. else{
  274. regw(ctlr, Rsar0, to & 0xFF);
  275. regw(ctlr, Rsar1, (to>>8) & 0xFF);
  276. regw(ctlr, Rbcr0, len & 0xFF);
  277. regw(ctlr, Rbcr1, (len>>8) & 0xFF);
  278. regw(ctlr, Cr, Page0|RdWRITE|Sta);
  279. }
  280. /*
  281. * Pump the data into the I/O port
  282. * then wait for the remote DMA to finish.
  283. */
  284. rdwrite(ctlr, from, len);
  285. for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--)
  286. ;
  287. regw(ctlr, Isr, Rdc);
  288. regw(ctlr, Cr, cr);
  289. return (void*)to;
  290. }
  291. static void
  292. ringinit(Dp8390* ctlr)
  293. {
  294. regw(ctlr, Pstart, ctlr->pstart);
  295. regw(ctlr, Pstop, ctlr->pstop);
  296. regw(ctlr, Bnry, ctlr->pstop-1);
  297. regw(ctlr, Cr, Page1|RdABORT|Stp);
  298. regw(ctlr, Curr, ctlr->pstart);
  299. regw(ctlr, Cr, Page0|RdABORT|Stp);
  300. ctlr->nxtpkt = ctlr->pstart;
  301. }
  302. static uchar
  303. getcurr(Dp8390* ctlr)
  304. {
  305. uchar cr, curr;
  306. cr = regr(ctlr, Cr) & ~Txp;
  307. regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
  308. curr = regr(ctlr, Curr);
  309. regw(ctlr, Cr, cr);
  310. return curr;
  311. }
  312. static void
  313. receive(Ether* ether)
  314. {
  315. Dp8390 *ctlr;
  316. uchar curr, *p;
  317. Hdr hdr;
  318. ulong count, data, len;
  319. RingBuf *ring;
  320. ctlr = ether->ctlr;
  321. for(curr = getcurr(ctlr); ctlr->nxtpkt != curr; curr = getcurr(ctlr)){
  322. data = ctlr->nxtpkt*Dp8390BufSz;
  323. if(ctlr->ram)
  324. memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr));
  325. else
  326. _dp8390read(ctlr, &hdr, data, sizeof(Hdr));
  327. /*
  328. * Don't believe the upper byte count, work it
  329. * out from the software next-page pointer and
  330. * the current next-page pointer.
  331. */
  332. if(hdr.next > ctlr->nxtpkt)
  333. len = hdr.next - ctlr->nxtpkt - 1;
  334. else
  335. len = (ctlr->pstop-ctlr->nxtpkt) + (hdr.next-ctlr->pstart) - 1;
  336. if(hdr.len0 > (Dp8390BufSz-sizeof(Hdr)))
  337. len--;
  338. len = ((len<<8)|hdr.len0)-4;
  339. /*
  340. * Chip is badly scrogged, reinitialise the ring.
  341. */
  342. if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop
  343. || len < 60 || len > sizeof(Etherpkt)){
  344. print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%lud\n",
  345. hdr.status, hdr.next, hdr.len0, hdr.len1, len);
  346. regw(ctlr, Cr, Page0|RdABORT|Stp);
  347. ringinit(ctlr);
  348. regw(ctlr, Cr, Page0|RdABORT|Sta);
  349. return;
  350. }
  351. /*
  352. * If it's a good packet read it in to the software buffer.
  353. * If the packet wraps round the hardware ring, read it in
  354. * two pieces.
  355. */
  356. ring = &ether->rb[ether->ri];
  357. if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok && ring->owner == Interface){
  358. p = ring->pkt;
  359. ring->len = len;
  360. data += sizeof(Hdr);
  361. if((data+len) >= ctlr->pstop*Dp8390BufSz){
  362. count = ctlr->pstop*Dp8390BufSz - data;
  363. if(ctlr->ram)
  364. memmove(p, (void*)(ether->mem+data), count);
  365. else
  366. _dp8390read(ctlr, p, data, count);
  367. p += count;
  368. data = ctlr->pstart*Dp8390BufSz;
  369. len -= count;
  370. }
  371. if(len){
  372. if(ctlr->ram)
  373. memmove(p, (void*)(ether->mem+data), len);
  374. else
  375. _dp8390read(ctlr, p, data, len);
  376. }
  377. /*
  378. * Copy the packet to whoever wants it.
  379. */
  380. ring->owner = Host;
  381. ether->ri = NEXT(ether->ri, ether->nrb);
  382. }
  383. /*
  384. * Finished with this packet, update the
  385. * hardware and software ring pointers.
  386. */
  387. ctlr->nxtpkt = hdr.next;
  388. hdr.next--;
  389. if(hdr.next < ctlr->pstart)
  390. hdr.next = ctlr->pstop-1;
  391. regw(ctlr, Bnry, hdr.next);
  392. }
  393. }
  394. static void
  395. txstart(Ether* ether)
  396. {
  397. int len;
  398. Dp8390 *ctlr;
  399. RingBuf *ring;
  400. uchar minpkt[ETHERMINTU], *rp;
  401. ctlr = ether->ctlr;
  402. /*
  403. * This routine is called both from the top level and from interrupt
  404. * level and expects to be called with ctlr already locked.
  405. */
  406. if(ether->tbusy)
  407. return;
  408. ring = &ether->tb[ether->ti];
  409. if(ring->owner != Interface)
  410. return;
  411. /*
  412. * Make sure the packet is of minimum length;
  413. * copy it to the card's memory by the appropriate means;
  414. * start the transmission.
  415. */
  416. len = ring->len;
  417. rp = ring->pkt;
  418. if(len < ETHERMINTU){
  419. rp = minpkt;
  420. memmove(rp, ring->pkt, len);
  421. memset(rp+len, 0, ETHERMINTU-len);
  422. len = ETHERMINTU;
  423. }
  424. if(ctlr->ram)
  425. memmove((void*)(ether->mem+ctlr->tstart*Dp8390BufSz), rp, len);
  426. else
  427. dp8390write(ctlr, ctlr->tstart*Dp8390BufSz, rp, len);
  428. regw(ctlr, Tbcr0, len & 0xFF);
  429. regw(ctlr, Tbcr1, (len>>8) & 0xFF);
  430. regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
  431. ether->tbusy = 1;
  432. }
  433. static void
  434. transmit(Ether* ether)
  435. {
  436. Dp8390 *ctlr;
  437. ctlr = ether->ctlr;
  438. ilock(ctlr);
  439. txstart(ether);
  440. iunlock(ctlr);
  441. }
  442. static void
  443. overflow(Ether *ether)
  444. {
  445. Dp8390 *ctlr;
  446. uchar txp;
  447. int resend;
  448. ctlr = ether->ctlr;
  449. /*
  450. * The following procedure is taken from the DP8390[12D] datasheet,
  451. * it seems pretty adamant that this is what has to be done.
  452. */
  453. txp = regr(ctlr, Cr) & Txp;
  454. regw(ctlr, Cr, Page0|RdABORT|Stp);
  455. delay(2);
  456. regw(ctlr, Rbcr0, 0);
  457. regw(ctlr, Rbcr1, 0);
  458. resend = 0;
  459. if(txp && (regr(ctlr, Isr) & (Txe|Ptx)) == 0)
  460. resend = 1;
  461. regw(ctlr, Tcr, LpbkNIC);
  462. regw(ctlr, Cr, Page0|RdABORT|Sta);
  463. receive(ether);
  464. regw(ctlr, Isr, Ovw);
  465. regw(ctlr, Tcr, LpbkNORMAL);
  466. if(resend)
  467. regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
  468. }
  469. static void
  470. interrupt(Ureg*, void* arg)
  471. {
  472. Ether *ether;
  473. Dp8390 *ctlr;
  474. RingBuf *ring;
  475. uchar isr, r;
  476. ether = arg;
  477. ctlr = ether->ctlr;
  478. /*
  479. * While there is something of interest,
  480. * clear all the interrupts and process.
  481. */
  482. ilock(ctlr);
  483. regw(ctlr, Imr, 0x00);
  484. while(isr = (regr(ctlr, Isr) & (Cnt|Ovw|Txe|Rxe|Ptx|Prx))){
  485. if(isr & Ovw){
  486. overflow(ether);
  487. regw(ctlr, Isr, Ovw);
  488. }
  489. /*
  490. * Packets have been received.
  491. * Take a spin round the ring.
  492. */
  493. if(isr & (Rxe|Prx)){
  494. receive(ether);
  495. regw(ctlr, Isr, Rxe|Prx);
  496. }
  497. /*
  498. * A packet completed transmission, successfully or
  499. * not. Start transmission on the next buffered packet,
  500. * and wake the output routine.
  501. */
  502. if(isr & (Txe|Ptx)){
  503. r = regr(ctlr, Tsr);
  504. if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){
  505. print("dp8390: Tsr#%2.2ux|", r);
  506. }
  507. regw(ctlr, Isr, Txe|Ptx);
  508. ring = &ether->tb[ether->ti];
  509. ring->owner = Host;
  510. ether->ti = NEXT(ether->ti, ether->ntb);
  511. ether->tbusy = 0;
  512. txstart(ether);
  513. }
  514. if(isr & Cnt){
  515. regr(ctlr, Cntr0);
  516. regr(ctlr, Cntr1);
  517. regr(ctlr, Cntr2);
  518. regw(ctlr, Isr, Cnt);
  519. }
  520. }
  521. regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
  522. iunlock(ctlr);
  523. }
  524. static void
  525. attach(Ether* ether)
  526. {
  527. Dp8390 *ctlr;
  528. uchar r;
  529. ctlr = ether->ctlr;
  530. /*
  531. * Enable the chip for transmit/receive.
  532. * The init routine leaves the chip in monitor
  533. * mode. Clear the missed-packet counter, it
  534. * increments while in monitor mode.
  535. * Sometimes there's an interrupt pending at this
  536. * point but there's nothing in the Isr, so
  537. * any pending interrupts are cleared and the
  538. * mask of acceptable interrupts is enabled here.
  539. */
  540. r = Ab;
  541. ilock(ctlr);
  542. regw(ctlr, Isr, 0xFF);
  543. regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
  544. regw(ctlr, Rcr, r);
  545. r = regr(ctlr, Cntr2);
  546. regw(ctlr, Tcr, LpbkNORMAL);
  547. iunlock(ctlr);
  548. USED(r);
  549. }
  550. static void
  551. detach(Ether* ether)
  552. {
  553. int timo;
  554. Dp8390 *ctlr;
  555. /*
  556. * Stop the chip. Set the Stp bit and wait for the chip
  557. * to finish whatever was on its tiny mind before it sets
  558. * the Rst bit.
  559. * The timeout is needed because there may not be a real
  560. * chip there if this is called when probing for a device
  561. * at boot.
  562. */
  563. ctlr = ether->ctlr;
  564. regw(ctlr, Cr, Page0|RdABORT|Stp);
  565. regw(ctlr, Rbcr0, 0);
  566. regw(ctlr, Rbcr1, 0);
  567. for(timo = 10000; (regr(ctlr, Isr) & Rst) == 0 && timo; timo--)
  568. ;
  569. }
  570. int
  571. dp8390reset(Ether* ether)
  572. {
  573. Dp8390 *ctlr;
  574. ctlr = ether->ctlr;
  575. /*
  576. * This is the initialisation procedure described
  577. * as 'mandatory' in the datasheet, with references
  578. * to the 3C503 technical reference manual.
  579. */
  580. detach(ether);
  581. if(ctlr->width != 1)
  582. regw(ctlr, Dcr, Ft4WORD|Ls|Wts);
  583. else
  584. regw(ctlr, Dcr, Ft4WORD|Ls);
  585. regw(ctlr, Rbcr0, 0);
  586. regw(ctlr, Rbcr1, 0);
  587. regw(ctlr, Tcr, LpbkNIC);
  588. regw(ctlr, Rcr, Mon);
  589. /*
  590. * Init the ring hardware and software ring pointers.
  591. * Can't initialise ethernet address as it may not be
  592. * known yet.
  593. */
  594. ringinit(ctlr);
  595. regw(ctlr, Tpsr, ctlr->tstart);
  596. /*
  597. * Clear any pending interrupts and mask then all off.
  598. */
  599. regw(ctlr, Isr, 0xFF);
  600. regw(ctlr, Imr, 0);
  601. /*
  602. * Leave the chip initialised,
  603. * but in monitor mode.
  604. */
  605. regw(ctlr, Cr, Page0|RdABORT|Sta);
  606. /*
  607. * Set up the software configuration.
  608. */
  609. ether->attach = attach;
  610. ether->transmit = transmit;
  611. ether->interrupt = interrupt;
  612. ether->detach = detach;
  613. return 0;
  614. }