etherm10g.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608
  1. /*
  2. * myricom 10 Gb ethernet driver
  3. * © 2007 erik quanstrom, coraid
  4. */
  5. #include "u.h"
  6. #include "../port/lib.h"
  7. #include "mem.h"
  8. #include "dat.h"
  9. #include "fns.h"
  10. #include "io.h"
  11. #include "../port/error.h"
  12. #include "../port/netif.h"
  13. #include "etherif.h"
  14. #define K * 1024
  15. #define MB * 1024 K
  16. #define dprint(...) if(debug) print(__VA_ARGS__)
  17. #define pcicapdbg(...)
  18. #define malign(n) xspanalloc(n, 4 K, 0)
  19. #include "etherm10g2k.i"
  20. #include "etherm10g4k.i"
  21. static int debug = 0;
  22. static char Etimeout[] = "timeout";
  23. enum {
  24. Epromsz = 256,
  25. Maxslots= 1024,
  26. Align = 4096,
  27. Maxmtu = 9000,
  28. Noconf = 0xffffffff,
  29. Fwoffset= 1 MB,
  30. Cmdoff = 0xf80000, /* command port offset */
  31. Fwsubmt = 0xfc0000, /* firmware submission command port offset */
  32. Rdmaoff = 0xfc01c0, /* rdma command port offset */
  33. };
  34. enum {
  35. CZero,
  36. Creset,
  37. Cversion,
  38. CSintrqdma, /* issue these before Cetherup */
  39. CSbigsz, /* in bytes bigsize = 2^n */
  40. CSsmallsz,
  41. CGsendoff,
  42. CGsmallrxoff,
  43. CGbigrxoff,
  44. CGirqackoff,
  45. CGirqdeassoff,
  46. CGsendrgsz,
  47. CGrxrgsz,
  48. CSintrqsz, /* 2^n */
  49. Cetherup, /* above parameters + mtu/mac addr must be set first. */
  50. Cetherdn,
  51. CSmtu, /* below may be issued live */
  52. CGcoaloff, /* in µs */
  53. CSstatsrate, /* in µs */
  54. CSstatsdma,
  55. Cpromisc,
  56. Cnopromisc,
  57. CSmac,
  58. Cenablefc,
  59. Cdisablefc,
  60. Cdmatest, /* address in d[0-1], d[2]=length */
  61. Cenableallmc,
  62. Cdisableallmc,
  63. CSjoinmc,
  64. CSleavemc,
  65. Cleaveallmc,
  66. CSstatsdma2, /* adds (unused) multicast stats */
  67. };
  68. typedef union {
  69. uint i[2];
  70. uchar c[8];
  71. } Cmd;
  72. typedef struct {
  73. u16int cksum;
  74. u16int len;
  75. } Slot;
  76. enum {
  77. SFsmall = 1,
  78. SFfirst = 2,
  79. SFalign = 4,
  80. SFnotso = 16,
  81. };
  82. typedef struct {
  83. u32int high;
  84. u32int low;
  85. u16int hdroff;
  86. u16int len;
  87. uchar pad;
  88. uchar nrdma;
  89. uchar chkoff;
  90. uchar flags;
  91. } Send;
  92. typedef struct {
  93. QLock;
  94. Send *lanai; /* tx ring (cksum+len in lanai memory) */
  95. Send *host; /* tx ring (data in our memory) */
  96. Block **bring;
  97. // uchar *wcfifo; /* what the heck is a w/c fifo? */
  98. int size; /* of buffers in the z8's memory */
  99. u32int segsz;
  100. uint n; /* rxslots */
  101. uint m; /* mask; rxslots must be a power of two */
  102. uint i; /* number of segments (not frames) queued */
  103. uint cnt; /* number of segments sent by the card */
  104. ulong npkt;
  105. vlong nbytes;
  106. } Tx;
  107. typedef struct {
  108. Lock;
  109. Block *head;
  110. uint size; /* buffer size of each block */
  111. uint n; /* n free buffers */
  112. uint cnt;
  113. } Bpool;
  114. Bpool smpool = { .size = 128, };
  115. Bpool bgpool = { .size = Maxmtu, };
  116. typedef struct {
  117. Bpool *pool; /* free buffers */
  118. u32int *lanai; /* rx ring; we have no permanent host shadow */
  119. Block **host; /* called "info" in myricom driver */
  120. // uchar *wcfifo; /* cmd submission fifo */
  121. uint m;
  122. uint n; /* rxslots */
  123. uint i;
  124. uint cnt; /* number of buffers allocated (lifetime) */
  125. uint allocfail;
  126. } Rx;
  127. /* dma mapped. unix network byte order. */
  128. typedef struct {
  129. uchar txcnt[4];
  130. uchar linkstat[4];
  131. uchar dlink[4];
  132. uchar derror[4];
  133. uchar drunt[4];
  134. uchar doverrun[4];
  135. uchar dnosm[4];
  136. uchar dnobg[4];
  137. uchar nrdma[4];
  138. uchar txstopped;
  139. uchar down;
  140. uchar updated;
  141. uchar valid;
  142. } Stats;
  143. enum {
  144. Detached,
  145. Attached,
  146. Runed,
  147. };
  148. typedef struct {
  149. Slot *entry;
  150. uintptr busaddr;
  151. uint m;
  152. uint n;
  153. uint i;
  154. } Done;
  155. typedef struct Ctlr Ctlr;
  156. typedef struct Ctlr {
  157. QLock;
  158. int state;
  159. int kprocs;
  160. uintptr port;
  161. Pcidev* pcidev;
  162. Ctlr* next;
  163. int active;
  164. int id; /* do we need this? */
  165. uchar ra[Eaddrlen];
  166. int ramsz;
  167. uchar *ram;
  168. u32int *irqack;
  169. u32int *irqdeass;
  170. u32int *coal;
  171. char eprom[Epromsz];
  172. ulong serial; /* unit serial number */
  173. QLock cmdl;
  174. Cmd *cmd; /* address of command return */
  175. uintptr cprt; /* bus address of command */
  176. uintptr boot; /* boot address */
  177. Done done;
  178. Tx tx;
  179. Rx sm;
  180. Rx bg;
  181. Stats *stats;
  182. uintptr statsprt;
  183. Rendez rxrendez;
  184. Rendez txrendez;
  185. int msi;
  186. u32int linkstat;
  187. u32int nrdma;
  188. } Ctlr;
  189. static Ctlr *ctlrs;
  190. enum {
  191. PciCapPMG = 0x01, /* power management */
  192. PciCapAGP = 0x02,
  193. PciCapVPD = 0x03, /* vital product data */
  194. PciCapSID = 0x04, /* slot id */
  195. PciCapMSI = 0x05,
  196. PciCapCHS = 0x06, /* compact pci hot swap */
  197. PciCapPCIX = 0x07,
  198. PciCapHTC = 0x08, /* hypertransport irq conf */
  199. PciCapVND = 0x09, /* vendor specific information */
  200. PciCapHSW = 0x0C, /* hot swap */
  201. PciCapPCIe = 0x10,
  202. PciCapMSIX = 0x11,
  203. };
  204. enum {
  205. PcieAERC = 1,
  206. PcieVC,
  207. PcieSNC,
  208. PciePBC,
  209. };
  210. enum {
  211. AercCCR = 0x18, /* control register */
  212. };
  213. enum {
  214. PcieCTL = 8,
  215. PcieLCR = 12,
  216. PcieMRD = 0x7000, /* maximum read size */
  217. };
  218. int
  219. pcicap(Pcidev *p, int cap)
  220. {
  221. int i, c, off;
  222. pcicapdbg("pcicap: %x:%d\n", p->vid, p->did);
  223. off = 0x34; /* 0x14 for cardbus */
  224. for(i = 48; i--; ){
  225. pcicapdbg("\t" "loop %x\n", off);
  226. off = pcicfgr8(p, off);
  227. pcicapdbg("\t" "pcicfgr8 %x\n", off);
  228. if(off < 0x40)
  229. break;
  230. off &= ~3;
  231. c = pcicfgr8(p, off);
  232. pcicapdbg("\t" "pcicfgr8 %x\n", c);
  233. if(c == 0xff)
  234. break;
  235. if(c == cap)
  236. return off;
  237. off++;
  238. }
  239. return 0;
  240. }
  241. /*
  242. * this function doesn't work because pcicgr32 doesn't have access
  243. * to the pcie extended configuration space.
  244. */
  245. int
  246. pciecap(Pcidev *p, int cap)
  247. {
  248. uint off, i;
  249. off = 0x100;
  250. while(((i = pcicfgr32(p, off))&0xffff) != cap){
  251. off = i >> 20;
  252. print("pciecap offset = %ud\n", off);
  253. if(off < 0x100 || off >= 4 K - 1)
  254. return 0;
  255. }
  256. print("pciecap found = %ud\n", off);
  257. return off;
  258. }
  259. static int
  260. setpcie(Pcidev *p)
  261. {
  262. int off;
  263. /* set 4k writes */
  264. off = pcicap(p, PciCapPCIe);
  265. if(off < 64)
  266. return -1;
  267. off += PcieCTL;
  268. pcicfgw16(p, off, (pcicfgr16(p, off) & ~PcieMRD) | 5<<12);
  269. return 0;
  270. }
  271. static int
  272. whichfw(Pcidev *p)
  273. {
  274. char *s;
  275. int i, off, lanes, ecrc;
  276. u32int cap;
  277. /* check the number of configured lanes. */
  278. off = pcicap(p, PciCapPCIe);
  279. if(off < 64)
  280. return -1;
  281. off += PcieLCR;
  282. cap = pcicfgr16(p, off);
  283. lanes = (cap>>4) & 0x3f;
  284. /* check AERC register. we need it on. */
  285. off = pciecap(p, PcieAERC);
  286. print("%d offset\n", off);
  287. cap = 0;
  288. if(off != 0){
  289. off += AercCCR;
  290. cap = pcicfgr32(p, off);
  291. print("%ud cap\n", cap);
  292. }
  293. ecrc = (cap>>4) & 0xf;
  294. /* if we don't like the aerc, kick it here. */
  295. print("m10g %d lanes; ecrc=%d; ", lanes, ecrc);
  296. if(s = getconf("myriforce")){
  297. i = atoi(s);
  298. if(i != 4 K || i != 2 K)
  299. i = 2 K;
  300. print("fw=%d [forced]\n", i);
  301. return i;
  302. }
  303. if(lanes <= 4){
  304. print("fw = 4096 [lanes]\n");
  305. return 4 K;
  306. }
  307. if(ecrc & 10){
  308. print("fw = 4096 [ecrc set]\n");
  309. return 4K;
  310. }
  311. print("fw = 4096 [default]\n");
  312. return 4 K;
  313. }
  314. static int
  315. parseeprom(Ctlr *c)
  316. {
  317. int i, j, k, l, bits;
  318. char *s;
  319. dprint("m10g eprom:\n");
  320. s = c->eprom;
  321. bits = 3;
  322. for(i = 0; s[i] && i < Epromsz; i++){
  323. l = strlen(s+i);
  324. dprint("\t%s\n", s+i);
  325. if(strncmp(s+i, "MAC=", 4) == 0 && l == 4+12+5){
  326. bits ^= 1;
  327. j = i + 4;
  328. for(k = 0; k < 6; k++)
  329. c->ra[k] = strtoul(s+j+3*k, 0, 16);
  330. }else if(strncmp(s+i, "SN=", 3) == 0){
  331. bits ^= 2;
  332. c->serial = atoi(s+i+3);
  333. }
  334. i += l;
  335. }
  336. if(bits)
  337. return -1;
  338. return 0;
  339. }
  340. u16int
  341. pbit16(u16int i)
  342. {
  343. u16int j;
  344. uchar *p;
  345. p = (uchar*)&j;
  346. p[1] = i;
  347. p[0] = i>>8;
  348. return j;
  349. }
  350. u16int
  351. gbit16(uchar i[2])
  352. {
  353. u16int j;
  354. j = i[1];
  355. j |= i[0]<<8;
  356. return j;
  357. }
  358. u32int
  359. pbit32(u32int i)
  360. {
  361. u32int j;
  362. uchar *p;
  363. p = (uchar*)&j;
  364. p[3] = i;
  365. p[2] = i>>8;
  366. p[1] = i>>16;
  367. p[0] = i>>24;
  368. return j;
  369. }
  370. static u32int
  371. gbit32(uchar i[4])
  372. {
  373. u32int j;
  374. j = i[3];
  375. j |= i[2]<<8;
  376. j |= i[1]<<16;
  377. j |= i[0]<<24;
  378. return j;
  379. }
  380. static void
  381. prepcmd(uint *cmd, int i)
  382. {
  383. while(i-- > 0)
  384. cmd[i] = pbit32(cmd[i]);
  385. }
  386. /*
  387. * the command looks like this (int 32bit integers)
  388. * cmd type
  389. * addr (low)
  390. * addr (high)
  391. * pad (used for dma testing)
  392. * response (high)
  393. * response (low)
  394. * 40 byte = 5 int pad.
  395. */
  396. u32int
  397. cmd(Ctlr *c, int type, u32int data)
  398. {
  399. u32int buf[16], i;
  400. Cmd *cmd;
  401. qlock(&c->cmdl);
  402. cmd = c->cmd;
  403. cmd->i[1] = Noconf;
  404. memset(buf, 0, sizeof buf);
  405. buf[0] = type;
  406. buf[1] = data;
  407. buf[5] = c->cprt;
  408. prepcmd(buf, 6);
  409. coherence();
  410. memmove(c->ram + Cmdoff, buf, sizeof buf);
  411. if(waserror())
  412. nexterror();
  413. for(i = 0; i < 15; i++){
  414. if(cmd->i[1] != Noconf){
  415. poperror();
  416. i = gbit32(cmd->c);
  417. qunlock(&c->cmdl);
  418. if(cmd->i[1] != 0)
  419. dprint("[%ux]", i);
  420. return i;
  421. }
  422. tsleep(&up->sleep, return0, 0, 1);
  423. }
  424. qunlock(&c->cmdl);
  425. iprint("m10g: cmd timeout [%ux %ux] cmd=%d\n",
  426. cmd->i[0], cmd->i[1], type);
  427. error(Etimeout);
  428. return ~0; /* silence! */
  429. }
  430. u32int
  431. maccmd(Ctlr *c, int type, uchar *m)
  432. {
  433. u32int buf[16], i;
  434. Cmd *cmd;
  435. qlock(&c->cmdl);
  436. cmd = c->cmd;
  437. cmd->i[1] = Noconf;
  438. memset(buf, 0, sizeof buf);
  439. buf[0] = type;
  440. buf[1] = m[0]<<24 | m[1]<<16 | m[2]<<8 | m[3];
  441. buf[2] = m[4]<< 8 | m[5];
  442. buf[5] = c->cprt;
  443. prepcmd(buf, 6);
  444. coherence();
  445. memmove(c->ram + Cmdoff, buf, sizeof buf);
  446. if(waserror())
  447. nexterror();
  448. for(i = 0; i < 15; i++){
  449. if(cmd->i[1] != Noconf){
  450. poperror();
  451. i = gbit32(cmd->c);
  452. qunlock(&c->cmdl);
  453. if(cmd->i[1] != 0)
  454. dprint("[%ux]", i);
  455. return i;
  456. }
  457. tsleep(&up->sleep, return0, 0, 1);
  458. }
  459. qunlock(&c->cmdl);
  460. iprint("m10g: maccmd timeout [%ux %ux] cmd=%d\n",
  461. cmd->i[0], cmd->i[1], type);
  462. error(Etimeout);
  463. return ~0; /* silence! */
  464. }
  465. /* remove this garbage after testing */
  466. enum {
  467. DMAread = 0x10000,
  468. DMAwrite= 0x1,
  469. };
  470. u32int
  471. dmatestcmd(Ctlr *c, int type, u32int addr, int len)
  472. {
  473. u32int buf[16], i;
  474. memset(buf, 0, sizeof buf);
  475. memset(c->cmd, Noconf, sizeof *c->cmd);
  476. buf[0] = Cdmatest;
  477. buf[1] = addr;
  478. buf[3] = len * type;
  479. buf[5] = c->cprt;
  480. prepcmd(buf, 6);
  481. coherence();
  482. memmove(c->ram + Cmdoff, buf, sizeof buf);
  483. if(waserror())
  484. nexterror();
  485. for(i = 0; i < 15; i++){
  486. if(c->cmd->i[1] != Noconf){
  487. i = gbit32(c->cmd->c);
  488. if(i == 0)
  489. error(Eio);
  490. poperror();
  491. return i;
  492. }
  493. tsleep(&up->sleep, return0, 0, 5);
  494. }
  495. error(Etimeout);
  496. return ~0; /* silence! */
  497. }
  498. u32int
  499. rdmacmd(Ctlr *c, int on)
  500. {
  501. u32int buf[16], i;
  502. memset(buf, 0, sizeof buf);
  503. c->cmd->i[0] = 0;
  504. coherence();
  505. buf[1] = c->cprt;
  506. buf[2] = Noconf;
  507. buf[4] = c->cprt;
  508. buf[5] = on;
  509. prepcmd(buf, 6);
  510. memmove(c->ram + Rdmaoff, buf, sizeof buf);
  511. if(waserror())
  512. nexterror();
  513. for(i = 0; i < 20; i++){
  514. if(c->cmd->i[0] == Noconf){
  515. poperror();
  516. return gbit32(c->cmd->c);
  517. }
  518. tsleep(&up->sleep, return0, 0, 1);
  519. }
  520. error(Etimeout);
  521. iprint("m10g: rdmacmd timeout\n");
  522. return ~0; /* silence! */
  523. }
  524. static int
  525. loadfw(Ctlr *c, int *align)
  526. {
  527. uint *f, *s, sz;
  528. int i;
  529. if((*align = whichfw(c->pcidev)) == 4 K){
  530. f = (u32int*)fw4k;
  531. sz = sizeof fw4k;
  532. }else{
  533. f = (u32int*)fw2k;
  534. sz = sizeof fw2k;
  535. }
  536. s = (u32int*)(c->ram + Fwoffset);
  537. for(i = 0; i < sz / 4; i++)
  538. s[i] = f[i];
  539. return sz & ~3;
  540. }
  541. static int
  542. bootfw(Ctlr *c)
  543. {
  544. int i, sz, align;
  545. uint buf[16];
  546. Cmd* cmd;
  547. if((sz = loadfw(c, &align)) == 0)
  548. return 0;
  549. dprint("bootfw %d bytes ... ", sz);
  550. cmd = c->cmd;
  551. memset(buf, 0, sizeof buf);
  552. c->cmd->i[0] = 0;
  553. coherence();
  554. buf[0] = 0; /* upper 32 bits of dma target address */
  555. buf[1] = c->cprt; /* lower */
  556. buf[2] = Noconf; /* writeback */
  557. buf[3] = Fwoffset + 8,
  558. buf[4] = sz - 8;
  559. buf[5] = 8;
  560. buf[6] = 0;
  561. prepcmd(buf, 7);
  562. coherence();
  563. memmove(c->ram + Fwsubmt, buf, sizeof buf);
  564. for(i = 0; i < 20; i++){
  565. if(cmd->i[0] == Noconf)
  566. break;
  567. delay(1);
  568. }
  569. dprint("[%ux %ux]", gbit32(cmd->c), gbit32(cmd->c+4));
  570. if(i == 20){
  571. print("m10g: cannot load fw\n");
  572. return -1;
  573. }
  574. dprint("\n");
  575. c->tx.segsz = align;
  576. return 0;
  577. }
  578. int
  579. kickthebaby(Pcidev *p, Ctlr *c)
  580. {
  581. /* don't kick the baby! */
  582. u32int code;
  583. pcicfgw8(p, 0x10+c->boot, 0x3);
  584. pcicfgw32(p, 0x18+c->boot, 0xfffffff0);
  585. code = pcicfgr32(p, 0x14+c->boot);
  586. dprint("reboot status = %ux\n", code);
  587. if(code != 0xfffffff0)
  588. return -1;
  589. return 0;
  590. }
  591. typedef struct {
  592. uchar len[4];
  593. uchar type[4];
  594. char version[128];
  595. uchar globals[4];
  596. uchar ramsz[4];
  597. uchar specs[4];
  598. uchar specssz[4];
  599. } Fwhdr;
  600. enum {
  601. Tmx = 0x4d582020,
  602. Tpcie = 0x70636965,
  603. Teth = 0x45544820,
  604. Tmcp0 = 0x4d435030,
  605. };
  606. char*
  607. fwtype(u32int type)
  608. {
  609. switch(type){
  610. case Tmx:
  611. return "mx";
  612. case Tpcie:
  613. return "PCIe";
  614. case Teth:
  615. return "eth";
  616. case Tmcp0:
  617. return "mcp0";
  618. }
  619. return "*GOK*";
  620. }
  621. int
  622. chkfw(Ctlr *c)
  623. {
  624. uintptr off;
  625. Fwhdr *h;
  626. u32int type;
  627. off = gbit32(c->ram+0x3c);
  628. dprint("firmware %ulx\n", off);
  629. if((off&3) || off + sizeof *h > c->ramsz){
  630. print("!m10g: bad firmware %ulx\n", off);
  631. return -1;
  632. }
  633. h = (Fwhdr*)(c->ram + off);
  634. type = gbit32(h->type);
  635. dprint("\t" "type %s\n", fwtype(type));
  636. dprint("\t" "vers %s\n", h->version);
  637. dprint("\t" "ramsz %ux\n", gbit32(h->ramsz));
  638. if(type != Teth){
  639. print("!m10g: bad card type %s\n", fwtype(type));
  640. return -1;
  641. }
  642. return bootfw(c) || rdmacmd(c, 0);
  643. }
  644. static int
  645. reset(Ether *e, Ctlr *c)
  646. {
  647. u32int i, sz;
  648. if(waserror()){
  649. print("m10g: reset error\n");
  650. nexterror();
  651. return -1;
  652. }
  653. chkfw(c);
  654. cmd(c, Creset, 0);
  655. cmd(c, CSintrqsz, c->done.n*sizeof *c->done.entry);
  656. cmd(c, CSintrqdma, c->done.busaddr);
  657. c->irqack = (u32int*)(c->ram + cmd(c, CGirqackoff, 0));
  658. /* required only if we're not doing msi? */
  659. c->irqdeass = (u32int*)(c->ram + cmd(c, CGirqdeassoff, 0));
  660. /* this is the driver default, why fiddle with this? */
  661. c->coal = (u32int*)(c->ram + cmd(c, CGcoaloff, 0));
  662. *c->coal = pbit32(25);
  663. dprint("dma stats:\n");
  664. rdmacmd(c, 1);
  665. sz = c->tx.segsz;
  666. i = dmatestcmd(c, DMAread, c->done.busaddr, sz);
  667. print("\t" "read: %ud MB/s\n", ((i>>16)*sz*2)/(i&0xffff));
  668. i = dmatestcmd(c, DMAwrite, c->done.busaddr, sz);
  669. print("\t" "write: %ud MB/s\n", ((i>>16)*sz*2)/(i&0xffff));
  670. i = dmatestcmd(c, DMAwrite|DMAread, c->done.busaddr, sz);
  671. print("\t" "r/w: %ud MB/s\n", ((i>>16)*sz*2*2)/(i&0xffff));
  672. memset(c->done.entry, 0, c->done.n * sizeof *c->done.entry);
  673. maccmd(c, CSmac, c->ra);
  674. // cmd(c, Cnopromisc, 0);
  675. cmd(c, Cenablefc, 0);
  676. e->maxmtu = Maxmtu;
  677. cmd(c, CSmtu, e->maxmtu);
  678. dprint("CSmtu %d...\n", e->maxmtu);
  679. poperror();
  680. return 0;
  681. }
  682. static void
  683. ctlrfree(Ctlr *c)
  684. {
  685. /* free up all the Block*s, too */
  686. free(c->tx.host);
  687. free(c->sm.host);
  688. free(c->bg.host);
  689. free(c->cmd);
  690. free(c->done.entry);
  691. free(c->stats);
  692. free(c);
  693. }
  694. static int
  695. setmem(Pcidev *p, Ctlr *c)
  696. {
  697. u32int i, raddr;
  698. Done *d;
  699. void *mem;
  700. c->tx.segsz = 2048;
  701. c->ramsz = 2 MB - (2*48 K + 32 K) - 0x100;
  702. if(c->ramsz > p->mem[0].size)
  703. return -1;
  704. raddr = p->mem[0].bar & ~0x0F;
  705. mem = vmap(raddr, p->mem[0].size);
  706. if(mem == nil){
  707. print("m10g: can't map %8.8lux\n", p->mem[0].bar);
  708. return -1;
  709. }
  710. dprint("%ux <- vmap(mem[0].size = %ux)\n", raddr, p->mem[0].size);
  711. c->port = raddr;
  712. c->ram = mem;
  713. c->cmd = malign(sizeof *c->cmd);
  714. c->cprt = PCIWADDR(c->cmd);
  715. d = &c->done;
  716. d->n = Maxslots;
  717. d->m = d->n - 1;
  718. i = d->n * sizeof *d->entry;
  719. d->entry = malign(i);
  720. memset(d->entry, 0, i);
  721. d->busaddr = PCIWADDR(d->entry);
  722. c->stats = malign(sizeof *c->stats);
  723. memset(c->stats, 0, sizeof *c->stats);
  724. c->statsprt = PCIWADDR(c->stats);
  725. memmove(c->eprom, c->ram + c->ramsz - Epromsz, Epromsz-2);
  726. return setpcie(p) || parseeprom(c);
  727. }
  728. static Rx*
  729. whichrx(Ctlr *c, int sz)
  730. {
  731. if(sz <= smpool.size)
  732. return &c->sm;
  733. return &c->bg;
  734. }
  735. static Block*
  736. balloc(Rx* rx)
  737. {
  738. Block *b;
  739. ilock(rx->pool);
  740. if((b = rx->pool->head) != nil){
  741. rx->pool->head = b->next;
  742. b->next = nil;
  743. rx->pool->n--;
  744. }
  745. iunlock(rx->pool);
  746. return b;
  747. }
  748. static void
  749. smbfree(Block *b)
  750. {
  751. Bpool *p;
  752. b->rp = b->wp = (uchar*)PGROUND((uintptr)b->base);
  753. p = &smpool;
  754. ilock(p);
  755. b->next = p->head;
  756. p->head = b;
  757. p->n++;
  758. p->cnt++;
  759. iunlock(p);
  760. }
  761. static void
  762. bgbfree(Block *b)
  763. {
  764. Bpool *p;
  765. b->rp = b->wp = (uchar*)PGROUND((uintptr)b->base);
  766. p = &bgpool;
  767. ilock(p);
  768. b->next = p->head;
  769. p->head = b;
  770. p->n++;
  771. p->cnt++;
  772. iunlock(p);
  773. }
  774. static void
  775. replenish(Rx *rx)
  776. {
  777. u32int buf[16], i, idx, e;
  778. Bpool *p;
  779. Block *b;
  780. p = rx->pool;
  781. if(p->n < 8)
  782. return;
  783. memset(buf, 0, sizeof buf);
  784. e = (rx->i - rx->cnt) & ~7;
  785. e += rx->n;
  786. while(p->n >= 8 && e){
  787. idx = rx->cnt & rx->m;
  788. for(i = 0; i < 8; i++){
  789. b = balloc(rx);
  790. buf[i*2 + 1] = pbit32(PCIWADDR(b->wp));
  791. rx->host[idx+i] = b;
  792. assert(b);
  793. }
  794. memmove(rx->lanai + 2*idx, buf, sizeof buf);
  795. coherence();
  796. rx->cnt += 8;
  797. e -= 8;
  798. }
  799. if(e && p->n > 7+1)
  800. print("should panic? pool->n = %d\n", p->n);
  801. }
  802. /*
  803. * future:
  804. * if (c->mtrr >= 0) {
  805. * c->tx.wcfifo = c->ram+0x200000;
  806. * c->sm.wcfifo = c->ram+0x300000;
  807. * c->bg.wcfifo = c->ram+0x340000;
  808. * }
  809. */
  810. static int
  811. nextpow(int j)
  812. {
  813. int i;
  814. for(i = 0; j > (1<<i); i++)
  815. ;
  816. return 1 << i;
  817. }
  818. static void*
  819. emalign(int sz)
  820. {
  821. void *v;
  822. v = malign(sz);
  823. if(v == nil)
  824. error(Enomem);
  825. memset(v, 0, sz);
  826. return v;
  827. }
  828. static void
  829. open0(Ether *e, Ctlr *c)
  830. {
  831. Block *b;
  832. int i, sz, entries;
  833. entries = cmd(c, CGsendrgsz, 0)/sizeof *c->tx.lanai;
  834. c->tx.lanai = (Send*)(c->ram + cmd(c, CGsendoff, 0));
  835. c->tx.host = emalign(entries * sizeof *c->tx.host);
  836. c->tx.bring = emalign(entries * sizeof *c->tx.bring);
  837. c->tx.n = entries;
  838. c->tx.m = entries-1;
  839. entries = cmd(c, CGrxrgsz, 0)/8;
  840. c->sm.pool = &smpool;
  841. cmd(c, CSsmallsz, c->sm.pool->size);
  842. c->sm.lanai = (u32int*)(c->ram + cmd(c, CGsmallrxoff, 0));
  843. c->sm.n = entries;
  844. c->sm.m = entries-1;
  845. c->sm.host = emalign(entries * sizeof *c->sm.host);
  846. c->bg.pool = &bgpool;
  847. c->bg.pool->size = nextpow(2 + e->maxmtu); /* 2-byte alignment pad */
  848. cmd(c, CSbigsz, c->bg.pool->size);
  849. c->bg.lanai = (u32int*)(c->ram + cmd(c, CGbigrxoff, 0));
  850. c->bg.n = entries;
  851. c->bg.m = entries-1;
  852. c->bg.host = emalign(entries * sizeof *c->bg.host);
  853. sz = c->sm.pool->size + BY2PG;
  854. for(i = 0; i < c->sm.n; i++){
  855. if((b = allocb(sz)) == 0)
  856. break;
  857. b->free = smbfree;
  858. freeb(b);
  859. }
  860. sz = c->bg.pool->size + BY2PG;
  861. for(i = 0; i < c->bg.n; i++){
  862. if((b = allocb(sz)) == 0)
  863. break;
  864. b->free = bgbfree;
  865. freeb(b);
  866. }
  867. cmd(c, CSstatsdma, c->statsprt);
  868. c->linkstat = ~0;
  869. c->nrdma = 15;
  870. cmd(c, Cetherup, 0);
  871. }
  872. static Block*
  873. nextblock(Ctlr *c)
  874. {
  875. uint i;
  876. u16int l, k;
  877. Block *b;
  878. Done *d;
  879. Rx *rx;
  880. Slot *s;
  881. d = &c->done;
  882. s = d->entry;
  883. i = d->i & d->m;
  884. l = s[i].len;
  885. if(l == 0)
  886. return 0;
  887. k = s[i].cksum;
  888. *(u32int*)(s+i) = 0;
  889. d->i++;
  890. l = gbit16((uchar*)&l);
  891. //dprint("nextb: i=%d l=%d\n", d->i, l);
  892. rx = whichrx(c, l);
  893. if(rx->i >= rx->cnt){
  894. iprint("m10g: overrun\n");
  895. return 0;
  896. }
  897. i = rx->i & rx->m;
  898. b = rx->host[i];
  899. rx->host[i] = 0;
  900. if(b == 0){
  901. iprint("m10g: error rx to no block. memory is hosed.\n");
  902. return 0;
  903. }
  904. rx->i++;
  905. b->flag |= Bipck|Btcpck|Budpck;
  906. b->checksum = k;
  907. b->rp += 2;
  908. b->wp += 2+l;
  909. b->lim = b->wp; /* lie like a dog. */
  910. return b;
  911. }
  912. static int
  913. rxcansleep(void *v)
  914. {
  915. Ctlr *c;
  916. Slot *s;
  917. Done *d;
  918. c = v;
  919. d = &c->done;
  920. s = c->done.entry;
  921. if(s[d->i & d->m].len != 0)
  922. return -1;
  923. c->irqack[0] = pbit32(3);
  924. return 0;
  925. }
  926. static void
  927. m10rx(void *v)
  928. {
  929. Ether *e;
  930. Ctlr *c;
  931. Block *b;
  932. e = v;
  933. c = e->ctlr;
  934. for(;;){
  935. replenish(&c->sm);
  936. replenish(&c->bg);
  937. sleep(&c->rxrendez, rxcansleep, c);
  938. while(b = nextblock(c))
  939. etheriq(e, b, 1);
  940. }
  941. }
  942. void
  943. txcleanup(Tx *tx, u32int n)
  944. {
  945. Block *b;
  946. uint j, l, m;
  947. if(tx->npkt == n)
  948. return;
  949. l = 0;
  950. m = tx->m;
  951. /* if tx->cnt == tx->i, yet tx->npkt == n-1 we just */
  952. /* caught ourselves and myricom card updating. */
  953. for(;; tx->cnt++){
  954. j = tx->cnt & tx->m;
  955. if(b = tx->bring[j]){
  956. tx->bring[j] = 0;
  957. tx->nbytes += BLEN(b);
  958. freeb(b);
  959. if(++tx->npkt == n)
  960. return;
  961. }
  962. if(tx->cnt == tx->i)
  963. return;
  964. if(l++ == m){
  965. iprint("tx ovrun: %ud %uld\n", n, tx->npkt);
  966. return;
  967. }
  968. }
  969. }
  970. static int
  971. txcansleep(void *v)
  972. {
  973. Ctlr *c;
  974. c = v;
  975. if(c->tx.cnt != c->tx.i && c->tx.npkt != gbit32(c->stats->txcnt))
  976. return -1;
  977. return 0;
  978. }
  979. void
  980. txproc(void *v)
  981. {
  982. Ether *e;
  983. Ctlr *c;
  984. Tx *tx;
  985. e = v;
  986. c = e->ctlr;
  987. tx = &c->tx;
  988. for(;;){
  989. sleep(&c->txrendez, txcansleep, c);
  990. txcleanup(tx, gbit32(c->stats->txcnt));
  991. }
  992. }
  993. void
  994. submittx(Tx *tx, int n)
  995. {
  996. Send *l, *h;
  997. int i0, i, m;
  998. m = tx->m;
  999. i0 = tx->i & m;
  1000. l = tx->lanai;
  1001. h = tx->host;
  1002. for(i = n-1; i >= 0; i--)
  1003. memmove(l+(i + i0 & m), h+(i + i0 & m), sizeof *h);
  1004. tx->i += n;
  1005. // coherence();
  1006. }
  1007. int
  1008. nsegments(Block *b, int segsz)
  1009. {
  1010. uintptr bus, end, slen, len;
  1011. int i;
  1012. bus = PCIWADDR(b->rp);
  1013. i = 0;
  1014. for(len = BLEN(b); len; len -= slen){
  1015. end = bus + segsz & ~(segsz-1);
  1016. slen = end - bus;
  1017. if(slen > len)
  1018. slen = len;
  1019. bus += slen;
  1020. i++;
  1021. }
  1022. return i;
  1023. }
  1024. static void
  1025. m10gtransmit(Ether *e)
  1026. {
  1027. u16int slen;
  1028. u32int i, cnt, rdma, nseg, count, end, bus, len, segsz;
  1029. uchar flags;
  1030. Block *b;
  1031. Ctlr *c;
  1032. Send *s, *s0, *s0m8;
  1033. Tx *tx;
  1034. c = e->ctlr;
  1035. tx = &c->tx;
  1036. segsz = tx->segsz;
  1037. qlock(tx);
  1038. count = 0;
  1039. s = tx->host+(tx->i & tx->m);
  1040. cnt = tx->cnt;
  1041. s0 = tx->host+(cnt & tx->m);
  1042. s0m8 = tx->host+(cnt - 8 & tx->m);
  1043. i = tx->i;
  1044. for(; s >= s0 || s < s0m8; i += nseg){
  1045. if((b = qget(e->oq)) == nil)
  1046. break;
  1047. flags = SFfirst|SFnotso;
  1048. if((len = BLEN(b)) < 1520)
  1049. flags |= SFsmall;
  1050. rdma = nseg = nsegments(b, segsz);
  1051. bus = PCIWADDR(b->rp);
  1052. for(; len; len -= slen){
  1053. end = bus + segsz & ~(segsz-1);
  1054. slen = end - bus;
  1055. if(slen > len)
  1056. slen = len;
  1057. s->low = pbit32(bus);
  1058. s->len = pbit16(slen);
  1059. s->nrdma = rdma;
  1060. s->flags = flags;
  1061. bus += slen;
  1062. if(++s == tx->host + tx->n)
  1063. s = tx->host;
  1064. count++;
  1065. flags &= ~SFfirst;
  1066. rdma = 1;
  1067. }
  1068. tx->bring[i + nseg - 1 & tx->m] = b;
  1069. if(1 || count > 0){
  1070. submittx(tx, count);
  1071. count = 0;
  1072. cnt = tx->cnt;
  1073. s0 = tx->host+(cnt & tx->m);
  1074. s0m8 = tx->host+(cnt - 8 & tx->m);
  1075. }
  1076. }
  1077. qunlock(tx);
  1078. }
  1079. static void
  1080. checkstats(Ether *e, Ctlr *c, Stats *s)
  1081. {
  1082. u32int i;
  1083. if(s->updated == 0)
  1084. return;
  1085. i = gbit32(s->linkstat);
  1086. if(c->linkstat != i){
  1087. e->link = i;
  1088. if(c->linkstat = i)
  1089. dprint("m10g: link up\n");
  1090. else
  1091. dprint("m10g: link down\n");
  1092. }
  1093. i = gbit32(s->nrdma);
  1094. if(i != c->nrdma){
  1095. dprint("m10g: rdma timeout %d\n", i);
  1096. c->nrdma = i;
  1097. }
  1098. }
  1099. static void
  1100. waitintx(Ctlr *c)
  1101. {
  1102. int i;
  1103. for(i = 0; i < 1024*1024; i++){
  1104. if(c->stats->valid == 0)
  1105. break;
  1106. coherence();
  1107. }
  1108. }
  1109. static void
  1110. m10ginterrupt(Ureg *, void *v)
  1111. {
  1112. Ether *e;
  1113. Ctlr *c;
  1114. e = v;
  1115. c = e->ctlr;
  1116. if(c->state != Runed || c->stats->valid == 0) /* not ready for us? */
  1117. return;
  1118. if(c->stats->valid & 1)
  1119. wakeup(&c->rxrendez);
  1120. if(gbit32(c->stats->txcnt) != c->tx.npkt)
  1121. wakeup(&c->txrendez);
  1122. if(c->msi == 0)
  1123. *c->irqdeass = 0;
  1124. else
  1125. c->stats->valid = 0;
  1126. waitintx(c);
  1127. checkstats(e, c, c->stats);
  1128. c->irqack[1] = pbit32(3);
  1129. }
  1130. static void
  1131. m10gattach(Ether *e)
  1132. {
  1133. Ctlr *c;
  1134. char name[12];
  1135. dprint("m10gattach\n");
  1136. qlock(e->ctlr);
  1137. c = e->ctlr;
  1138. if(c->state != Detached){
  1139. qunlock(c);
  1140. return;
  1141. }
  1142. if(waserror()){
  1143. c->state = Detached;
  1144. qunlock(c);
  1145. nexterror();
  1146. }
  1147. reset(e, c);
  1148. c->state = Attached;
  1149. open0(e, c);
  1150. if(c->kprocs == 0){
  1151. c->kprocs++;
  1152. snprint(name, sizeof name, "#l%drxproc", e->ctlrno);
  1153. kproc(name, m10rx, e);
  1154. snprint(name, sizeof name, "#l%dtxproc", e->ctlrno);
  1155. kproc(name, txproc, e);
  1156. }
  1157. c->state = Runed;
  1158. qunlock(c);
  1159. poperror();
  1160. }
  1161. static int
  1162. m10gdetach(Ctlr *c)
  1163. {
  1164. dprint("m10gdetach\n");
  1165. // reset(e->ctlr);
  1166. vunmap(c->ram, c->pcidev->mem[0].size);
  1167. ctlrfree(c);
  1168. return -1;
  1169. }
  1170. static int
  1171. lstcount(Block *b)
  1172. {
  1173. int i;
  1174. i = 0;
  1175. for(; b; b = b->next)
  1176. i++;
  1177. return i;
  1178. }
  1179. static long
  1180. m10gifstat(Ether *e, void *v, long n, ulong off)
  1181. {
  1182. int l, lim;
  1183. char *p;
  1184. Ctlr *c;
  1185. Stats s;
  1186. c = e->ctlr;
  1187. lim = 2*READSTR-1;
  1188. p = malloc(lim+1);
  1189. l = 0;
  1190. /* no point in locking this because this is done via dma. */
  1191. memmove(&s, c->stats, sizeof s);
  1192. // l +=
  1193. snprint(p+l, lim,
  1194. "txcnt = %ud\n" "linkstat = %ud\n" "dlink = %ud\n"
  1195. "derror = %ud\n" "drunt = %ud\n" "doverrun = %ud\n"
  1196. "dnosm = %ud\n" "dnobg = %ud\n" "nrdma = %ud\n"
  1197. "txstopped = %ud\n" "down = %ud\n" "updated = %ud\n"
  1198. "valid = %ud\n\n"
  1199. "tx pkt = %uld\n" "tx bytes = %lld\n"
  1200. "tx cnt = %ud\n" "tx n = %ud\n" "tx i = %ud\n"
  1201. "sm cnt = %ud\n" "sm i = %ud\n" "sm n = %ud\n" "sm lst = %ud\n"
  1202. "bg cnt = %ud\n" "bg i = %ud\n" "bg n = %ud\n" "bg lst = %ud\n"
  1203. "segsz = %ud\n" "coal = %d\n",
  1204. gbit32(s.txcnt), gbit32(s.linkstat), gbit32(s.dlink),
  1205. gbit32(s.derror), gbit32(s.drunt), gbit32(s.doverrun),
  1206. gbit32(s.dnosm), gbit32(s.dnobg), gbit32(s.nrdma),
  1207. s.txstopped, s.down, s.updated, s.valid,
  1208. c->tx.npkt, c->tx.nbytes,
  1209. c->tx.cnt, c->tx.n, c->tx.i,
  1210. c->sm.cnt, c->sm.i, c->sm.pool->n, lstcount(c->sm.pool->head),
  1211. c->bg.cnt, c->bg.i, c->bg.pool->n, lstcount(c->bg.pool->head),
  1212. c->tx.segsz, gbit32((uchar*)c->coal));
  1213. n = readstr(off, v, n, p);
  1214. free(p);
  1215. return n;
  1216. }
  1217. //void
  1218. //summary(Ether *e)
  1219. //{
  1220. // char *buf;
  1221. // int n, i, j;
  1222. //
  1223. // if(e == 0)
  1224. // return;
  1225. // buf = malloc(n=250);
  1226. // if(buf == 0)
  1227. // return;
  1228. //
  1229. // snprint(buf, n, "oq\n");
  1230. // qsummary(e->oq, buf+3, n-3-1);
  1231. // iprint("%s", buf);
  1232. //
  1233. // if(e->f) for(i = 0; e->f[i]; i++){
  1234. // j = snprint(buf, n, "f%d %d\n", i, e->f[i]->type);
  1235. // qsummary(e->f[i]->in, buf+j, n-j-1);
  1236. // print("%s", buf);
  1237. // }
  1238. //
  1239. // free(buf);
  1240. //}
  1241. void
  1242. rxring(Ctlr *c)
  1243. {
  1244. Done *d;
  1245. Slot *s;
  1246. int i;
  1247. d = &c->done;
  1248. s = d->entry;
  1249. for(i = 0; i < d->n; i++)
  1250. if(s[i].len)
  1251. iprint("s[%d] = %d\n", i, s[i].len);
  1252. }
  1253. enum {
  1254. CMdebug,
  1255. CMcoal,
  1256. CMwakeup,
  1257. CMtxwakeup,
  1258. CMqsummary,
  1259. CMrxring,
  1260. };
  1261. static Cmdtab ctab[] = {
  1262. CMdebug, "debug", 2,
  1263. CMcoal, "coal", 2,
  1264. CMwakeup, "wakeup", 1,
  1265. CMtxwakeup, "txwakeup", 1,
  1266. // CMqsummary, "q", 1,
  1267. CMrxring, "rxring", 1,
  1268. };
  1269. static long
  1270. m10gctl(Ether *e, void *v, long n)
  1271. {
  1272. int i;
  1273. Cmdbuf *c;
  1274. Cmdtab *t;
  1275. dprint("m10gctl\n");
  1276. if(e->ctlr == nil)
  1277. error(Enonexist);
  1278. c = parsecmd(v, n);
  1279. if(waserror()){
  1280. free(c);
  1281. nexterror();
  1282. }
  1283. t = lookupcmd(c, ctab, nelem(ctab));
  1284. switch(t->index){
  1285. case CMdebug:
  1286. if(strcmp(c->f[1], "on") == 0)
  1287. debug = 1;
  1288. else
  1289. debug = 0;
  1290. break;
  1291. case CMcoal:
  1292. i = atoi(c->f[1]);
  1293. if(i < 0 || i > 1000)
  1294. error(Ebadarg);
  1295. *((Ctlr*)e->ctlr)->coal = pbit32(i);
  1296. break;
  1297. case CMwakeup:
  1298. wakeup(&((Ctlr*)e->ctlr)->rxrendez); /* you're kidding, right? */
  1299. break;
  1300. case CMtxwakeup:
  1301. wakeup(&((Ctlr*)e->ctlr)->txrendez); /* you're kidding, right? */
  1302. break;
  1303. // case CMqsummary:
  1304. // summary(e);
  1305. // break;
  1306. case CMrxring:
  1307. rxring(e->ctlr);
  1308. break;
  1309. default:
  1310. error(Ebadarg);
  1311. }
  1312. free(c);
  1313. poperror();
  1314. return n;
  1315. }
  1316. static void
  1317. m10gshutdown(Ether *e)
  1318. {
  1319. dprint("m10gshutdown\n");
  1320. m10gdetach(e->ctlr);
  1321. }
  1322. static void
  1323. m10gpromiscuous(void *v, int on)
  1324. {
  1325. Ether *e;
  1326. int i;
  1327. dprint("m10gpromiscuous\n");
  1328. e = v;
  1329. if(on)
  1330. i = Cpromisc;
  1331. else
  1332. i = Cnopromisc;
  1333. cmd(e->ctlr, i, 0);
  1334. }
  1335. static int mcctab[] = { CSleavemc, CSjoinmc };
  1336. static char *mcntab[] = { "leave", "join" };
  1337. static void
  1338. m10gmulticast(void *v, uchar *ea, int on)
  1339. {
  1340. Ether *e;
  1341. int i;
  1342. dprint("m10gmulticast\n");
  1343. e = v;
  1344. if((i = maccmd(e->ctlr, mcctab[on], ea)) != 0)
  1345. print("m10g: can't %s %E: %d\n", mcntab[on], ea, i);
  1346. }
  1347. static void
  1348. m10gpci(void)
  1349. {
  1350. Pcidev *p;
  1351. Ctlr *t, *c;
  1352. t = 0;
  1353. for(p = 0; p = pcimatch(p, 0x14c1, 0x0008); ){
  1354. c = malloc(sizeof *c);
  1355. if(c == nil)
  1356. continue;
  1357. memset(c, 0, sizeof *c);
  1358. c->pcidev = p;
  1359. c->id = p->did<<16 | p->vid;
  1360. c->boot = pcicap(p, PciCapVND);
  1361. // kickthebaby(p, c);
  1362. pcisetbme(p);
  1363. if(setmem(p, c) == -1){
  1364. print("m10g failed\n");
  1365. free(c);
  1366. /* cleanup */
  1367. continue;
  1368. }
  1369. if(t)
  1370. t->next = c;
  1371. else
  1372. ctlrs = c;
  1373. t = c;
  1374. }
  1375. }
  1376. static int
  1377. m10gpnp(Ether *e)
  1378. {
  1379. Ctlr *c;
  1380. if(ctlrs == nil)
  1381. m10gpci();
  1382. for(c = ctlrs; c != nil; c = c->next)
  1383. if(c->active)
  1384. continue;
  1385. else if(e->port == 0 || e->port == c->port)
  1386. break;
  1387. if(c == nil)
  1388. return -1;
  1389. c->active = 1;
  1390. e->ctlr = c;
  1391. e->port = c->port;
  1392. e->irq = c->pcidev->intl;
  1393. e->tbdf = c->pcidev->tbdf;
  1394. e->mbps = 10000;
  1395. memmove(e->ea, c->ra, Eaddrlen);
  1396. e->attach = m10gattach;
  1397. e->detach = m10gshutdown;
  1398. e->transmit = m10gtransmit;
  1399. e->interrupt = m10ginterrupt;
  1400. e->ifstat = m10gifstat;
  1401. e->ctl = m10gctl;
  1402. // e->power = m10gpower;
  1403. e->shutdown = m10gshutdown;
  1404. e->arg = e;
  1405. e->promiscuous = m10gpromiscuous;
  1406. e->multicast = m10gmulticast;
  1407. return 0;
  1408. }
  1409. void
  1410. etherm10glink(void)
  1411. {
  1412. addethercard("m10g", m10gpnp);
  1413. }