ether8390.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  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. top:
  230. /*
  231. * Write some data to offset 'to' in the card's memory
  232. * using the DP8390 remote DMA facility, reading it at
  233. * 'from' in main memory, via the I/O data port.
  234. */
  235. cr = regr(ctlr, Cr) & ~Txp;
  236. regw(ctlr, Cr, Page0|RdABORT|Sta);
  237. regw(ctlr, Isr, Rdc);
  238. len = ROUNDUP(len, ctlr->width);
  239. /*
  240. * Set up the remote DMA address and count.
  241. * This is straight from the DP8390[12D] datasheet,
  242. * hence the initial set up for read.
  243. * Assumption here that the A7000 EtherV card will
  244. * never need a dummyrr.
  245. */
  246. if(ctlr->dummyrr && (ctlr->width == 1 || ctlr->width == 2)){
  247. if(ctlr->width == 2)
  248. width = 1;
  249. else
  250. width = 0;
  251. crda = to-1-width;
  252. regw(ctlr, Rbcr0, (len+1+width) & 0xFF);
  253. regw(ctlr, Rbcr1, ((len+1+width)>>8) & 0xFF);
  254. regw(ctlr, Rsar0, crda & 0xFF);
  255. regw(ctlr, Rsar1, (crda>>8) & 0xFF);
  256. regw(ctlr, Cr, Page0|RdREAD|Sta);
  257. for(timo=0;; timo++){
  258. if(timo > 10000){
  259. print("ether8390: dummyrr timeout; assuming nodummyrr\n");
  260. ctlr->dummyrr = 0;
  261. goto top;
  262. }
  263. crda = regr(ctlr, Crda0);
  264. crda |= regr(ctlr, Crda1)<<8;
  265. if(crda == to){
  266. /*
  267. * Start the remote DMA write and make sure
  268. * the registers are correct.
  269. */
  270. regw(ctlr, Cr, Page0|RdWRITE|Sta);
  271. crda = regr(ctlr, Crda0);
  272. crda |= regr(ctlr, Crda1)<<8;
  273. if(crda != to)
  274. panic("crda write %d to %d\n", crda, to);
  275. break;
  276. }
  277. }
  278. }
  279. else{
  280. regw(ctlr, Rsar0, to & 0xFF);
  281. regw(ctlr, Rsar1, (to>>8) & 0xFF);
  282. regw(ctlr, Rbcr0, len & 0xFF);
  283. regw(ctlr, Rbcr1, (len>>8) & 0xFF);
  284. regw(ctlr, Cr, Page0|RdWRITE|Sta);
  285. }
  286. /*
  287. * Pump the data into the I/O port
  288. * then wait for the remote DMA to finish.
  289. */
  290. rdwrite(ctlr, from, len);
  291. for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--)
  292. ;
  293. regw(ctlr, Isr, Rdc);
  294. regw(ctlr, Cr, cr);
  295. return (void*)to;
  296. }
  297. static void
  298. ringinit(Dp8390* ctlr)
  299. {
  300. regw(ctlr, Pstart, ctlr->pstart);
  301. regw(ctlr, Pstop, ctlr->pstop);
  302. regw(ctlr, Bnry, ctlr->pstop-1);
  303. regw(ctlr, Cr, Page1|RdABORT|Stp);
  304. regw(ctlr, Curr, ctlr->pstart);
  305. regw(ctlr, Cr, Page0|RdABORT|Stp);
  306. ctlr->nxtpkt = ctlr->pstart;
  307. }
  308. static uchar
  309. getcurr(Dp8390* ctlr)
  310. {
  311. uchar cr, curr;
  312. cr = regr(ctlr, Cr) & ~Txp;
  313. regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
  314. curr = regr(ctlr, Curr);
  315. regw(ctlr, Cr, cr);
  316. return curr;
  317. }
  318. static void
  319. receive(Ether* ether)
  320. {
  321. Dp8390 *ctlr;
  322. uchar curr, *p;
  323. Hdr hdr;
  324. ulong count, data, len;
  325. RingBuf *ring;
  326. ctlr = ether->ctlr;
  327. for(curr = getcurr(ctlr); ctlr->nxtpkt != curr; curr = getcurr(ctlr)){
  328. data = ctlr->nxtpkt*Dp8390BufSz;
  329. if(ctlr->ram)
  330. memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr));
  331. else
  332. _dp8390read(ctlr, &hdr, data, sizeof(Hdr));
  333. /*
  334. * Don't believe the upper byte count, work it
  335. * out from the software next-page pointer and
  336. * the current next-page pointer.
  337. */
  338. if(hdr.next > ctlr->nxtpkt)
  339. len = hdr.next - ctlr->nxtpkt - 1;
  340. else
  341. len = (ctlr->pstop-ctlr->nxtpkt) + (hdr.next-ctlr->pstart) - 1;
  342. if(hdr.len0 > (Dp8390BufSz-sizeof(Hdr)))
  343. len--;
  344. len = ((len<<8)|hdr.len0)-4;
  345. /*
  346. * Chip is badly scrogged, reinitialise the ring.
  347. */
  348. if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop
  349. || len < 60 || len > sizeof(Etherpkt)){
  350. print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%lud\n",
  351. hdr.status, hdr.next, hdr.len0, hdr.len1, len);
  352. regw(ctlr, Cr, Page0|RdABORT|Stp);
  353. ringinit(ctlr);
  354. regw(ctlr, Cr, Page0|RdABORT|Sta);
  355. return;
  356. }
  357. /*
  358. * If it's a good packet read it in to the software buffer.
  359. * If the packet wraps round the hardware ring, read it in
  360. * two pieces.
  361. */
  362. ring = &ether->rb[ether->ri];
  363. if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok && ring->owner == Interface){
  364. p = ring->pkt;
  365. ring->len = len;
  366. data += sizeof(Hdr);
  367. if((data+len) >= ctlr->pstop*Dp8390BufSz){
  368. count = ctlr->pstop*Dp8390BufSz - data;
  369. if(ctlr->ram)
  370. memmove(p, (void*)(ether->mem+data), count);
  371. else
  372. _dp8390read(ctlr, p, data, count);
  373. p += count;
  374. data = ctlr->pstart*Dp8390BufSz;
  375. len -= count;
  376. }
  377. if(len){
  378. if(ctlr->ram)
  379. memmove(p, (void*)(ether->mem+data), len);
  380. else
  381. _dp8390read(ctlr, p, data, len);
  382. }
  383. /*
  384. * Copy the packet to whoever wants it.
  385. */
  386. ring->owner = Host;
  387. ether->ri = NEXT(ether->ri, ether->nrb);
  388. }
  389. /*
  390. * Finished with this packet, update the
  391. * hardware and software ring pointers.
  392. */
  393. ctlr->nxtpkt = hdr.next;
  394. hdr.next--;
  395. if(hdr.next < ctlr->pstart)
  396. hdr.next = ctlr->pstop-1;
  397. regw(ctlr, Bnry, hdr.next);
  398. }
  399. }
  400. static void
  401. txstart(Ether* ether)
  402. {
  403. int len;
  404. Dp8390 *ctlr;
  405. RingBuf *ring;
  406. uchar minpkt[ETHERMINTU], *rp;
  407. ctlr = ether->ctlr;
  408. /*
  409. * This routine is called both from the top level and from interrupt
  410. * level and expects to be called with ctlr already locked.
  411. */
  412. if(ether->tbusy)
  413. return;
  414. ring = &ether->tb[ether->ti];
  415. if(ring->owner != Interface)
  416. return;
  417. /*
  418. * Make sure the packet is of minimum length;
  419. * copy it to the card's memory by the appropriate means;
  420. * start the transmission.
  421. */
  422. len = ring->len;
  423. rp = ring->pkt;
  424. if(len < ETHERMINTU){
  425. rp = minpkt;
  426. memmove(rp, ring->pkt, len);
  427. memset(rp+len, 0, ETHERMINTU-len);
  428. len = ETHERMINTU;
  429. }
  430. if(ctlr->ram)
  431. memmove((void*)(ether->mem+ctlr->tstart*Dp8390BufSz), rp, len);
  432. else
  433. dp8390write(ctlr, ctlr->tstart*Dp8390BufSz, rp, len);
  434. regw(ctlr, Tbcr0, len & 0xFF);
  435. regw(ctlr, Tbcr1, (len>>8) & 0xFF);
  436. regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
  437. ether->tbusy = 1;
  438. }
  439. static void
  440. transmit(Ether* ether)
  441. {
  442. Dp8390 *ctlr;
  443. ctlr = ether->ctlr;
  444. ilock(ctlr);
  445. txstart(ether);
  446. iunlock(ctlr);
  447. }
  448. static void
  449. overflow(Ether *ether)
  450. {
  451. Dp8390 *ctlr;
  452. uchar txp;
  453. int resend;
  454. ctlr = ether->ctlr;
  455. /*
  456. * The following procedure is taken from the DP8390[12D] datasheet,
  457. * it seems pretty adamant that this is what has to be done.
  458. */
  459. txp = regr(ctlr, Cr) & Txp;
  460. regw(ctlr, Cr, Page0|RdABORT|Stp);
  461. delay(2);
  462. regw(ctlr, Rbcr0, 0);
  463. regw(ctlr, Rbcr1, 0);
  464. resend = 0;
  465. if(txp && (regr(ctlr, Isr) & (Txe|Ptx)) == 0)
  466. resend = 1;
  467. regw(ctlr, Tcr, LpbkNIC);
  468. regw(ctlr, Cr, Page0|RdABORT|Sta);
  469. receive(ether);
  470. regw(ctlr, Isr, Ovw);
  471. regw(ctlr, Tcr, LpbkNORMAL);
  472. if(resend)
  473. regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);
  474. }
  475. static void
  476. interrupt(Ureg*, void* arg)
  477. {
  478. Ether *ether;
  479. Dp8390 *ctlr;
  480. RingBuf *ring;
  481. uchar isr, r;
  482. ether = arg;
  483. ctlr = ether->ctlr;
  484. /*
  485. * While there is something of interest,
  486. * clear all the interrupts and process.
  487. */
  488. ilock(ctlr);
  489. regw(ctlr, Imr, 0x00);
  490. while(isr = (regr(ctlr, Isr) & (Cnt|Ovw|Txe|Rxe|Ptx|Prx))){
  491. if(isr & Ovw){
  492. overflow(ether);
  493. regw(ctlr, Isr, Ovw);
  494. }
  495. /*
  496. * Packets have been received.
  497. * Take a spin round the ring.
  498. */
  499. if(isr & (Rxe|Prx)){
  500. receive(ether);
  501. regw(ctlr, Isr, Rxe|Prx);
  502. }
  503. /*
  504. * A packet completed transmission, successfully or
  505. * not. Start transmission on the next buffered packet,
  506. * and wake the output routine.
  507. */
  508. if(isr & (Txe|Ptx)){
  509. r = regr(ctlr, Tsr);
  510. if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){
  511. print("dp8390: Tsr#%2.2ux|", r);
  512. }
  513. regw(ctlr, Isr, Txe|Ptx);
  514. ring = &ether->tb[ether->ti];
  515. ring->owner = Host;
  516. ether->ti = NEXT(ether->ti, ether->ntb);
  517. ether->tbusy = 0;
  518. txstart(ether);
  519. }
  520. if(isr & Cnt){
  521. regr(ctlr, Cntr0);
  522. regr(ctlr, Cntr1);
  523. regr(ctlr, Cntr2);
  524. regw(ctlr, Isr, Cnt);
  525. }
  526. }
  527. regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
  528. iunlock(ctlr);
  529. }
  530. static void
  531. attach(Ether* ether)
  532. {
  533. Dp8390 *ctlr;
  534. uchar r;
  535. ctlr = ether->ctlr;
  536. /*
  537. * Enable the chip for transmit/receive.
  538. * The init routine leaves the chip in monitor
  539. * mode. Clear the missed-packet counter, it
  540. * increments while in monitor mode.
  541. * Sometimes there's an interrupt pending at this
  542. * point but there's nothing in the Isr, so
  543. * any pending interrupts are cleared and the
  544. * mask of acceptable interrupts is enabled here.
  545. */
  546. r = Ab;
  547. ilock(ctlr);
  548. regw(ctlr, Isr, 0xFF);
  549. regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
  550. regw(ctlr, Rcr, r);
  551. r = regr(ctlr, Cntr2);
  552. regw(ctlr, Tcr, LpbkNORMAL);
  553. iunlock(ctlr);
  554. USED(r);
  555. }
  556. static void
  557. detach(Ether* ether)
  558. {
  559. int timo;
  560. Dp8390 *ctlr;
  561. /*
  562. * Stop the chip. Set the Stp bit and wait for the chip
  563. * to finish whatever was on its tiny mind before it sets
  564. * the Rst bit.
  565. * The timeout is needed because there may not be a real
  566. * chip there if this is called when probing for a device
  567. * at boot.
  568. */
  569. ctlr = ether->ctlr;
  570. regw(ctlr, Cr, Page0|RdABORT|Stp);
  571. regw(ctlr, Rbcr0, 0);
  572. regw(ctlr, Rbcr1, 0);
  573. for(timo = 10000; (regr(ctlr, Isr) & Rst) == 0 && timo; timo--)
  574. ;
  575. }
  576. int
  577. dp8390reset(Ether* ether)
  578. {
  579. Dp8390 *ctlr;
  580. ctlr = ether->ctlr;
  581. /*
  582. * This is the initialisation procedure described
  583. * as 'mandatory' in the datasheet, with references
  584. * to the 3C503 technical reference manual.
  585. */
  586. detach(ether);
  587. if(ctlr->width != 1)
  588. regw(ctlr, Dcr, Ft4WORD|Ls|Wts);
  589. else
  590. regw(ctlr, Dcr, Ft4WORD|Ls);
  591. regw(ctlr, Rbcr0, 0);
  592. regw(ctlr, Rbcr1, 0);
  593. regw(ctlr, Tcr, LpbkNIC);
  594. regw(ctlr, Rcr, Mon);
  595. /*
  596. * Init the ring hardware and software ring pointers.
  597. * Can't initialise ethernet address as it may not be
  598. * known yet.
  599. */
  600. ringinit(ctlr);
  601. regw(ctlr, Tpsr, ctlr->tstart);
  602. /*
  603. * Clear any pending interrupts and mask then all off.
  604. */
  605. regw(ctlr, Isr, 0xFF);
  606. regw(ctlr, Imr, 0);
  607. /*
  608. * Leave the chip initialised,
  609. * but in monitor mode.
  610. */
  611. regw(ctlr, Cr, Page0|RdABORT|Sta);
  612. /*
  613. * Set up the software configuration.
  614. */
  615. ether->attach = attach;
  616. ether->transmit = transmit;
  617. ether->interrupt = interrupt;
  618. ether->detach = detach;
  619. return 0;
  620. }