ether8390.c 17 KB

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