etherga620.c 29 KB

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