etherga620.c 24 KB

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