ether9221.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. /*
  2. * SMSC 9221 Ethernet driver
  3. * specifically for the ISEE IGEPv2 board,
  4. * where it is assigned to Chip Select 5,
  5. * its registers are at 0x2c000000 (inherited from u-boot),
  6. * and irq is 34 from gpio pin 176, thus gpio module 6.
  7. *
  8. * it's slow due to the use of fifos instead of buffer rings.
  9. * the slow system dma just makes it worse.
  10. *
  11. * igepv2 u-boot uses pin 64 on gpio 3 as an output pin to reset the 9221.
  12. */
  13. #include "u.h"
  14. #include "../port/lib.h"
  15. #include "mem.h"
  16. #include "dat.h"
  17. #include "fns.h"
  18. #include "io.h"
  19. #include "../port/error.h"
  20. #include "../port/netif.h"
  21. #include "etherif.h"
  22. /* currently using kprocs is a lot slower than not (87 s. to boot vs 60) */
  23. #undef USE_KPROCS
  24. enum {
  25. Vid9221 = 0x9221,
  26. Slop = 4, /* beyond ETHERMAXTU */
  27. };
  28. typedef struct Regs Regs;
  29. struct Regs {
  30. /* fifo ports */
  31. ulong rxdata;
  32. uchar _pad0[0x20 - 4];
  33. ulong txdata;
  34. uchar _pad1[0x40 - 0x24];
  35. ulong rxsts;
  36. ulong rxstspeek;
  37. ulong txsts;
  38. ulong txstspeek;
  39. /* control & status */
  40. ushort rev; /* chip revision */
  41. ushort id; /* chip id, 0x9221 */
  42. ulong irqcfg;
  43. ulong intsts;
  44. ulong inten;
  45. ulong _pad2;
  46. ulong bytetest;
  47. ulong fifoint; /* fifo level interrupts */
  48. ulong rxcfg;
  49. ulong txcfg;
  50. ulong hwcfg;
  51. ulong rxdpctl; /* rx data path control */
  52. ulong rxfifoinf;
  53. ulong txfifoinf;
  54. ulong pmtctl; /* power mgmt. control */
  55. ulong gpiocfg;
  56. ulong gptcfg; /* timer */
  57. ulong gptcnt;
  58. ulong _pad3;
  59. ulong wordswap;
  60. ulong freerun; /* counters */
  61. ulong rxdrop;
  62. /*
  63. * mac registers are accessed indirectly via the mac csr registers.
  64. * phy registers are doubly indirect, via the mac csr mii_acc &
  65. * mii_data mac csr registers.
  66. */
  67. ulong maccsrcmd; /* mac csr synchronizer */
  68. ulong maccsrdata;
  69. ulong afccfg; /* automatic flow control cfg. */
  70. ulong eepcmd; /* eeprom */
  71. ulong eepdata;
  72. /* 0xb8 */
  73. };
  74. enum {
  75. Nstatistics = 128,
  76. };
  77. enum {
  78. /* txcmda bits */
  79. Intcompl = 1<<31,
  80. Bufendalign = 3<<24, /* mask */
  81. Datastoff = 037<<16, /* mask */
  82. Firstseg = 1<<13,
  83. Lastseg = 1<<12,
  84. Bufsize = MASK(11),
  85. /* txcmdb bits */
  86. Pkttag = MASK(16) << 16,
  87. Txcksumen = 1<<14,
  88. Addcrcdis = 1<<13,
  89. Framepaddis = 1<<12,
  90. Pktlen = (1<<1) - 1, /* mask */
  91. /* txcfg bits */
  92. Txsdump = 1<<15, /* flush tx status fifo */
  93. Txddump = 1<<14, /* flush tx data fifo */
  94. Txon = 1<<1,
  95. Stoptx = 1<<0,
  96. /* hwcfg bits */
  97. Mbo = 1<<20, /* must be one */
  98. Srstto = 1<<1, /* soft reset time-out */
  99. Srst = 1<<0,
  100. /* rxcfg bits */
  101. Rxdmacntshift = 16, /* ulong count, 12 bits wide */
  102. Rxdmacntmask = MASK(12) << Rxdmacntshift,
  103. Rxdump = 1<<15, /* flush rx fifos */
  104. /* rxsts bits */
  105. Rxpktlenshift = 16, /* byte count */
  106. Rxpktlenmask = MASK(14) << Rxpktlenshift,
  107. Rxerr = 1<<15,
  108. /* rxfifoinf bits */
  109. Rxstsusedshift = 16, /* ulong count */
  110. Rxstsusedmask = MASK(8) << Rxstsusedshift,
  111. Rxdatausedmask = MASK(16), /* byte count */
  112. /* txfifoinf bits */
  113. Txstsusedshift = 16, /* ulong count */
  114. Txstsusedmask = MASK(8) << Txstsusedshift,
  115. Txdatafreemask = MASK(16), /* byte count */
  116. /* pmtctl bits */
  117. Dready = 1<<0,
  118. /* maccsrcmd bits */
  119. Csrbusy = 1<<31,
  120. Csrread = 1<<30, /* not write */
  121. Csraddrshift = 0,
  122. Csraddrmask = MASK(8) - 1,
  123. /* mac registers' indices */
  124. Maccr = 1,
  125. Macaddrh,
  126. Macaddrl,
  127. Machashh,
  128. Machashl,
  129. Macmiiacc, /* for doubly-indirect phy access */
  130. Macmiidata,
  131. Macflow,
  132. Macvlan1,
  133. Macvlan2,
  134. Macwuff,
  135. Macwucsr,
  136. Maccoe,
  137. /* Maccr bits */
  138. Rxall = 1<<31,
  139. Rcvown = 1<<23, /* don't receive own transmissions */
  140. Fdpx = 1<<20, /* full duplex */
  141. Mcpas = 1<<19, /* pass all multicast */
  142. Prms = 1<<18, /* promiscuous */
  143. Ho = 1<<15, /* hash-only filtering */
  144. Hpfilt = 1<<13, /* hash/perfect filtering */
  145. Padstr = 1<<8, /* strip padding & fcs (crc) */
  146. Txen = 1<<3,
  147. Rxen = 1<<2,
  148. /* irqcfg bits */
  149. Irqdeasclr = 1<<14, /* deassertion intv'l clear */
  150. Irqdeassts = 1<<13, /* deassertion intv'l status */
  151. Irqint = 1<<12, /* intr being asserted? (ro) */
  152. Irqen = 1<<8,
  153. Irqpol = 1<<4, /* irq output is active high */
  154. Irqpushpull = 1<<0, /* irq output is push/pull driver */
  155. /* intsts/inten bits */
  156. Swint = 1<<31, /* generate an interrupt */
  157. Txstop = 1<<25,
  158. Rxstop = 1<<24,
  159. Txioc = 1<<21,
  160. Rxdma = 1<<20,
  161. Gptimer = 1<<19,
  162. Phy = 1<<18,
  163. Rxe = 1<<14, /* errors */
  164. Txe = 1<<13,
  165. Tdfo = 1<<10, /* tx data fifo overrun */
  166. Tdfa = 1<<9, /* tx data fifo available */
  167. Tsff = 1<<8, /* tx status fifo full */
  168. Tsfl = 1<<7, /* tx status fifo level */
  169. Rsff = 1<<4, /* rx status fifo full */
  170. Rsfl = 1<<3, /* rx status fifo level */
  171. /* eepcmd bits */
  172. Epcbusy = 1<<31,
  173. Epccmdshift = 28, /* interesting one is Reload (7) */
  174. Epctimeout = 1<<9,
  175. Epcmacloaded = 1<<8,
  176. Epcaddrshift = 0,
  177. };
  178. enum {
  179. Rxintrs = Rsff | Rsfl | Rxe,
  180. Txintrs = Tsff | Tsfl | Txe | Txioc,
  181. };
  182. /* wake-up frame filter */
  183. struct Wakeup {
  184. ulong bytemask[4]; /* index is filter # */
  185. uchar filt0cmd; /* filter 0 command */
  186. uchar _pad0;
  187. uchar filt1cmd;
  188. uchar _pad1;
  189. uchar filt2cmd;
  190. uchar _pad2;
  191. uchar filt3cmd;
  192. uchar _pad3;
  193. uchar offset[4]; /* index is filter # */
  194. ushort crc16[4]; /* " */
  195. };
  196. typedef struct Ctlr Ctlr;
  197. struct Ctlr {
  198. int port;
  199. Ctlr* next;
  200. Ether* edev;
  201. Regs* regs;
  202. int active;
  203. int started;
  204. int inited;
  205. int id;
  206. int cls;
  207. ushort eeprom[0x40];
  208. QLock alock; /* attach */
  209. int nrb; /* how many this Ctlr has in the pool */
  210. int* nic;
  211. Lock imlock;
  212. int im; /* interrupt mask */
  213. // Mii* mii;
  214. // Rendez lrendez;
  215. int lim;
  216. int link;
  217. QLock slock;
  218. uint statistics[Nstatistics];
  219. uint lsleep;
  220. uint lintr;
  221. uint rsleep;
  222. uint rintr;
  223. int tsleep;
  224. uint tintr;
  225. uchar ra[Eaddrlen]; /* receive address */
  226. ulong mta[128]; /* multicast table array */
  227. Rendez rrendez;
  228. int gotinput;
  229. int rdcpydone;
  230. Rendez trendez;
  231. int gotoutput;
  232. int wrcpydone;
  233. Lock tlock;
  234. };
  235. #define csr32r(c, r) (*((c)->nic+((r)/4)))
  236. #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
  237. static Ctlr *smcctlrhead, *smcctlrtail;
  238. static char* statistics[Nstatistics] = { "dummy", };
  239. static uchar mymac[] = { 0xb0, 0x0f, 0xba, 0xbe, 0x00, 0x00, };
  240. static void etherclock(void);
  241. static void smcreceive(Ether *edev);
  242. static void smcinterrupt(Ureg*, void* arg);
  243. static Ether *thisether;
  244. static int attached;
  245. static void
  246. smconce(Ether *edev)
  247. {
  248. static int beenhere;
  249. static Lock l;
  250. ilock(&l);
  251. if (!beenhere && edev != nil) {
  252. beenhere = 1;
  253. /* simulate interrupts if we don't know the irq */
  254. if (edev->irq < 0) { /* poll as backup */
  255. thisether = edev;
  256. addclock0link(etherclock, 1000/HZ);
  257. iprint(" polling");
  258. }
  259. }
  260. iunlock(&l);
  261. }
  262. /*
  263. * indirect (mac) register access
  264. */
  265. static void
  266. macwait(Regs *regs)
  267. {
  268. long bound;
  269. for (bound = 400*Mhz; regs->maccsrcmd & Csrbusy && bound > 0; bound--)
  270. ;
  271. if (bound <= 0)
  272. iprint("smc: mac registers didn't come ready\n");
  273. }
  274. static ulong
  275. macrd(Regs *regs, uchar index)
  276. {
  277. macwait(regs);
  278. regs->maccsrcmd = Csrbusy | Csrread | index;
  279. coherence(); /* back-to-back write/read delay per §6.2.1 */
  280. macwait(regs);
  281. return regs->maccsrdata;
  282. }
  283. static void
  284. macwr(Regs *regs, uchar index, ulong val)
  285. {
  286. macwait(regs);
  287. regs->maccsrdata = val;
  288. regs->maccsrcmd = Csrbusy | index; /* fire */
  289. macwait(regs);
  290. }
  291. static long
  292. smcifstat(Ether* edev, void* a, long n, ulong offset)
  293. {
  294. Ctlr *ctlr;
  295. char *p, *s;
  296. int i, l, r;
  297. ctlr = edev->ctlr;
  298. qlock(&ctlr->slock);
  299. p = malloc(READSTR);
  300. l = 0;
  301. for(i = 0; i < Nstatistics; i++){
  302. // read regs->rxdrop TODO
  303. r = 0;
  304. if((s = statistics[i]) == nil)
  305. continue;
  306. switch(i){
  307. default:
  308. ctlr->statistics[i] += r;
  309. if(ctlr->statistics[i] == 0)
  310. continue;
  311. l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
  312. s, ctlr->statistics[i], r);
  313. break;
  314. }
  315. }
  316. l += snprint(p+l, READSTR-l, "lintr: %ud %ud\n",
  317. ctlr->lintr, ctlr->lsleep);
  318. l += snprint(p+l, READSTR-l, "rintr: %ud %ud\n",
  319. ctlr->rintr, ctlr->rsleep);
  320. l += snprint(p+l, READSTR-l, "tintr: %ud %ud\n",
  321. ctlr->tintr, ctlr->tsleep);
  322. l += snprint(p+l, READSTR-l, "eeprom:");
  323. for(i = 0; i < 0x40; i++){
  324. if(i && ((i & 0x07) == 0))
  325. l += snprint(p+l, READSTR-l, "\n ");
  326. l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
  327. }
  328. l += snprint(p+l, READSTR-l, "\n");
  329. USED(l);
  330. n = readstr(offset, a, n, p);
  331. free(p);
  332. qunlock(&ctlr->slock);
  333. return n;
  334. }
  335. static void
  336. smcpromiscuous(void* arg, int on)
  337. {
  338. int rctl;
  339. Ctlr *ctlr;
  340. Ether *edev;
  341. Regs *regs;
  342. edev = arg;
  343. ctlr = edev->ctlr;
  344. regs = ctlr->regs;
  345. rctl = macrd(regs, Maccr);
  346. if(on)
  347. rctl |= Prms;
  348. else
  349. rctl &= ~Prms;
  350. macwr(regs, Maccr, rctl);
  351. }
  352. static void
  353. smcmulticast(void*, uchar*, int)
  354. {
  355. /* nothing to do, we allow all multicast packets in */
  356. }
  357. static int
  358. iswrcpydone(void *arg)
  359. {
  360. return ((Ctlr *)arg)->wrcpydone;
  361. }
  362. static int
  363. smctxstart(Ctlr *ctlr, uchar *ubuf, uint len)
  364. {
  365. uint wds, ruplen;
  366. ulong *wdp, *txdp;
  367. Regs *regs;
  368. static ulong buf[ROUNDUP(ETHERMAXTU, sizeof(ulong)) / sizeof(ulong)];
  369. if (!ctlr->inited) {
  370. iprint("smctxstart: too soon to send\n");
  371. return -1; /* toss it */
  372. }
  373. regs = ctlr->regs;
  374. /* is there room for a packet in the tx data fifo? */
  375. if (len < ETHERMINTU)
  376. iprint("sending too-short (%d) pkt\n", len);
  377. else if (len > ETHERMAXTU)
  378. iprint("sending jumbo (%d) pkt\n", len);
  379. ruplen = ROUNDUP(len, sizeof(ulong));
  380. coherence(); /* back-to-back read/read delay per §6.2.2 */
  381. if ((regs->txfifoinf & Txdatafreemask) < ruplen + 2*sizeof(ulong))
  382. return -1; /* not enough room for data + command words */
  383. if ((uintptr)ubuf & MASK(2)) { /* ensure word alignment */
  384. memmove(buf, ubuf, len);
  385. ubuf = (uchar *)buf;
  386. }
  387. /* tx cmd a: length is bytes in this buffer */
  388. txdp = &regs->txdata;
  389. *txdp = Intcompl | Firstseg | Lastseg | len;
  390. /* tx cmd b: length is bytes in this packet (could be multiple buf.s) */
  391. *txdp = len;
  392. /* shovel pkt into tx fifo, which triggers transmission due to Txon */
  393. wdp = (ulong *)ubuf;
  394. for (wds = ruplen / sizeof(ulong) + 1; --wds > 0; )
  395. *txdp = *wdp++;
  396. regs->intsts = Txintrs; /* dismiss intr */
  397. coherence();
  398. regs->inten |= Txintrs;
  399. coherence(); /* back-to-back write/read delay per §6.2.1 */
  400. return 0;
  401. }
  402. static void
  403. smctransmit(Ether* edev)
  404. {
  405. Block *bp;
  406. Ctlr *ctlr;
  407. ctlr = edev->ctlr;
  408. if (ctlr == nil)
  409. panic("smctransmit: nil ctlr");
  410. ilock(&ctlr->tlock);
  411. /*
  412. * Try to fill the chip's buffers back up, via the tx fifo.
  413. */
  414. while ((bp = qget(edev->oq)) != nil)
  415. if (smctxstart(ctlr, bp->rp, BLEN(bp)) < 0) {
  416. qputback(edev->oq, bp); /* retry the block later */
  417. iprint("smctransmit: tx data fifo full\n");
  418. break;
  419. } else
  420. freeb(bp);
  421. iunlock(&ctlr->tlock);
  422. }
  423. static void
  424. smctransmitcall(Ether *edev) /* called from devether.c */
  425. {
  426. Ctlr *ctlr;
  427. ctlr = edev->ctlr;
  428. ctlr->gotoutput = 1;
  429. #ifdef USE_KPROCS
  430. wakeup(&ctlr->trendez);
  431. #else
  432. smctransmit(edev);
  433. #endif
  434. }
  435. static int
  436. smcrim(void* ctlr)
  437. {
  438. return ((Ctlr*)ctlr)->gotinput;
  439. }
  440. static void
  441. smcrproc(void* arg)
  442. {
  443. Ctlr *ctlr;
  444. Ether *edev;
  445. edev = arg;
  446. ctlr = edev->ctlr;
  447. for(;;){
  448. ctlr->rsleep++;
  449. sleep(&ctlr->rrendez, smcrim, ctlr);
  450. /* process any newly-arrived packets and pass to etheriq */
  451. ctlr->gotinput = 0;
  452. smcreceive(edev);
  453. }
  454. }
  455. static int
  456. smcgotout(void* ctlr)
  457. {
  458. return ((Ctlr*)ctlr)->gotoutput;
  459. }
  460. static void
  461. smctproc(void* arg)
  462. {
  463. Ctlr *ctlr;
  464. Ether *edev;
  465. edev = arg;
  466. ctlr = edev->ctlr;
  467. for(;;){
  468. ctlr->tsleep++;
  469. sleep(&ctlr->trendez, smcgotout, ctlr);
  470. /* process any newly-arrived packets and pass to etheriq */
  471. ctlr->gotoutput = 0;
  472. smctransmit(edev);
  473. }
  474. }
  475. void gpioirqclr(void);
  476. static void
  477. smcattach(Ether* edev)
  478. {
  479. #ifdef USE_KPROCS
  480. char name[KNAMELEN];
  481. #endif
  482. Ctlr *ctlr;
  483. ctlr = edev->ctlr;
  484. qlock(&ctlr->alock);
  485. if(waserror()){
  486. qunlock(&ctlr->alock);
  487. nexterror();
  488. }
  489. if (!ctlr->inited) {
  490. ctlr->inited = 1;
  491. #ifdef USE_KPROCS
  492. snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
  493. kproc(name, smcrproc, edev);
  494. snprint(name, KNAMELEN, "#l%dtproc", edev->ctlrno);
  495. kproc(name, smctproc, edev);
  496. #endif
  497. iprint("smcattach:");
  498. #ifdef USE_KPROCS
  499. iprint(" with kprocs");
  500. #else
  501. iprint(" no kprocs");
  502. #endif
  503. iprint(", no dma");
  504. /* can now accept real or simulated interrupts */
  505. smconce(edev);
  506. attached = 1;
  507. iprint("\n");
  508. }
  509. qunlock(&ctlr->alock);
  510. poperror();
  511. }
  512. static int
  513. isrdcpydone(void *arg)
  514. {
  515. return ((Ctlr *)arg)->rdcpydone;
  516. }
  517. static void
  518. smcreceive(Ether *edev)
  519. {
  520. uint wds, len, sts;
  521. ulong *wdp, *rxdp;
  522. Block *bp;
  523. Ctlr *ctlr;
  524. Regs *regs;
  525. ctlr = edev->ctlr;
  526. regs = ctlr->regs;
  527. coherence(); /* back-to-back read/read delay per §6.2.2 */
  528. /*
  529. * is there a full packet in the rx data fifo?
  530. */
  531. while (((regs->rxfifoinf & Rxstsusedmask) >> Rxstsusedshift) != 0) {
  532. coherence();
  533. sts = regs->rxsts; /* pop rx status */
  534. if(sts & Rxerr)
  535. iprint("smcreceive: rx error\n");
  536. len = (sts & Rxpktlenmask) >> Rxpktlenshift;
  537. if (len > ETHERMAXTU + Slop)
  538. iprint("smcreceive: oversized rx pkt (%d)\n", len);
  539. else if (len < ETHERMINTU)
  540. iprint("smcreceive: too-short (%d) pkt\n", len);
  541. wds = ROUNDUP(len, sizeof(ulong)) / sizeof(ulong);
  542. if (wds > 0) {
  543. /* copy aligned words from rx fifo into a Block */
  544. bp = iallocb(len + sizeof(ulong) /* - 1 */);
  545. if (bp == nil)
  546. panic("smcreceive: nil Block*");
  547. /* bp->rp should be 32-byte aligned, more than we need */
  548. assert(((uintptr)bp->rp & (sizeof(ulong) - 1)) == 0);
  549. wdp = (ulong *)bp->rp;
  550. rxdp = &regs->rxdata;
  551. wds = ROUNDUP(len, sizeof(ulong)) / sizeof(ulong) + 1;
  552. while (--wds > 0)
  553. *wdp++ = *rxdp;
  554. bp->wp = bp->rp + len;
  555. /* and push the Block upstream */
  556. if (ctlr->inited)
  557. etheriq(edev, bp, 1);
  558. else
  559. freeb(bp);
  560. regs->intsts = Rxintrs; /* dismiss intr */
  561. coherence();
  562. regs->inten |= Rxintrs;
  563. }
  564. coherence();
  565. }
  566. regs->inten |= Rxintrs;
  567. coherence();
  568. }
  569. /*
  570. * disable the stsclr bits in inten and write them to intsts to ack and dismiss
  571. * the interrupt source.
  572. */
  573. void
  574. ackintr(Regs *regs, ulong stsclr)
  575. {
  576. if (stsclr == 0)
  577. return;
  578. regs->inten &= ~stsclr;
  579. coherence();
  580. // regs->intsts = stsclr; /* acknowledge & clear intr(s) */
  581. // coherence();
  582. }
  583. static void
  584. smcinterrupt(Ureg*, void* arg)
  585. {
  586. int junk;
  587. unsigned intsts, intr;
  588. Ctlr *ctlr;
  589. Ether *edev;
  590. Regs *regs;
  591. edev = arg;
  592. ctlr = edev->ctlr;
  593. ilock(&ctlr->imlock);
  594. regs = ctlr->regs;
  595. gpioirqclr();
  596. coherence(); /* back-to-back read/read delay per §6.2.2 */
  597. intsts = regs->intsts;
  598. coherence();
  599. intsts &= ~MASK(3); /* ignore gpio bits */
  600. if (0 && intsts == 0) {
  601. coherence();
  602. iprint("smc: interrupt without a cause; insts %#ux (vs inten %#lux)\n",
  603. intsts, regs->inten);
  604. }
  605. intr = intsts & Rxintrs;
  606. if(intr) {
  607. /* disable interrupt sources; kproc/smcreceive will reenable */
  608. ackintr(regs, intr);
  609. ctlr->rintr++;
  610. ctlr->gotinput = 1;
  611. #ifdef USE_KPROCS
  612. wakeup(&ctlr->rrendez);
  613. #else
  614. smcreceive(edev);
  615. #endif
  616. }
  617. while(((regs->txfifoinf & Txstsusedmask) >> Txstsusedshift) != 0) {
  618. /* probably indicates tx completion, just toss it */
  619. junk = regs->txsts; /* pop tx sts */
  620. USED(junk);
  621. coherence();
  622. }
  623. intr = intsts & Txintrs;
  624. if (ctlr->gotoutput || intr) {
  625. /* disable interrupt sources; kproc/smctransmit will reenable */
  626. ackintr(regs, intr);
  627. ctlr->tintr++;
  628. ctlr->gotoutput = 1;
  629. #ifdef USE_KPROCS
  630. wakeup(&ctlr->trendez);
  631. #else
  632. smctransmit(edev);
  633. #endif
  634. }
  635. iunlock(&ctlr->imlock);
  636. }
  637. static void
  638. etherclock(void)
  639. {
  640. smcinterrupt(nil, thisether);
  641. }
  642. static int
  643. smcmii(Ctlr *)
  644. {
  645. return 0;
  646. }
  647. static int
  648. smcdetach(Ctlr* ctlr)
  649. {
  650. Regs *regs;
  651. if (ctlr == nil || ctlr->regs == nil)
  652. return -1;
  653. regs = ctlr->regs;
  654. /* verify that it's real by reading a few registers */
  655. switch (regs->id) {
  656. case Vid9221:
  657. break;
  658. default:
  659. print("smc: unknown chip id %#ux\n", regs->id);
  660. return -1;
  661. }
  662. regs->inten = 0; /* no interrupts */
  663. regs->intsts = ~0; /* clear any pending */
  664. regs->gptcfg = 0;
  665. coherence();
  666. regs->rxcfg = Rxdump;
  667. regs->txcfg = Txsdump | Txddump;
  668. regs->irqcfg &= ~Irqen;
  669. coherence();
  670. return 0;
  671. }
  672. static void
  673. smcshutdown(Ether* ether)
  674. {
  675. smcdetach(ether->ctlr);
  676. }
  677. static void
  678. powerwait(Regs *regs)
  679. {
  680. long bound;
  681. regs->bytetest = 0; /* bring power on */
  682. for (bound = 400*Mhz; !(regs->pmtctl & Dready) && bound > 0; bound--)
  683. ;
  684. if (bound <= 0)
  685. iprint("smc: pmtctl didn't come ready\n");
  686. }
  687. static int
  688. smcreset(Ctlr* ctlr)
  689. {
  690. int r;
  691. Regs *regs;
  692. static char zea[Eaddrlen];
  693. regs = ctlr->regs;
  694. powerwait(regs);
  695. if(smcdetach(ctlr))
  696. return -1;
  697. /* verify that it's real by reading a few registers */
  698. switch (regs->id) {
  699. case Vid9221:
  700. break;
  701. default:
  702. print("smc: unknown chip id %#ux\n", regs->id);
  703. return -1;
  704. }
  705. if (regs->bytetest != 0x87654321) {
  706. print("smc: bytetest reg %#p (%#lux) != 0x87654321\n",
  707. &regs->bytetest, regs->bytetest);
  708. return -1;
  709. }
  710. #ifdef TODO /* read MAC from EEPROM */
  711. // int ctrl, i, pause, swdpio, txcw;
  712. /*
  713. * Snarf and set up the receive addresses.
  714. * There are 16 addresses. The first should be the MAC address.
  715. * The others are cleared and not marked valid (MS bit of Rah).
  716. */
  717. for(i = Ea; i < Eaddrlen/2; i++){
  718. ctlr->ra[2*i] = ctlr->eeprom[i];
  719. ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
  720. }
  721. /*
  722. * Clear the Multicast Table Array.
  723. * It's a 4096 bit vector accessed as 128 32-bit registers.
  724. */
  725. memset(ctlr->mta, 0, sizeof(ctlr->mta));
  726. for(i = 0; i < 128; i++)
  727. csr32w(ctlr, Mta+i*4, 0);
  728. #endif
  729. regs->hwcfg |= Mbo;
  730. /* don't overwrite existing ea */
  731. // if (memcmp(edev->ea, zea, Eaddrlen) == 0)
  732. // memmove(edev->ea, ctlr->ra, Eaddrlen);
  733. r = ctlr->ra[3]<<24 | ctlr->ra[2]<<16 | ctlr->ra[1]<<8 | ctlr->ra[0];
  734. macwr(regs, Macaddrl, r);
  735. macwr(regs, Macaddrh, ctlr->ra[5]<<8 | ctlr->ra[4]);
  736. /* turn on the controller */
  737. macwr(regs, Maccoe, 0);
  738. regs->inten = 0; /* no interrupts yet */
  739. regs->intsts = ~0; /* clear any pending */
  740. regs->gptcfg = 0;
  741. coherence();
  742. regs->rxcfg = Rxdump;
  743. regs->txcfg = Txsdump | Txddump | Txon;
  744. regs->fifoint = 72<<24; /* default values */
  745. macwr(regs, Maccr, Rxall | Rcvown | Fdpx | Mcpas | Txen | Rxen);
  746. coherence(); /* back-to-back write/read delay per §6.2.1 */
  747. regs->irqcfg = 1<<24 | Irqen | Irqpushpull; /* deas for 10µs (linux) */
  748. coherence(); /* back-to-back write/read delay per §6.2.1 */
  749. regs->inten = Rxintrs | Txintrs;
  750. coherence();
  751. if(smcmii(ctlr) < 0)
  752. return -1;
  753. return 0;
  754. }
  755. static void
  756. smcpci(void)
  757. {
  758. Ctlr *ctlr;
  759. static int beenhere;
  760. if (beenhere)
  761. return;
  762. beenhere = 1;
  763. if (probeaddr(PHYSETHER) < 0)
  764. return;
  765. ctlr = malloc(sizeof(Ctlr));
  766. ctlr->id = Vid9221<<16 | 0x0424; /* smsc 9221 */
  767. ctlr->port = PHYSETHER;
  768. ctlr->nic = (int *)PHYSETHER;
  769. ctlr->regs = (Regs *)PHYSETHER;
  770. if(smcreset(ctlr)){
  771. free(ctlr);
  772. return;
  773. }
  774. if(smcctlrhead != nil)
  775. smcctlrtail->next = ctlr;
  776. else
  777. smcctlrhead = ctlr;
  778. smcctlrtail = ctlr;
  779. }
  780. static int
  781. smcpnp(Ether* edev)
  782. {
  783. Ctlr *ctlr;
  784. static char zea[Eaddrlen];
  785. if(smcctlrhead == nil)
  786. smcpci();
  787. /*
  788. * Any adapter matches if no edev->port is supplied,
  789. * otherwise the ports must match.
  790. */
  791. for(ctlr = smcctlrhead; ctlr != nil; ctlr = ctlr->next){
  792. if(ctlr->active)
  793. continue;
  794. if(edev->port == 0 || edev->port == ctlr->port){
  795. ctlr->active = 1;
  796. break;
  797. }
  798. }
  799. if(ctlr == nil)
  800. return -1;
  801. edev->ctlr = ctlr;
  802. ctlr->edev = edev; /* point back to Ether* */
  803. edev->port = ctlr->port;
  804. edev->irq = 34;
  805. // TODO: verify speed (100Mb/s) and duplicity (full-duplex)
  806. edev->mbps = 100;
  807. /* don't overwrite existing ea */
  808. if (memcmp(edev->ea, zea, Eaddrlen) == 0)
  809. memmove(edev->ea, ctlr->ra, Eaddrlen);
  810. /*
  811. * Linkage to the generic ethernet driver.
  812. */
  813. edev->attach = smcattach;
  814. edev->transmit = smctransmitcall;
  815. edev->interrupt = smcinterrupt;
  816. edev->ifstat = smcifstat;
  817. /* edev->ctl = smcctl; /* no ctl msgs supported */
  818. edev->arg = edev;
  819. edev->promiscuous = smcpromiscuous;
  820. edev->multicast = smcmulticast;
  821. edev->shutdown = smcshutdown;
  822. return 0;
  823. }
  824. void
  825. ether9221link(void)
  826. {
  827. addethercard("9221", smcpnp);
  828. }