etherga620.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. /*
  2. * bootstrap driver for
  3. * Netgear GA620 Gigabit Ethernet Card.
  4. * Specific for the Alteon Tigon 2 and Intel Pentium or later.
  5. * To Do:
  6. * cache alignment for PCI Write-and-Invalidate
  7. * mini ring (what size)?
  8. * tune coalescing values
  9. * statistics formatting
  10. * don't update Spi if nothing to send
  11. * receive ring alignment
  12. * watchdog for link management?
  13. */
  14. #include "u.h"
  15. #include "lib.h"
  16. #include "mem.h"
  17. #include "dat.h"
  18. #include "fns.h"
  19. #include "io.h"
  20. #define malign(n) xspanalloc((n), 32, 0)
  21. #include "etherif.h"
  22. #include "etherga620fw.h"
  23. enum {
  24. Mhc = 0x0040, /* Miscellaneous Host Control */
  25. Mlc = 0x0044, /* Miscellaneous Local Control */
  26. Mc = 0x0050, /* Miscellaneous Configuration */
  27. Ps = 0x005C, /* PCI State */
  28. Wba = 0x0068, /* Window Base Address */
  29. Wd = 0x006C, /* Window Data */
  30. DMAas = 0x011C, /* DMA Assist State */
  31. CPUAstate = 0x0140, /* CPU A State */
  32. CPUApc = 0x0144, /* CPU A Programme Counter */
  33. CPUBstate = 0x0240, /* CPU B State */
  34. Hi = 0x0504, /* Host In Interrupt Handler */
  35. Cpi = 0x050C, /* Command Producer Index */
  36. Spi = 0x0514, /* Send Producer Index */
  37. Rspi = 0x051C, /* Receive Standard Producer Index */
  38. Rjpi = 0x0524, /* Receive Jumbo Producer Index */
  39. Rmpi = 0x052C, /* Receive Mini Producer Index */
  40. Mac = 0x0600, /* MAC Address */
  41. Gip = 0x0608, /* General Information Pointer */
  42. Om = 0x0618, /* Operating Mode */
  43. DMArc = 0x061C, /* DMA Read Configuration */
  44. DMAwc = 0x0620, /* DMA Write Configuration */
  45. Tbr = 0x0624, /* Transmit Buffer Ratio */
  46. Eci = 0x0628, /* Event Consumer Index */
  47. Cci = 0x062C, /* Command Consumer Index */
  48. Rct = 0x0630, /* Receive Coalesced Ticks */
  49. Sct = 0x0634, /* Send Coalesced Ticks */
  50. St = 0x0638, /* Stat Ticks */
  51. SmcBD = 0x063C, /* Send Max. Coalesced BDs */
  52. RmcBD = 0x0640, /* Receive Max. Coalesced BDs */
  53. Nt = 0x0644, /* NIC Tracing */
  54. Gln = 0x0648, /* Gigabit Link Negotiation */
  55. Fln = 0x064C, /* 10/100 Link Negotiation */
  56. Ifx = 0x065C, /* Interface Index */
  57. IfMTU = 0x0660, /* Interface MTU */
  58. Mi = 0x0664, /* Mask Interrupts */
  59. Gls = 0x0668, /* Gigabit Link State */
  60. Fls = 0x066C, /* 10/100 Link State */
  61. Cr = 0x0700, /* Command Ring */
  62. Lmw = 0x0800, /* Local Memory Window */
  63. };
  64. enum { /* Mhc */
  65. Is = 0x00000001, /* Interrupt State */
  66. Ci = 0x00000002, /* Clear Interrupt */
  67. Hr = 0x00000008, /* Hard Reset */
  68. Eebs = 0x00000010, /* Enable Endian Byte Swap */
  69. Eews = 0x00000020, /* Enable Endian Word (64-bit) swap */
  70. Mpio = 0x00000040, /* Mask PCI Interrupt Output */
  71. };
  72. enum { /* Mlc */
  73. SRAM512 = 0x00000200, /* SRAM Bank Size of 512KB */
  74. SRAMmask = 0x00000300,
  75. EEclk = 0x00100000, /* Serial EEPROM Clock Output */
  76. EEdoe = 0x00200000, /* Serial EEPROM Data Out Enable */
  77. EEdo = 0x00400000, /* Serial EEPROM Data Out Value */
  78. EEdi = 0x00800000, /* Serial EEPROM Data Input */
  79. };
  80. enum { /* Mc */
  81. SyncSRAM = 0x00100000, /* Set Synchronous SRAM Timing */
  82. };
  83. enum { /* Ps */
  84. PCIwm32 = 0x000000C0, /* Write Max DMA 32 */
  85. PCImrm = 0x00020000, /* Use Memory Read Multiple Command */
  86. PCI66 = 0x00080000,
  87. PCI32 = 0x00100000,
  88. PCIrcmd = 0x06000000, /* PCI Read Command */
  89. PCIwcmd = 0x70000000, /* PCI Write Command */
  90. };
  91. enum { /* CPUAstate */
  92. CPUrf = 0x00000010, /* ROM Fail */
  93. CPUhalt = 0x00010000, /* Halt the internal CPU */
  94. CPUhie = 0x00040000, /* HALT instruction executed */
  95. };
  96. enum { /* Om */
  97. BswapBD = 0x00000002, /* Byte Swap Buffer Descriptors */
  98. WswapBD = 0x00000004, /* Word Swap Buffer Descriptors */
  99. Warn = 0x00000008,
  100. BswapDMA = 0x00000010, /* Byte Swap DMA Data */
  101. Only1DMA = 0x00000040, /* Only One DMA Active at a time */
  102. NoJFrag = 0x00000200, /* Don't Fragment Jumbo Frames */
  103. Fatal = 0x40000000,
  104. };
  105. enum { /* Lmw */
  106. Lmwsz = 2*1024, /* Local Memory Window Size */
  107. /*
  108. * legal values are 0x3800 iff Nsr is 128, 0x3000 iff Nsr is 256,
  109. * or 0x2000 iff Nsr is 512.
  110. */
  111. Sr = 0x3800, /* Send Ring (accessed via Lmw) */
  112. };
  113. enum { /* Link */
  114. Lpref = 0x00008000, /* Preferred Link */
  115. L10MB = 0x00010000,
  116. L100MB = 0x00020000,
  117. L1000MB = 0x00040000,
  118. Lfd = 0x00080000, /* Full Duplex */
  119. Lhd = 0x00100000, /* Half Duplex */
  120. Lefc = 0x00200000, /* Emit Flow Control Packets */
  121. Lofc = 0x00800000, /* Obey Flow Control Packets */
  122. Lean = 0x20000000, /* Enable Autonegotiation/Sensing */
  123. Le = 0x40000000, /* Link Enable */
  124. };
  125. typedef struct Host64 {
  126. uint hi;
  127. uint lo;
  128. } Host64;
  129. typedef struct Ere { /* Event Ring Element */
  130. int event; /* event<<24 | code<<12 | index */
  131. int unused;
  132. } Ere;
  133. typedef int Cmd; /* cmd<<24 | flags<<12 | index */
  134. typedef struct Rbd { /* Receive Buffer Descriptor */
  135. Host64 addr;
  136. int indexlen; /* ring-index<<16 | buffer-length */
  137. int flags; /* only lower 16-bits */
  138. int checksum; /* ip<<16 |tcp/udp */
  139. int error; /* only upper 16-bits */
  140. int reserved;
  141. void* opaque; /* passed to receive return ring */
  142. } Rbd;
  143. typedef struct Sbd { /* Send Buffer Descriptor */
  144. Host64 addr;
  145. int lenflags; /* len<<16 |flags */
  146. int reserved;
  147. } Sbd;
  148. enum { /* Buffer Descriptor Flags */
  149. Fend = 0x00000004, /* Frame Ends in this Buffer */
  150. Frjr = 0x00000010, /* Receive Jumbo Ring Buffer */
  151. Funicast = 0x00000020, /* Unicast packet (2-bit field) */
  152. Fmulticast = 0x00000040, /* Multicast packet */
  153. Fbroadcast = 0x00000060, /* Broadcast packet */
  154. Ferror = 0x00000400, /* Frame Has Error */
  155. Frmr = 0x00001000, /* Receive Mini Ring Buffer */
  156. };
  157. enum { /* Buffer Error Flags */
  158. Ecrc = 0x00010000, /* bad CRC */
  159. Ecollision = 0x00020000, /* collision */
  160. Elink = 0x00040000, /* link lost */
  161. Ephy = 0x00080000, /* unspecified PHY frame decode error */
  162. Eodd = 0x00100000, /* odd number of nibbles */
  163. Emac = 0x00200000, /* unspecified MAC abort */
  164. Elen64 = 0x00400000, /* short packet */
  165. Eresources = 0x00800000, /* MAC out of internal resources */
  166. Egiant = 0x01000000, /* packet too big */
  167. };
  168. typedef struct Rcb { /* Ring Control Block */
  169. Host64 addr; /* points to the Rbd ring */
  170. int control; /* max_len<<16 |flags */
  171. int unused;
  172. } Rcb;
  173. enum {
  174. TcpUdpCksum = 0x0001, /* Perform TCP or UDP checksum */
  175. IpCksum = 0x0002, /* Perform IP checksum */
  176. NoPseudoHdrCksum= 0x0008, /* Don't include the pseudo header */
  177. VlanAssist = 0x0010, /* Enable VLAN tagging */
  178. CoalUpdateOnly = 0x0020, /* Coalesce transmit interrupts */
  179. HostRing = 0x0040, /* Sr in host memory */
  180. SnapCksum = 0x0080, /* Parse + offload 802.3 SNAP frames */
  181. UseExtRxBd = 0x0100, /* Extended Rbd for Jumbo frames */
  182. RingDisabled = 0x0200, /* Jumbo or Mini RCB only */
  183. };
  184. typedef struct Gib { /* General Information Block */
  185. int statistics[256]; /* Statistics */
  186. Rcb ercb; /* Event Ring */
  187. Rcb crcb; /* Command Ring */
  188. Rcb srcb; /* Send Ring */
  189. Rcb rsrcb; /* Receive Standard Ring */
  190. Rcb rjrcb; /* Receive Jumbo Ring */
  191. Rcb rmrcb; /* Receive Mini Ring */
  192. Rcb rrrcb; /* Receive Return Ring */
  193. Host64 epp; /* Event Producer */
  194. Host64 rrrpp; /* Receive Return Ring Producer */
  195. Host64 scp; /* Send Consumer */
  196. Host64 rsp; /* Refresh Stats */
  197. } Gib;
  198. /*
  199. * these sizes are all fixed in the card,
  200. * except for Nsr, which has only 3 valid sizes.
  201. */
  202. enum { /* Host/NIC Interface ring sizes */
  203. Ner = 256, /* event ring */
  204. Ncr = 64, /* command ring */
  205. Nsr = 128, /* send ring: 128, 256 or 512 */
  206. Nrsr = 512, /* receive standard ring */
  207. Nrjr = 256, /* receive jumbo ring */
  208. Nrmr = 1024, /* receive mini ring, optional */
  209. Nrrr = 2048, /* receive return ring */
  210. };
  211. enum {
  212. NrsrHI = 72, /* Fill-level of Rsr (m.b. < Nrsr) */
  213. NrsrLO = 54, /* Level at which to top-up ring */
  214. NrjrHI = 0, /* Fill-level of Rjr (m.b. < Nrjr) */
  215. NrjrLO = 0, /* Level at which to top-up ring */
  216. NrmrHI = 0, /* Fill-level of Rmr (m.b. < Nrmr) */
  217. NrmrLO = 0, /* Level at which to top-up ring */
  218. };
  219. typedef struct Ctlr Ctlr;
  220. struct Ctlr {
  221. int port;
  222. Pcidev* pcidev;
  223. Ctlr* next;
  224. int active;
  225. int id;
  226. uchar ea[Eaddrlen];
  227. int* nic;
  228. Gib* gib;
  229. Ere* er;
  230. Lock srlock;
  231. Sbd* sr;
  232. Block** srb;
  233. int nsr; /* currently in send ring */
  234. Rbd* rsr;
  235. int nrsr; /* currently in Receive Standard Ring */
  236. Rbd* rjr;
  237. int nrjr; /* currently in Receive Jumbo Ring */
  238. Rbd* rmr;
  239. int nrmr; /* currently in Receive Mini Ring */
  240. Rbd* rrr;
  241. int rrrci; /* Receive Return Ring Consumer Index */
  242. int epi[2]; /* Event Producer Index */
  243. int rrrpi[2]; /* Receive Return Ring Producer Index */
  244. int sci[3]; /* Send Consumer Index ([2] is host) */
  245. int interrupts; /* statistics */
  246. int mi;
  247. uvlong ticks;
  248. int coalupdateonly; /* tuning */
  249. int hardwarecksum;
  250. int rct; /* Receive Coalesce Ticks */
  251. int sct; /* Send Coalesce Ticks */
  252. int st; /* Stat Ticks */
  253. int smcbd; /* Send Max. Coalesced BDs */
  254. int rmcbd; /* Receive Max. Coalesced BDs */
  255. };
  256. static Ctlr* ctlrhead;
  257. static Ctlr* ctlrtail;
  258. #define csr32r(c, r) (*((c)->nic+((r)/4)))
  259. #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
  260. static void
  261. sethost64(Host64* host64, void* addr)
  262. {
  263. uvlong uvl;
  264. uvl = PCIWADDR(addr);
  265. host64->hi = uvl>>32;
  266. host64->lo = uvl & 0xFFFFFFFFL;
  267. }
  268. static void
  269. ga620command(Ctlr* ctlr, int cmd, int flags, int index)
  270. {
  271. int cpi;
  272. cpi = csr32r(ctlr, Cpi);
  273. csr32w(ctlr, Cr+(cpi*4), cmd<<24 | flags<<12 | index);
  274. cpi = NEXT(cpi, Ncr);
  275. csr32w(ctlr, Cpi, cpi);
  276. }
  277. static void
  278. ga620attach(Ether* )
  279. {
  280. }
  281. static void
  282. waitforlink(Ether *edev)
  283. {
  284. int i;
  285. if (edev->mbps == 0) {
  286. print("#l%d: ga620: waiting for link", edev->ctlrno);
  287. /* usually takes about 10 seconds */
  288. for (i = 0; i < 20 && edev->mbps == 0; i++) {
  289. print(".");
  290. delay(1000);
  291. }
  292. print("\n");
  293. if (i == 20 && edev->mbps == 0)
  294. edev->mbps = 1; /* buggered */
  295. }
  296. }
  297. static void
  298. toringbuf(Ether *ether, Block *bp)
  299. {
  300. RingBuf *rb = &ether->rb[ether->ri];
  301. if (rb->owner == Interface) {
  302. rb->len = BLEN(bp);
  303. memmove(rb->pkt, bp->rp, rb->len);
  304. rb->owner = Host;
  305. ether->ri = NEXT(ether->ri, ether->nrb);
  306. }
  307. /* else no one is expecting packets from the network */
  308. }
  309. static Block *
  310. fromringbuf(Ether *ether)
  311. {
  312. RingBuf *tb = &ether->tb[ether->ti];
  313. Block *bp = allocb(tb->len);
  314. if (bp == nil)
  315. panic("fromringbuf: nil allocb return");
  316. if (bp->wp == nil)
  317. panic("fromringbuf: nil bp->wb");
  318. memmove(bp->wp, tb->pkt, tb->len);
  319. memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
  320. bp->wp += tb->len;
  321. return bp;
  322. }
  323. static int
  324. _ga620transmit(Ether* edev)
  325. {
  326. Sbd *sbd;
  327. Block *bp;
  328. Ctlr *ctlr;
  329. RingBuf *tb;
  330. int sci, spi, work;
  331. /*
  332. * For now there are no smarts here, just empty the
  333. * ring and try to fill it back up. Tuning comes later.
  334. */
  335. ctlr = edev->ctlr;
  336. waitforlink(edev);
  337. ilock(&ctlr->srlock);
  338. /*
  339. * Free any completed packets.
  340. * Ctlr->sci[0] is where the NIC has got to consuming the ring.
  341. * Ctlr->sci[2] is where the host has got to tidying up after the
  342. * NIC has done with the packets.
  343. */
  344. work = 0;
  345. for(sci = ctlr->sci[2]; sci != ctlr->sci[0]; sci = NEXT(sci, Nsr)){
  346. if(ctlr->srb[sci] == nil)
  347. continue;
  348. freeb(ctlr->srb[sci]);
  349. ctlr->srb[sci] = nil;
  350. work++;
  351. }
  352. ctlr->sci[2] = sci;
  353. sci = PREV(sci, Nsr);
  354. tb = &edev->tb[edev->ti];
  355. for(spi = csr32r(ctlr, Spi); spi != sci && tb->owner == Interface;
  356. spi = NEXT(spi, Nsr)){
  357. bp = fromringbuf(edev);
  358. sbd = &ctlr->sr[spi];
  359. sethost64(&sbd->addr, bp->rp);
  360. sbd->lenflags = BLEN(bp)<<16 |Fend;
  361. ctlr->srb[spi] = bp;
  362. work++;
  363. tb->owner = Host;
  364. edev->ti = NEXT(edev->ti, edev->ntb);
  365. tb = &edev->tb[edev->ti];
  366. }
  367. csr32w(ctlr, Spi, spi);
  368. iunlock(&ctlr->srlock);
  369. return work;
  370. }
  371. static void
  372. ga620transmit(Ether* edev)
  373. {
  374. _ga620transmit(edev);
  375. }
  376. static void
  377. ga620replenish(Ctlr* ctlr)
  378. {
  379. Rbd *rbd;
  380. int rspi;
  381. Block *bp;
  382. rspi = csr32r(ctlr, Rspi);
  383. while(ctlr->nrsr < NrsrHI){
  384. if((bp = allocb(ETHERMAXTU+4)) == nil)
  385. break;
  386. rbd = &ctlr->rsr[rspi];
  387. sethost64(&rbd->addr, bp->rp);
  388. rbd->indexlen = rspi<<16 | (ETHERMAXTU+4);
  389. rbd->flags = 0;
  390. rbd->opaque = bp;
  391. rspi = NEXT(rspi, Nrsr);
  392. ctlr->nrsr++;
  393. }
  394. csr32w(ctlr, Rspi, rspi);
  395. }
  396. static void
  397. ga620event(Ether *edev, int eci, int epi)
  398. {
  399. unsigned event, code;
  400. Ctlr *ctlr;
  401. ctlr = edev->ctlr;
  402. while(eci != epi){
  403. event = ctlr->er[eci].event;
  404. code = (event >> 12) & ((1<<12)-1);
  405. switch(event>>24){
  406. case 0x01: /* firmware operational */
  407. /* host stack (us) is up. 3rd arg of 2 means down. */
  408. ga620command(ctlr, 0x01, 0x01, 0x00);
  409. /*
  410. * link negotiation: any speed is okay.
  411. * 3rd arg of 1 selects gigabit only; 2 10/100 only.
  412. */
  413. ga620command(ctlr, 0x0B, 0x00, 0x00);
  414. print("#l%d: ga620: port %8.8uX: firmware is up\n",
  415. edev->ctlrno, ctlr->port);
  416. break;
  417. case 0x04: /* statistics updated */
  418. break;
  419. case 0x06: /* link state changed */
  420. switch (code) {
  421. case 1:
  422. edev->mbps = 1000;
  423. break;
  424. case 2:
  425. print("#l%d: link down\n", edev->ctlrno);
  426. break;
  427. case 3:
  428. edev->mbps = 100; /* it's 10 or 100 */
  429. break;
  430. }
  431. if (code != 2)
  432. print("#l%d: %dMbps link up\n",
  433. edev->ctlrno, edev->mbps);
  434. break;
  435. case 0x07: /* event error */
  436. default:
  437. print("#l%d: ga620: er[%d] = %8.8uX\n", edev->ctlrno,
  438. eci, event);
  439. break;
  440. }
  441. eci = NEXT(eci, Ner);
  442. }
  443. csr32w(ctlr, Eci, eci);
  444. }
  445. static void
  446. ga620receive(Ether* edev)
  447. {
  448. int len;
  449. Rbd *rbd;
  450. Block *bp;
  451. Ctlr* ctlr;
  452. ctlr = edev->ctlr;
  453. while(ctlr->rrrci != ctlr->rrrpi[0]){
  454. rbd = &ctlr->rrr[ctlr->rrrci];
  455. /*
  456. * Errors are collected in the statistics block so
  457. * no need to tally them here, let ifstat do the work.
  458. */
  459. len = rbd->indexlen & 0xFFFF;
  460. if(!(rbd->flags & Ferror) && len != 0){
  461. bp = rbd->opaque;
  462. bp->wp = bp->rp+len;
  463. toringbuf(edev, bp);
  464. } else
  465. freeb(rbd->opaque);
  466. rbd->opaque = nil;
  467. if(rbd->flags & Frjr)
  468. ctlr->nrjr--;
  469. else if(rbd->flags & Frmr)
  470. ctlr->nrmr--;
  471. else
  472. ctlr->nrsr--;
  473. ctlr->rrrci = NEXT(ctlr->rrrci, Nrrr);
  474. }
  475. }
  476. static void
  477. ga620interrupt(Ureg*, void* arg)
  478. {
  479. int csr, ie, work;
  480. Ctlr *ctlr;
  481. Ether *edev;
  482. edev = arg;
  483. ctlr = edev->ctlr;
  484. if(!(csr32r(ctlr, Mhc) & Is))
  485. return;
  486. ctlr->interrupts++;
  487. csr32w(ctlr, Hi, 1);
  488. ie = 0;
  489. work = 0;
  490. while(ie < 2){
  491. if(ctlr->rrrci != ctlr->rrrpi[0]){
  492. ga620receive(edev);
  493. work = 1;
  494. }
  495. if(_ga620transmit(edev) != 0)
  496. work = 1;
  497. csr = csr32r(ctlr, Eci);
  498. if(csr != ctlr->epi[0]){
  499. ga620event(edev, csr, ctlr->epi[0]);
  500. work = 1;
  501. }
  502. if(ctlr->nrsr <= NrsrLO)
  503. ga620replenish(ctlr);
  504. if(work == 0){
  505. if(ie == 0)
  506. csr32w(ctlr, Hi, 0);
  507. ie++;
  508. }
  509. work = 0;
  510. }
  511. }
  512. static void
  513. ga620lmw(Ctlr* ctlr, int addr, int* data, int len)
  514. {
  515. int i, l, lmw, v;
  516. /*
  517. * Write to or clear ('data' == nil) 'len' bytes of the NIC
  518. * local memory at address 'addr'.
  519. * The destination address and count should be 32-bit aligned.
  520. */
  521. v = 0;
  522. while(len > 0){
  523. /*
  524. * 1) Set the window. The (Lmwsz-1) bits are ignored
  525. * in Wba when accessing through the local memory window;
  526. * 2) Find the minimum of how many bytes still to
  527. * transfer and how many left in this window;
  528. * 3) Create the offset into the local memory window in the
  529. * shared memory space then copy (or zero) the data;
  530. * 4) Bump the counts.
  531. */
  532. csr32w(ctlr, Wba, addr);
  533. l = ROUNDUP(addr+1, Lmwsz) - addr;
  534. if(l > len)
  535. l = len;
  536. lmw = Lmw + (addr & (Lmwsz-1));
  537. for(i = 0; i < l; i += 4){
  538. if(data != nil)
  539. v = *data++;
  540. csr32w(ctlr, lmw+i, v);
  541. }
  542. len -= l;
  543. addr += l;
  544. }
  545. }
  546. static int
  547. ga620init(Ether* edev)
  548. {
  549. Ctlr *ctlr;
  550. Host64 host64;
  551. int csr, ea, i, flags;
  552. ctlr = edev->ctlr;
  553. /*
  554. * Load the MAC address.
  555. */
  556. ea = edev->ea[0]<<8 | edev->ea[1];
  557. csr32w(ctlr, Mac, ea);
  558. ea = edev->ea[2]<<24 | edev->ea[3]<<16 | edev->ea[4]<<8 | edev->ea[5];
  559. csr32w(ctlr, Mac+4, ea);
  560. /*
  561. * General Information Block.
  562. */
  563. ctlr->gib = malloc(sizeof(Gib));
  564. sethost64(&host64, ctlr->gib);
  565. csr32w(ctlr, Gip, host64.hi);
  566. csr32w(ctlr, Gip+4, host64.lo);
  567. /*
  568. * Event Ring.
  569. * This is located in host memory. Allocate the ring,
  570. * tell the NIC where it is and initialise the indices.
  571. */
  572. ctlr->er = malign(sizeof(Ere)*Ner);
  573. sethost64(&ctlr->gib->ercb.addr, ctlr->er);
  574. sethost64(&ctlr->gib->epp, ctlr->epi);
  575. csr32w(ctlr, Eci, 0);
  576. /*
  577. * Command Ring.
  578. * This is located in the General Communications Region
  579. * and so the value placed in the Rcb is unused, the NIC
  580. * knows where it is. Stick in the value according to
  581. * the datasheet anyway.
  582. * Initialise the ring and indices.
  583. */
  584. ctlr->gib->crcb.addr.lo = Cr - 0x400;
  585. for(i = 0; i < Ncr*4; i += 4)
  586. csr32w(ctlr, Cr+i, 0);
  587. csr32w(ctlr, Cpi, 0);
  588. csr32w(ctlr, Cci, 0);
  589. /*
  590. * Send Ring.
  591. * This ring is either in NIC memory at a fixed location depending
  592. * on how big the ring is or it is in host memory. If in NIC
  593. * memory it is accessed via the Local Memory Window; with a send
  594. * ring size of 128 the window covers the whole ring and then need
  595. * only be set once:
  596. * ctlr->sr = (uchar*)ctlr->nic+Lmw;
  597. * ga620lmw(ctlr, Sr, nil, sizeof(Sbd)*Nsr);
  598. * ctlr->gib->srcb.addr.lo = Sr;
  599. * There is nowhere in the Sbd to hold the Block* associated
  600. * with this entry so an external array must be kept.
  601. */
  602. ctlr->sr = malign(sizeof(Sbd)*Nsr);
  603. sethost64(&ctlr->gib->srcb.addr, ctlr->sr);
  604. if(ctlr->hardwarecksum)
  605. flags = TcpUdpCksum|NoPseudoHdrCksum|HostRing;
  606. else
  607. flags = HostRing;
  608. if(ctlr->coalupdateonly)
  609. flags |= CoalUpdateOnly;
  610. ctlr->gib->srcb.control = Nsr<<16 | flags;
  611. sethost64(&ctlr->gib->scp, ctlr->sci);
  612. csr32w(ctlr, Spi, 0);
  613. ctlr->srb = malloc(sizeof(Block*)*Nsr);
  614. /*
  615. * Receive Standard Ring.
  616. */
  617. ctlr->rsr = malign(sizeof(Rbd)*Nrsr);
  618. sethost64(&ctlr->gib->rsrcb.addr, ctlr->rsr);
  619. if(ctlr->hardwarecksum)
  620. flags = TcpUdpCksum|NoPseudoHdrCksum;
  621. else
  622. flags = 0;
  623. ctlr->gib->rsrcb.control = (ETHERMAXTU+4)<<16 | flags;
  624. csr32w(ctlr, Rspi, 0);
  625. /*
  626. * Jumbo and Mini Rings. Unused for now.
  627. */
  628. ctlr->gib->rjrcb.control = RingDisabled;
  629. ctlr->gib->rmrcb.control = RingDisabled;
  630. /*
  631. * Receive Return Ring.
  632. * This is located in host memory. Allocate the ring,
  633. * tell the NIC where it is and initialise the indices.
  634. */
  635. ctlr->rrr = malign(sizeof(Rbd)*Nrrr);
  636. sethost64(&ctlr->gib->rrrcb.addr, ctlr->rrr);
  637. ctlr->gib->rrrcb.control = Nrrr<<16 | 0;
  638. sethost64(&ctlr->gib->rrrpp, ctlr->rrrpi);
  639. ctlr->rrrci = 0;
  640. /*
  641. * Refresh Stats Pointer.
  642. * For now just point it at the existing statistics block.
  643. */
  644. sethost64(&ctlr->gib->rsp, ctlr->gib->statistics);
  645. /*
  646. * DMA configuration.
  647. * Use the recommended values.
  648. */
  649. csr32w(ctlr, DMArc, 0x80);
  650. csr32w(ctlr, DMAwc, 0x80);
  651. /*
  652. * Transmit Buffer Ratio.
  653. * Set to 1/3 of available buffer space (units are 1/64ths)
  654. * if using Jumbo packets, ~64KB otherwise (assume 1MB on NIC).
  655. */
  656. if(NrjrHI > 0 || Nsr > 128)
  657. csr32w(ctlr, Tbr, 64/3);
  658. else
  659. csr32w(ctlr, Tbr, 4);
  660. /*
  661. * Tuneable parameters.
  662. * These defaults are based on the tuning hints in the Alteon
  663. * Host/NIC Software Interface Definition and example software.
  664. */
  665. ctlr->rct = 1 /*100*/;
  666. csr32w(ctlr, Rct, ctlr->rct);
  667. ctlr->sct = 0;
  668. csr32w(ctlr, Sct, ctlr->sct);
  669. ctlr->st = 1000000;
  670. csr32w(ctlr, St, ctlr->st);
  671. ctlr->smcbd = Nsr/4;
  672. csr32w(ctlr, SmcBD, ctlr->smcbd);
  673. ctlr->rmcbd = 4 /*6*/;
  674. csr32w(ctlr, RmcBD, ctlr->rmcbd);
  675. /*
  676. * Enable DMA Assist Logic.
  677. */
  678. csr = csr32r(ctlr, DMAas) & ~0x03;
  679. csr32w(ctlr, DMAas, csr|0x01);
  680. /*
  681. * Link negotiation.
  682. * The bits are set here but the NIC must be given a command
  683. * once it is running to set negotiation in motion.
  684. */
  685. csr32w(ctlr, Gln, Le|Lean|Lofc|Lfd|L1000MB|Lpref);
  686. csr32w(ctlr, Fln, Le|Lean|Lhd|Lfd|L100MB|L10MB);
  687. /*
  688. * A unique index for this controller and the maximum packet
  689. * length expected.
  690. * For now only standard packets are expected.
  691. */
  692. csr32w(ctlr, Ifx, 1);
  693. csr32w(ctlr, IfMTU, ETHERMAXTU+4);
  694. /*
  695. * Enable Interrupts.
  696. * There are 3 ways to mask interrupts - a bit in the Mhc (which
  697. * is already cleared), the Mi register and the Hi mailbox.
  698. * Writing to the Hi mailbox has the side-effect of clearing the
  699. * PCI interrupt.
  700. */
  701. csr32w(ctlr, Mi, 0);
  702. csr32w(ctlr, Hi, 0);
  703. /*
  704. * Start the firmware.
  705. */
  706. csr32w(ctlr, CPUApc, tigon2FwStartAddr);
  707. csr = csr32r(ctlr, CPUAstate) & ~CPUhalt;
  708. csr32w(ctlr, CPUAstate, csr);
  709. return 0;
  710. }
  711. static int
  712. at24c32io(Ctlr* ctlr, char* op, int data)
  713. {
  714. char *lp, *p;
  715. int i, loop, mlc, r;
  716. mlc = csr32r(ctlr, Mlc);
  717. r = 0;
  718. loop = -1;
  719. lp = nil;
  720. for(p = op; *p != '\0'; p++){
  721. switch(*p){
  722. default:
  723. return -1;
  724. case ' ':
  725. continue;
  726. case ':': /* start of 8-bit loop */
  727. if(lp != nil)
  728. return -1;
  729. lp = p;
  730. loop = 7;
  731. continue;
  732. case ';': /* end of 8-bit loop */
  733. if(lp == nil)
  734. return -1;
  735. loop--;
  736. if(loop >= 0)
  737. p = lp;
  738. else
  739. lp = nil;
  740. continue;
  741. case 'C': /* assert clock */
  742. mlc |= EEclk;
  743. break;
  744. case 'c': /* deassert clock */
  745. mlc &= ~EEclk;
  746. break;
  747. case 'D': /* next bit in 'data' byte */
  748. if(loop < 0)
  749. return -1;
  750. if(data & (1<<loop))
  751. mlc |= EEdo;
  752. else
  753. mlc &= ~EEdo;
  754. break;
  755. case 'E': /* enable data output */
  756. mlc |= EEdoe;
  757. break;
  758. case 'e': /* disable data output */
  759. mlc &= ~EEdoe;
  760. break;
  761. case 'I': /* input bit */
  762. i = (csr32r(ctlr, Mlc) & EEdi) != 0;
  763. if(loop >= 0)
  764. r |= (i<<loop);
  765. else
  766. r = i;
  767. continue;
  768. case 'O': /* assert data output */
  769. mlc |= EEdo;
  770. break;
  771. case 'o': /* deassert data output */
  772. mlc &= ~EEdo;
  773. break;
  774. }
  775. csr32w(ctlr, Mlc, mlc);
  776. microdelay(1);
  777. }
  778. if(loop >= 0)
  779. return -1;
  780. return r;
  781. }
  782. static int
  783. at24c32r(Ctlr* ctlr, int addr)
  784. {
  785. int data;
  786. /*
  787. * Read a byte at address 'addr' from the Atmel AT24C32
  788. * Serial EEPROM. The 2-wire EEPROM access is controlled
  789. * by 4 bits in Mlc. See the AT24C32 datasheet for
  790. * protocol details.
  791. */
  792. /*
  793. * Start condition - a high to low transition of data
  794. * with the clock high must precede any other command.
  795. */
  796. at24c32io(ctlr, "OECoc", 0);
  797. /*
  798. * Perform a random read at 'addr'. A dummy byte
  799. * write sequence is performed to clock in the device
  800. * and data word addresses (0 and 'addr' respectively).
  801. */
  802. data = -1;
  803. if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA0) != 0)
  804. goto stop;
  805. if(at24c32io(ctlr, "oE :DCc; oeCIc", addr>>8) != 0)
  806. goto stop;
  807. if(at24c32io(ctlr, "oE :DCc; oeCIc", addr) != 0)
  808. goto stop;
  809. /*
  810. * Now send another start condition followed by a
  811. * request to read the device. The EEPROM responds
  812. * by clocking out the data.
  813. */
  814. at24c32io(ctlr, "OECoc", 0);
  815. if(at24c32io(ctlr, "oE :DCc; oeCIc", 0xA1) != 0)
  816. goto stop;
  817. data = at24c32io(ctlr, ":CIc;", 0xA1);
  818. stop:
  819. /*
  820. * Stop condition - a low to high transition of data
  821. * with the clock high is a stop condition. After a read
  822. * sequence, the stop command will place the EEPROM in
  823. * a standby power mode.
  824. */
  825. at24c32io(ctlr, "oECOc", 0);
  826. return data;
  827. }
  828. static int
  829. ga620detach(Ctlr* ctlr)
  830. {
  831. int timeo;
  832. /*
  833. * Hard reset (don't know which endian so catch both);
  834. * enable for little-endian mode;
  835. * wait for code to be loaded from serial EEPROM or flash;
  836. * make sure CPU A is halted.
  837. */
  838. csr32w(ctlr, Mhc, Hr<<24 | Hr);
  839. csr32w(ctlr, Mhc, (Eews|Ci)<<24 | Eews|Ci);
  840. microdelay(1);
  841. for(timeo = 0; timeo < 500000; timeo++){
  842. if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) == CPUhie)
  843. break;
  844. microdelay(1);
  845. }
  846. if((csr32r(ctlr, CPUAstate) & (CPUhie|CPUrf)) != CPUhie)
  847. return -1;
  848. csr32w(ctlr, CPUAstate, CPUhalt);
  849. /*
  850. * After reset, CPU B seems to be stuck in 'CPUrf'.
  851. * Worry about it later.
  852. */
  853. csr32w(ctlr, CPUBstate, CPUhalt);
  854. return 0;
  855. }
  856. static void
  857. ga620shutdown(Ether* ether)
  858. {
  859. print("ga620shutdown\n");
  860. ga620detach(ether->ctlr);
  861. }
  862. static int
  863. ga620reset(Ctlr* ctlr)
  864. {
  865. int cls, csr, i, r;
  866. if(ga620detach(ctlr) < 0)
  867. return -1;
  868. /*
  869. * Tigon 2 PCI NICs have 512KB SRAM per bank.
  870. * Clear out any lingering serial EEPROM state
  871. * bits.
  872. */
  873. csr = csr32r(ctlr, Mlc) & ~(EEdi|EEdo|EEdoe|EEclk|SRAMmask);
  874. csr32w(ctlr, Mlc, SRAM512|csr);
  875. csr = csr32r(ctlr, Mc);
  876. csr32w(ctlr, Mc, SyncSRAM|csr);
  877. /*
  878. * Initialise PCI State register.
  879. * If PCI Write-and-Invalidate is enabled set the max write DMA
  880. * value to the host cache-line size (32 on Pentium or later).
  881. */
  882. csr = csr32r(ctlr, Ps) & (PCI32|PCI66);
  883. csr |= PCIwcmd|PCIrcmd|PCImrm;
  884. if(ctlr->pcidev->pcr & 0x0010){
  885. cls = pcicfgr8(ctlr->pcidev, PciCLS) * 4;
  886. if(cls != 32)
  887. pcicfgw8(ctlr->pcidev, PciCLS, 32/4);
  888. csr |= PCIwm32;
  889. }
  890. csr32w(ctlr, Ps, csr);
  891. /*
  892. * Operating Mode.
  893. */
  894. csr32w(ctlr, Om, Fatal|NoJFrag|BswapDMA|WswapBD);
  895. /*
  896. * Snarf the MAC address from the serial EEPROM.
  897. */
  898. for(i = 0; i < Eaddrlen; i++){
  899. if((r = at24c32r(ctlr, 0x8E+i)) == -1)
  900. return -1;
  901. ctlr->ea[i] = r;
  902. }
  903. /*
  904. * Load the firmware.
  905. */
  906. ga620lmw(ctlr, tigon2FwTextAddr, tigon2FwText, tigon2FwTextLen);
  907. ga620lmw(ctlr, tigon2FwRodataAddr, tigon2FwRodata, tigon2FwRodataLen);
  908. ga620lmw(ctlr, tigon2FwDataAddr, tigon2FwData, tigon2FwDataLen);
  909. ga620lmw(ctlr, tigon2FwSbssAddr, nil, tigon2FwSbssLen);
  910. ga620lmw(ctlr, tigon2FwBssAddr, nil, tigon2FwBssLen);
  911. /*
  912. * we will eventually get events telling us that the firmware is
  913. * up and that the link is up.
  914. */
  915. return 0;
  916. }
  917. static void
  918. ga620pci(void)
  919. {
  920. int port;
  921. Pcidev *p;
  922. Ctlr *ctlr;
  923. p = nil;
  924. while(p = pcimatch(p, 0, 0)){
  925. if(p->ccrb != 0x02 || p->ccru != 0)
  926. continue;
  927. switch(p->did<<16 | p->vid){
  928. default:
  929. continue;
  930. case 0x620A<<16 | 0x1385: /* Netgear GA620 fiber */
  931. case 0x630A<<16 | 0x1385: /* Netgear GA620T copper */
  932. case 0x0001<<16 | 0x12AE: /* Alteon Acenic fiber
  933. * and DEC DEGPA-SA */
  934. case 0x0002<<16 | 0x12AE: /* Alteon Acenic copper */
  935. case 0x0009<<16 | 0x10A9: /* SGI Acenic */
  936. break;
  937. }
  938. port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
  939. if(port == 0){
  940. print("ga620: can't map %d @ 0x%8.8luX\n",
  941. p->mem[0].size, p->mem[0].bar);
  942. continue;
  943. }
  944. ctlr = malloc(sizeof(Ctlr));
  945. ctlr->port = port;
  946. ctlr->pcidev = p;
  947. ctlr->id = p->did<<16 | p->vid;
  948. ctlr->nic = KADDR(ctlr->port);
  949. if(ga620reset(ctlr)){
  950. free(ctlr);
  951. continue;
  952. }
  953. if(ctlrhead != nil)
  954. ctlrtail->next = ctlr;
  955. else
  956. ctlrhead = ctlr;
  957. ctlrtail = ctlr;
  958. }
  959. }
  960. int
  961. ga620pnp(Ether* edev)
  962. {
  963. Ctlr *ctlr;
  964. uchar ea[Eaddrlen];
  965. if(ctlrhead == nil)
  966. ga620pci();
  967. /*
  968. * Any adapter matches if no edev->port is supplied,
  969. * otherwise the ports must match.
  970. */
  971. for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
  972. if(ctlr->active)
  973. continue;
  974. if(edev->port == 0 || edev->port == ctlr->port){
  975. ctlr->active = 1;
  976. break;
  977. }
  978. }
  979. if(ctlr == nil)
  980. return -1;
  981. edev->ctlr = ctlr;
  982. edev->port = ctlr->port;
  983. edev->irq = ctlr->pcidev->intl;
  984. edev->tbdf = ctlr->pcidev->tbdf;
  985. /*
  986. * Check if the adapter's station address is to be overridden.
  987. * If not, read it from the EEPROM and set in ether->ea prior to
  988. * loading the station address in the hardware.
  989. */
  990. memset(ea, 0, Eaddrlen);
  991. if(memcmp(ea, edev->ea, Eaddrlen) == 0)
  992. memmove(edev->ea, ctlr->ea, Eaddrlen);
  993. ga620init(edev); /* enables interrupts */
  994. /*
  995. * Linkage to the generic ethernet driver.
  996. */
  997. edev->attach = ga620attach;
  998. edev->transmit = ga620transmit;
  999. edev->interrupt = ga620interrupt;
  1000. edev->detach = ga620shutdown;
  1001. return 0;
  1002. }