etherga620.c 28 KB

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