ethervgbe.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * VIA Velocity gigabit ethernet.
  11. * Register info has been stolen from FreeBSD driver.
  12. *
  13. * Has been tested on:
  14. * - VIA8237 (ABIT AV8): 100Mpbs Full duplex only.
  15. * It works enough to run replica/pull, vncv, ...
  16. *
  17. * To do:
  18. * - 64/48 bits
  19. * - autonegotiation
  20. * - thresholds
  21. * - dynamic ring sizing ??
  22. * - link status change
  23. * - shutxbufown
  24. * - promiscuous
  25. * - report error
  26. * - Rx/Tx Csum
  27. * - Jumbo frames
  28. *
  29. * Philippe Anel, xigh@free.fr
  30. */
  31. #include "u.h"
  32. #include "lib.h"
  33. #include "mem.h"
  34. #include "dat.h"
  35. #include "fns.h"
  36. #include "io.h"
  37. #include "etherif.h"
  38. #include "ethermii.h"
  39. #define DEBUG
  40. enum
  41. {
  42. DumpIntr = (1<<0),
  43. DumpRx = (1<<1),
  44. DumpTx = (1<<2),
  45. };
  46. #define htole16(x) (x)
  47. #define htole32(x) (x)
  48. #define le32toh(x) (x)
  49. enum
  50. {
  51. Timeout = 50000, // 10000000, //
  52. RxCount = 16,
  53. TxCount = 4,
  54. RxSize = 2048,
  55. EthAddr = 0x00,
  56. /* Command registers. */
  57. Cr0S = 0x08, /* Global command 0 (Set) */
  58. Cr0C = 0x0c, /* Global command 0 (Clear) */
  59. Cr0_Start = 0x01, /* - start MAC */
  60. Cr0_Stop = 0x02, /* - stop MAC */
  61. Cr0_EnableRx = 0x04, /* - turn on Rx engine */
  62. Cr0_EnableTx = 0x08, /* - turn on Tx engine */
  63. Cr1S = 0x09, /* Global command 1 (Set) */
  64. Cr1C = 0x0d, /* Global command 1 (Clear) */
  65. Cr1_NoPool = 0x08, /* - disable Rx/Tx desc pool */
  66. Cr1_reset = 0x80, /* - software reset */
  67. Cr2S = 0x0a, /* Global command 2 (Set) */
  68. Cr2_XonEnable = 0x80, /* - 802.3x XON/XOFF flow control */
  69. Cr3S = 0x0b, /* Global command 3 (Set) */
  70. Cr3C = 0x0f, /* Global command 3 (Set) */
  71. Cr3_IntMask = 0x02, /* - Mask all interrupts */
  72. /* Eeprom registers. */
  73. Eecsr = 0x93, /* EEPROM control/status */
  74. Eecsr_Autold = 0x20, /* - trigger reload from EEPROM */
  75. /* Mii registers. */
  76. MiiStatus = 0x6D, /* MII port status */
  77. MiiStatus_idle = 0x80, /* - idle */
  78. MiiCmd = 0x70, /* MII command */
  79. MiiCmd_write = 0x20, /* - write */
  80. MiiCmd_read = 0x40, /* - read */
  81. MiiCmd_auto = 0x80, /* - enable autopolling */
  82. MiiAddr = 0x71, /* MII address */
  83. MiiData = 0x72, /* MII data */
  84. /* 64 bits related registers. */
  85. TdHi = 0x18,
  86. DataBufHi = 0x1d,
  87. /* Rx engine registers. */
  88. RdLo = 0x38, /* Rx descriptor base address (lo 32 bits) */
  89. RxCsrS = 0x32, /* Rx descriptor queue control/status (Set) */
  90. RxCsrC = 0x36, /* Rx descriptor queue control/status (Clear) */
  91. RxCsr_RunQueue = 0x01, /* - enable queue */
  92. RxCsr_Active = 0x02, /* - queue active indicator */
  93. RxCsr_Wakeup = 0x04, /* - wake up queue */
  94. RxCsr_Dead = 0x08, /* - queue dead indicator */
  95. Rdcsize = 0x50, /* Size of Rx desc ring */
  96. Rdindex = 0x3c, /* Current Rx descriptor index */
  97. RxResCnt = 0x5e, /* Rx descriptor residue count */
  98. Txesr = 0x22,
  99. Tfdbs = (1<<19),
  100. Tdwbs = (1<<18),
  101. Tdrbs = (1<<17),
  102. Tdstr = (1<<16),
  103. Rxesr = 0x23, /* Rx host error status */
  104. Rfdbs = (1<<19),
  105. Rdwbs = (1<<18),
  106. Rdrbs = (1<<17),
  107. Rdstr = (1<<16),
  108. RxTimer = 0x3e, /* Rx queue timer pend */
  109. RxControl = 0x06, /* MAC Rx control */
  110. RxControl_BadFrame = 0x01, /* - accept CRC error frames */
  111. RxControl_Runt = 0x02, /* - accept runts */
  112. RxControl_MultiCast = 0x04, /* - accept multicasts */
  113. RxControl_BroadCast = 0x08, /* - accept broadcasts */
  114. RxControl_Promisc = 0x10, /* - promisc mode */
  115. RxControl_Giant = 0x20, /* - accept VLAN tagged frames */
  116. RxControl_UniCast = 0x40, /* - use perfect filtering */
  117. RxControl_SymbolErr = 0x80, /* - accept symbol err packet */
  118. RxConfig = 0x7e, /* MAC Rx config */
  119. RxConfig_VlanFilter = 0x01, /* - filter VLAN ID mismatches */
  120. RxConfig_VlanOpt0 = (0<<1), /* - TX: no tag insert, RX: all, no extr */
  121. RxConfig_VlanOpt1 = (1<<1), /* - TX: no tag insert, RX: tagged pkts, no extr */
  122. RxConfig_VlanOpt2 = (2<<1), /* - TX: tag insert, RX: all, extract tags */
  123. RxConfig_VlanOpt3 = (3<<1), /* - TX: tag insert, RX: tagged pkts, with extr */
  124. RxConfig_FifoLowWat = 0x08, /* - RX FIFO low watermark (7QW/15QW) */
  125. RxConfig_FifoTh128 = (0<<4), /* - RX FIFO threshold 128 bytes */
  126. RxConfig_FifoTh512 = (1<<4), /* - RX FIFO threshold 512 bytes */
  127. RxConfig_FifoTh1024 = (2<<4), /* - RX FIFO threshold 1024 bytes */
  128. RxConfig_FifoThFwd = (3<<4), /* - RX FIFO threshold ??? */
  129. RxConfig_ArbPrio = 0x80, /* - arbitration priority */
  130. /* Tx engine registers. */
  131. TdLo = 0x40, /* Tx descriptor base address (lo 32 bits) */
  132. TxCsrS = 0x30, /* Tx descriptor queue control/status (Set) */
  133. TxCsrC = 0x38, /* Tx descriptor queue control/status (Clear) */
  134. TxCsr_RunQueue = 0x01, /* - enable queue */
  135. TxCsr_Active = 0x02, /* - queue active indicator */
  136. TxCsr_Wakeup = 0x04, /* - wake up queue */
  137. TxCsr_Dead = 0x08, /* - queue dead indicator */
  138. TxNum = 0x52, /* Size of Tx desc ring */
  139. TxDscIdx = 0x54, /* Current Tx descriptor index */
  140. TxHostErr = 0x22, /* Tx host error status */
  141. TxTimer = 0x3f, /* Tx queue timer pend */
  142. TxControl = 0x07, /* MAC Rx control */
  143. TxControl_LC_Off = (0<<0), /* - loopback control off */
  144. TxControl_LC_Mac = (1<<0), /* - loopback control MAC internal */
  145. TxControl_LC_Ext = (2<<0), /* - loopback control external */
  146. TxControl_Coll16 = (0<<2), /* - one set of 16 retries */
  147. TxControl_Coll32 = (1<<2), /* - two sets of 16 retries */
  148. TxControl_Coll48 = (2<<2), /* - three sets of 16 retries */
  149. TxControl_CollInf = (3<<2), /* - retry forever */
  150. TxConfig = 0x7f, /* MAC Tx config */
  151. TxConfig_SnapOpt = 0x01, /* - 1 == insert VLAN tag at 13th byte, */
  152. /* 0 == insert VLAN tag after SNAP header (21st byte) */
  153. TxConfig_NonBlk = 0x02, /* - priority TX/non-blocking mode */
  154. TxConfig_Blk64 = (0<<3), /* - non-blocking threshold 64 packets */
  155. TxConfig_Blk32 = (1<<3), /* - non-blocking threshold 32 packets */
  156. TxConfig_Blk128 = (2<<3), /* - non-blocking threshold 128 packets */
  157. TxConfig_Blk8 = (3<<3), /* - non-blocking threshold 8 packets */
  158. TxConfig_ArbPrio = 0x80, /* - arbitration priority */
  159. /* Timer registers. */
  160. Timer0 = 0x74, /* single-shot timer */
  161. Timer1 = 0x76, /* periodic timer */
  162. /* Chip config registers. */
  163. ChipCfgA = 0x78, /* chip config A */
  164. ChipCfgB = 0x79, /* chip config B */
  165. ChipCfgC = 0x7a, /* chip config C */
  166. ChipCfgD = 0x7b, /* chip config D */
  167. /* DMA config registers. */
  168. DmaCfg0 = 0x7C, /* DMA config 0 */
  169. DmaCfg1 = 0x7D, /* DMA config 1 */
  170. /* Interrupt registers. */
  171. IntCtl = 0x20, /* Interrupt control */
  172. Imr = 0x28, /* Interrupt mask */
  173. isr = 0x24, /* Interrupt status */
  174. Pprx = (1<<0), /* - hi prio Rx int */
  175. Pptx = (1<<1), /* - hi prio Tx int */
  176. Prx = (1<<2), /* - Rx queue completed */
  177. Ptx = (1<<3), /* - One of Tx queues completed */
  178. Ptx0 = (1<<4), /* - Tx queue 0 completed */
  179. Ptx1 = (1<<5), /* - Tx queue 1 completed */
  180. Ptx2 = (1<<6), /* - Tx queue 2 completed */
  181. Ptx3 = (1<<7), /* - Tx queue 3 completed */
  182. isr_Reserved8 = (1<<8), /* - reserved */
  183. isr_Reserver9 = (1<<9), /* - reserved */
  184. Race = (1<<10), /* - Rx packet count overflow */
  185. Flon = (1<<11), /* - pause frame Rx */
  186. Ovf = (1<<12), /* - RX FIFO overflow */
  187. Lste = (1<<13), /* - ran out of Rx descriptors */
  188. Lstpe = (1<<14), /* - running out of Rx descriptors */
  189. Src = (1<<15), /* - link status change */
  190. Tmr0 = (1<<16), /* - one shot timer expired */
  191. Tmr1 = (1<<17), /* - periodic timer expired */
  192. Pwe = (1<<18), /* - wake up power event */
  193. Phyint = (1<<19), /* - PHY interrupt */
  194. Shdn = (1<<20), /* - software shutxbufown complete */
  195. isr_MibOvflow = (1<<21), /* - MIB counter overflow warning */
  196. isr_SoftIntr = (1<<22), /* - software interrupt */
  197. isr_HoldOffReload = (1<<23), /* - reload hold timer */
  198. Rxstl = (1<<24), /* - Rx DMA stall */
  199. Txstl = (1<<25), /* - Tx DMA stall */
  200. isr_Reserved26 = (1<<26), /* - reserved */
  201. isr_Reserved27 = (1<<27), /* - reserved */
  202. Isr0 = (1<<28), /* - interrupt source indication */
  203. Isr1 = (1<<29), /* - interrupt source indication */
  204. Isr2 = (1<<30), /* - interrupt source indication */
  205. Isr3 = (1<<31), /* - interrupt source indication */
  206. isr_Mask = Ptx0|Prx|Shdn|
  207. Ovf|Phyint|Src|
  208. Lste|Rxstl|Txstl
  209. };
  210. typedef struct Frag Frag;
  211. struct Frag
  212. {
  213. uint32_t addr_lo;
  214. uint16_t addr_hi;
  215. uint16_t length;
  216. };
  217. typedef struct Rd Rd;
  218. struct Rd
  219. {
  220. uint32_t status;
  221. uint32_t control;
  222. Frag;
  223. };
  224. typedef struct Td Td;
  225. struct Td
  226. {
  227. uint32_t status;
  228. uint32_t control;
  229. Frag frags[7];
  230. };
  231. enum
  232. {
  233. Vidm = (1<<0), /* VLAN tag filter miss */
  234. Crc = (1<<1), /* bad CRC error */
  235. Fae = (1<<3), /* frame alignment error */
  236. Ce = (1<<3), /* bad TCP/IP checksum */
  237. Rl = (1<<4), /* Rx length error */
  238. Rxer = (1<<5), /* PCS symbol error */
  239. Sntag = (1<<6), /* RX'ed tagged SNAP pkt */
  240. Detag = (1<<7), /* VLAN tag extracted */
  241. RDOneFrag = (0<<8), /* only one fragment */
  242. RDFirstFrag = (1<<8), /* first frag in frame */
  243. RDLastFrag = (2<<8), /* last frag in frame */
  244. RDMidFrag = (3<<8), /* intermediate frag */
  245. Vtag = (1<<10), /* VLAN tag indicator */
  246. Phy = (1<<11), /* unicast frame */
  247. Bar = (1<<12), /* broadcast frame */
  248. Mar = (1<<13), /* multicast frame */
  249. Pft = (1<<14), /* perfect filter hit */
  250. Rxok = (1<<15), /* frame is good. */
  251. RDSizShift = 16, /* received frame len shift */
  252. RDSizMask = 0x3FFF, /* received frame len mask */
  253. RDShutxbufown = (1<<30), /* shutxbufown during RX */
  254. Own = (1<<31), /* own bit */
  255. /* ... */
  256. /* ... */
  257. Td_Control_Intr = (1<<23), /* Tx intr request */
  258. Td_Control_Normal = (3<<24), /* normal frame */
  259. };
  260. typedef struct Stats Stats;
  261. struct Stats
  262. {
  263. uint32_t rx;
  264. uint32_t tx;
  265. uint32_t txe;
  266. uint32_t intr;
  267. };
  268. enum {
  269. Rblen64K = 0x00001800, /* 64KB+16 */
  270. Rblen = Rblen64K, /* Receive Buffer Length */
  271. Tdbsz = ROUNDUP(sizeof(Etherpkt), 4),
  272. };
  273. typedef struct Ctlr Ctlr;
  274. struct Ctlr
  275. {
  276. int port;
  277. Pcidev* pcidev;
  278. Ctlr *next;
  279. int id;
  280. int inited;
  281. Lock ilock;
  282. uint32_t debugflags;
  283. uint32_t debugcount;
  284. Mii* mii;
  285. int active;
  286. uint8_t ea[6];
  287. Rd* rdring;
  288. uint8_t* rxbuf[RxCount];
  289. Lock tlock;
  290. Td* td;
  291. uint8_t txpkt[TxCount][sizeof(Etherpkt)];
  292. uint32_t tx_count;
  293. Stats stats;
  294. };
  295. static Ctlr* vgbectlrhead;
  296. static Ctlr* vgbectlrtail;
  297. #define riob(c, r) inb((c)->port + (r))
  298. #define riow(c, r) ins((c)->port + (r))
  299. #define riol(c, r) inl((c)->port + (r))
  300. #define wiob(c, r, d) outb((c)->port + (r), (d))
  301. #define wiow(c, r, d) outs((c)->port + (r), (d))
  302. #define wiol(c, r, d) outl((c)->port + (r), (d))
  303. #define siob(c, r, b) wiob((c), (r), riob((c), (r)) | (b))
  304. #define siow(c, r, b) wiow((c), (r), riob((c), r) | b)
  305. #define siol(c, r, b) wiol(c, r, riob(c, r) | b)
  306. #define ciob(c, r, b) wiob(c, r, riob(c, r) & ~b)
  307. #define ciow(c, r, b) wiow(c, r, riob(c, r) & ~b)
  308. #define ciol(c, r, b) wiol(c, r, riob(c, r) & ~b)
  309. static int
  310. vgbemiiw(Mii* mii, int phy, int addr, int data)
  311. {
  312. Ctlr* ctlr;
  313. int i;
  314. if(phy != 1)
  315. return -1;
  316. ctlr = mii->ctlr;
  317. // write our addr to the Mii
  318. wiob(ctlr, MiiAddr, addr);
  319. // write our data to the Mii data reg
  320. wiow(ctlr, MiiData, (uint16_t) data);
  321. wiob(ctlr, MiiCmd, MiiCmd_write);
  322. // poll the mii
  323. for(i = 0; i < Timeout; i++)
  324. if((riob(ctlr, MiiCmd) & MiiCmd_write) == 0)
  325. break;
  326. if(i >= Timeout){
  327. print("vgbe: miiw timeout\n");
  328. return -1;
  329. }
  330. return 0;
  331. }
  332. static int
  333. vgbemiir(Mii* mii, int phy, int addr)
  334. {
  335. Ctlr* ctlr;
  336. int i;
  337. if(phy != 1)
  338. return -1;
  339. ctlr = mii->ctlr;
  340. wiob(ctlr, MiiAddr, addr);
  341. wiob(ctlr, MiiCmd, MiiCmd_read);
  342. for(i = 0; i < Timeout; i++)
  343. if((riob(ctlr, MiiCmd) & MiiCmd_read) == 0)
  344. break;
  345. if(i >= Timeout){
  346. print("vgbe: miir timeout\n");
  347. return -1;
  348. }
  349. return riow(ctlr, MiiData);
  350. }
  351. static char* vgbeisr_info[] = {
  352. "hi prio Rx int",
  353. "hi prio Tx int",
  354. "Rx queue completed",
  355. "One of Tx queues completed",
  356. "Tx queue 0 completed",
  357. "Tx queue 1 completed",
  358. "Tx queue 2 completed",
  359. "Tx queue 3 completed",
  360. "reserved",
  361. "reserved",
  362. "Rx packet count overflow",
  363. "pause frame Rx'ed",
  364. "RX FIFO overflow",
  365. "ran out of Rx descriptors",
  366. "running out of Rx descriptors",
  367. "link status change",
  368. "one shot timer expired",
  369. "periodic timer expired",
  370. "wake up power event",
  371. "PHY interrupt",
  372. "software shutxbufown complete",
  373. "MIB counter overflow warning",
  374. "software interrupt",
  375. "reload hold timer",
  376. "Rx DMA stall",
  377. "Tx DMA stall",
  378. "reserved",
  379. "reserved",
  380. "interrupt source indication 0",
  381. "interrupt source indication 1",
  382. "interrupt source indication 2",
  383. "interrupt source indication 3",
  384. };
  385. static void
  386. vgbedumpisr(uint32_t isr)
  387. {
  388. int i;
  389. uint32_t mask;
  390. for(i = 0; i < 32; i++){
  391. mask = 1<<i;
  392. if(isr & mask)
  393. print("vgbe: irq: - %02d : %c %s\n", i,
  394. isr_Mask & mask ? '*' : '-', vgbeisr_info[i]);
  395. }
  396. }
  397. static void
  398. noop(Block *)
  399. {
  400. }
  401. static int
  402. vgbenewrx(Ether* edev, int i)
  403. {
  404. Rd* rd;
  405. uint8_t *rb;
  406. Ctlr* ctlr;
  407. ctlr = edev->ctlr;
  408. /*
  409. * allocate a receive Block. we're maintaining
  410. * a private pool of Blocks, so we don't want freeb
  411. * to actually free them, thus we set block->free.
  412. */
  413. rb = mallocz(RxSize, 1);
  414. rb = (uint8_t*)ROUNDUP((uint32_t)rb, 64);
  415. ctlr->rxbuf[i] = rb;
  416. /* Initialize Rx descriptor. (TODO: 48/64 bits support ?) */
  417. rd = &ctlr->rdring[i];
  418. rd->status = htole32(Own);
  419. rd->control = htole32(0);
  420. rd->addr_lo = htole32((uint32_t)PADDR(rb));
  421. rd->addr_hi = htole16(0);
  422. rd->length = htole16(RxSize | 0x8000);
  423. return 0;
  424. }
  425. static void
  426. toringbuf(Ether* edev, uint8_t* data, int len)
  427. {
  428. RingBuf *rb;
  429. extern int interesting(void*);
  430. if(!interesting(data))
  431. return;
  432. rb = &edev->rb[edev->ri];
  433. if(rb->owner == Interface){
  434. if(len > sizeof(rb->pkt))
  435. len = sizeof(rb->pkt);
  436. rb->len = len;
  437. memmove(rb->pkt, data, rb->len);
  438. rb->owner = Host;
  439. edev->ri = NEXT(edev->ri, edev->nrb);
  440. }
  441. else if(debug){
  442. print("#l%d: toringbuf: dropping packets @ ri %d\n",
  443. edev->ctlrno, edev->ri);
  444. }
  445. }
  446. static void
  447. vgberxeof(Ether* edev)
  448. {
  449. Ctlr* ctlr;
  450. int i;
  451. uint32_t length, status;
  452. Rd* rd;
  453. uint8_t *rb;
  454. ctlr = edev->ctlr;
  455. if(ctlr->debugflags & DumpRx)
  456. print("vgbe: rx_eof\n");
  457. for(i = 0; i < RxCount; i++){
  458. rd = &ctlr->rdring[i];
  459. status = le32toh(rd->status);
  460. if(status & Own)
  461. continue;
  462. if(status & Rxok){
  463. if(ctlr->debugflags & DumpRx)
  464. print("vgbe: Receive successful!\n");
  465. length = status >> RDSizShift;
  466. length &= RDSizMask;
  467. if(ctlr->debugflags & DumpRx)
  468. print("vgbe: Rx-rd[%03d] status=%#08ulx ctl=%#08ulx len=%uld bytes\n",
  469. i, status, rd->control, length);
  470. rb = ctlr->rxbuf[i];
  471. ctlr->stats.rx++;
  472. if(ctlr->debugflags & DumpRx){
  473. print("&edev->rb[edev->ri] %ulx rb %ulx length %uld\n", &edev->rb[edev->ri], rb, length);
  474. for(i = 0; i < length; i++)
  475. print("%x ", rb[i]);
  476. print("\n");
  477. }
  478. toringbuf(edev, rb, length);
  479. }else
  480. print("vgbe: Rx-rd[%#02x] *BAD FRAME* status=%#08ulx ctl=%#08ulx\n",
  481. i, status, rd->control);
  482. /* reset packet ... */
  483. rd->status = htole32(Own);
  484. rd->control = htole32(0);
  485. }
  486. if(ctlr->debugflags & DumpRx)
  487. print("vgbe: rx_eof: done\n");
  488. wiow(ctlr, RxResCnt, RxCount);
  489. wiob(ctlr, RxCsrS, RxCsr_Wakeup);
  490. }
  491. static void
  492. vgbetxeof(Ether* edev)
  493. {
  494. Ctlr* ctlr;
  495. int i, count;
  496. uint32_t status;
  497. ctlr = edev->ctlr;
  498. ilock(&ctlr->tlock);
  499. if(ctlr->debugflags & DumpTx)
  500. print("vgbe: tx_eof\n");
  501. for(count = 0, i = 0; i < TxCount; i++){
  502. status = le32toh(ctlr->td[i].status);
  503. if(status & Own)
  504. continue;
  505. /* Todo add info if it failed */
  506. ctlr->stats.tx++;
  507. count++;
  508. }
  509. ctlr->tx_count -= count;
  510. if(ctlr->debugflags & DumpTx)
  511. print("vgbe: tx_eof: done [count=%d]\n", count);
  512. iunlock(&ctlr->tlock);
  513. if(ctlr->tx_count)
  514. wiob(ctlr, TxCsrS, TxCsr_Wakeup);
  515. }
  516. static void
  517. vgbetransmit(Ether* edev)
  518. {
  519. uint8_t *pkt;
  520. Ctlr* ctlr;
  521. int i, index, start, count;
  522. Td* desc;
  523. RingBuf *rb;
  524. uint32_t status, length;
  525. ctlr = edev->ctlr;
  526. ilock(&ctlr->tlock);
  527. /* find empty slot */
  528. start = riow(ctlr, TxDscIdx);
  529. for(count = 0, i = 0; i < TxCount; i++){
  530. index = (i + start) % TxCount;
  531. desc = &ctlr->td[index];
  532. status = le32toh(desc->status);
  533. if(status & Own)
  534. continue;
  535. rb = &edev->tb[edev->ti];
  536. if(rb->owner != Interface)
  537. break;
  538. pkt = ctlr->txpkt[index];
  539. length = rb->len;
  540. memmove(pkt, rb->pkt, length);
  541. count++;
  542. /* Initialize Tx descriptor. */
  543. desc->status = htole32((length<<16)|Own);
  544. desc->control = htole32(Td_Control_Intr|Td_Control_Normal|((1+1)<<28));
  545. desc->frags[0].addr_lo = htole32((uint32_t) PCIWADDR(pkt));
  546. desc->frags[0].addr_hi = htole16(0);
  547. desc->frags[0].length = htole16(length);
  548. rb->owner = Host;
  549. edev->ti = NEXT(edev->ti, edev->ntb);
  550. }
  551. ctlr->tx_count += count;
  552. if(ctlr->debugflags & DumpTx)
  553. print("vgbe: transmit: done [count=%d]\n", count);
  554. iunlock(&ctlr->tlock);
  555. if(ctlr->tx_count)
  556. wiob(ctlr, TxCsrS, TxCsr_Wakeup);
  557. if(count == 0)
  558. print("vgbe: transmit: no Tx entry available\n");
  559. }
  560. static void
  561. vgbeattach(Ether* edev)
  562. {
  563. Ctlr* ctlr;
  564. Rd* rd;
  565. Td* td;
  566. int i;
  567. ctlr = edev->ctlr;
  568. // ctlr->debugflags |= DumpRx;
  569. // ctlr->debugflags |= DumpRx|DumpTx;
  570. // XXX: lock occurs in init
  571. lock(&ctlr->ilock);
  572. if(ctlr->inited){
  573. unlock(&ctlr->ilock);
  574. return;
  575. }
  576. // print("vgbe: attach\n");
  577. /* Allocate Rx ring. (TODO: Alignment ?) */
  578. /*
  579. ctlr->rblen == RxCount
  580. ctlr->alloc = rd
  581. */
  582. // he's making
  583. rd = mallocalign(RxCount* sizeof(Rd), 256, 0, 0);
  584. if(rd == nil){
  585. print("vgbe: unable to alloc Rx ring\n");
  586. unlock(&ctlr->ilock);
  587. return;
  588. }
  589. ctlr->rdring = rd;
  590. /* Allocate Rx blocks, initialize Rx ring. */
  591. for(i = 0; i < RxCount; i++)
  592. vgbenewrx(edev, i);
  593. /* Init Rx MAC. */
  594. wiob(ctlr, RxControl,
  595. RxControl_MultiCast|RxControl_BroadCast|RxControl_UniCast);
  596. wiob(ctlr, RxConfig, RxConfig_VlanOpt0);
  597. /* Load Rx ring. */
  598. wiol(ctlr, RdLo, (uint32_t) PCIWADDR(rd));
  599. wiow(ctlr, Rdcsize, RxCount - 1);
  600. wiow(ctlr, Rdindex, 0);
  601. wiow(ctlr, RxResCnt, RxCount);
  602. /* Allocate Tx ring. */
  603. td = mallocalign(TxCount* sizeof(Td), 256, 0, 0);
  604. if(td == nil){
  605. print("vgbe: unable to alloc Tx ring\n");
  606. unlock(&ctlr->ilock);
  607. return;
  608. }
  609. ctlr->td = td;
  610. /* Init DMAs */
  611. wiob(ctlr, DmaCfg0, 4);
  612. /* Init Tx MAC. */
  613. wiob(ctlr, TxControl, 0);
  614. wiob(ctlr, TxConfig, TxConfig_NonBlk|TxConfig_ArbPrio);
  615. /* Load Tx ring. */
  616. wiol(ctlr, TdLo, (uint32_t) PCIWADDR(td));
  617. wiow(ctlr, TxNum, TxCount - 1);
  618. wiow(ctlr, TxDscIdx, 0);
  619. /* Enable Xon/Xoff */
  620. wiob(ctlr, Cr2S, 0xb|Cr2_XonEnable);
  621. /* Enable Rx queue */
  622. wiob(ctlr, RxCsrS, RxCsr_RunQueue);
  623. /* Enable Tx queue */
  624. wiob(ctlr, TxCsrS, TxCsr_RunQueue);
  625. /* Done */
  626. ctlr->inited = 1;
  627. unlock(&ctlr->ilock);
  628. /* Enable interrupts */
  629. wiol(ctlr, isr, 0xffffffff);
  630. wiob(ctlr, Cr3S, Cr3_IntMask);
  631. /* Wake up Rx queue */
  632. wiob(ctlr, RxCsrS, RxCsr_Wakeup);
  633. }
  634. static int
  635. vgbereset(Ctlr* ctlr)
  636. {
  637. // MiiPhy* phy;
  638. int timeo, i;
  639. // print("vgbe: reset: cr1s port: %x contents: %x\n", ctlr->port + Cr1S, riob(ctlr, Cr1S));
  640. /* Soft reset the controller. */
  641. wiob(ctlr, Cr1S, Cr1_reset);
  642. for(timeo = 0; timeo < Timeout; timeo++)
  643. if((riob(ctlr, Cr1S) & Cr1_reset) == 0)
  644. break;
  645. if(timeo >= Timeout){
  646. print("vgbe: softreset timeout\n");
  647. return -1;
  648. }
  649. /* Reload eeprom. */
  650. siob(ctlr, Eecsr, Eecsr_Autold);
  651. for(timeo = 0; timeo < Timeout; timeo++)
  652. if((riob(ctlr, Eecsr) & Eecsr_Autold) == 0)
  653. break;
  654. if(timeo >= Timeout){
  655. print("vgbe: eeprom reload timeout\n");
  656. return -1;
  657. }
  658. /* Load the MAC address. */
  659. for(i = 0; i < Eaddrlen; i++)
  660. ctlr->ea[i] = riob(ctlr, EthAddr+i);
  661. // print("vgbe: EA %E\n", ctlr->ea);
  662. /* Initialize interrupts. */
  663. wiol(ctlr, isr, 0xffffffff);
  664. wiol(ctlr, Imr, 0xffffffff);
  665. /* Disable interrupts. */
  666. wiol(ctlr, Cr3C, Cr3_IntMask);
  667. /* 32 bits addresses only. (TODO: 64 bits ?) */
  668. wiol(ctlr, TdHi, 0);
  669. wiow(ctlr, DataBufHi, 0);
  670. /* Enable MAC (turning off Rx/Tx engines for the moment). */
  671. wiob(ctlr, Cr0C, Cr0_Stop|Cr0_EnableRx|Cr0_EnableTx);
  672. wiob(ctlr, Cr0S, Cr0_Start);
  673. /* Initialize Rx engine. */
  674. wiow(ctlr, RxCsrC, RxCsr_RunQueue);
  675. /* Initialize Tx engine. */
  676. wiow(ctlr, TxCsrC, TxCsr_RunQueue);
  677. /* Enable Rx/Tx engines. */
  678. wiob(ctlr, Cr0S, Cr0_EnableRx|Cr0_EnableTx);
  679. /* Initialize link management. */
  680. ctlr->mii = malloc(sizeof(Mii));
  681. if(ctlr->mii == nil){
  682. print("vgbe: unable to alloc Mii\n");
  683. return -1;
  684. }
  685. ctlr->mii->mir = vgbemiir;
  686. ctlr->mii->miw = vgbemiiw;
  687. ctlr->mii->ctlr = ctlr;
  688. if(mii(ctlr->mii, 1<<1) == 0){
  689. print("vgbe: no phy found\n");
  690. return -1;
  691. }
  692. return 0;
  693. // phy = ctlr->mii->curphy;
  694. // print("vgbe: phy:oui %#x\n", phy->oui);
  695. }
  696. void
  697. vgbedetach(Ether* edev)
  698. {
  699. vgbereset(edev->ctlr);
  700. }
  701. static void
  702. vgbeinterrupt(Ureg *, void* arg)
  703. {
  704. /* now we need to do something special to empty the ring buffer since we don't have the process */
  705. Ether* edev;
  706. Ctlr* ctlr;
  707. uint32_t status;
  708. uint32_t err;
  709. // print("vgbe: Intr: entering interrupt\n");
  710. edev = arg;
  711. ctlr = edev->ctlr;
  712. /* Mask interrupts. */
  713. wiol(ctlr, Imr, 0);
  714. status = riol(ctlr, isr);
  715. if(status == 0xffff)
  716. goto end;
  717. /* acknowledge */
  718. if(status)
  719. wiol(ctlr, isr, status);
  720. if((status & isr_Mask) == 0)
  721. goto end;
  722. ctlr->stats.intr++;
  723. if(ctlr->debugflags & DumpIntr)
  724. if(ctlr->debugcount){
  725. print("vgbe: irq: status = %#08ulx\n", status);
  726. vgbedumpisr(status);
  727. ctlr->debugcount--;
  728. }
  729. if(status & Prx)
  730. vgberxeof(edev);
  731. if(status & Ptx0)
  732. vgbetxeof(edev);
  733. if(status & Shdn){
  734. //print("vgbe: irq: software shutxbufown complete\n");
  735. }
  736. if(status & Ovf)
  737. print("vgbe: irq: RX FIFO overflow\n");
  738. if(status & Phyint)
  739. print("vgbe: irq: PHY interrupt\n");
  740. if(status & Src)
  741. print("vgbe: irq: link status change\n");
  742. if(status & Lste)
  743. print("vgbe: irq: ran out of Rx descriptors\n");
  744. if(status & Rxstl){
  745. //print("vgbe: irq: Rx DMA stall\n");
  746. err = riol(ctlr, Rxesr);
  747. //print("vgbe: Rxesr %ulx\n", err);
  748. if(err & Rfdbs)
  749. print("Rx fifo dma bus error\n");
  750. if(err & Rdwbs)
  751. print("Rd write back host bus error\n");
  752. if(err & Rdrbs)
  753. print("Rd fetch host bus error.\n");
  754. if(err & Rdstr)
  755. print("Valid RD with linked buffer size zero.\n");
  756. wiol(ctlr, Rxesr, 0);
  757. wiol(ctlr, Cr3C, Cr3_IntMask);
  758. return;
  759. }
  760. if(status & Txstl){
  761. print("vgbe: irq: Tx DMA stall\n");
  762. wiol(ctlr, Cr3C, Cr3_IntMask);
  763. return;
  764. }
  765. end:
  766. /* Unmask interrupts. */
  767. wiol(ctlr, Imr, ~0);
  768. }
  769. static void
  770. vgbepci(void)
  771. {
  772. Pcidev *p;
  773. Ctlr *ctlr;
  774. int i, port;
  775. uint32_t bar;
  776. p = nil;
  777. while(p = pcimatch(p, 0, 0)){
  778. if(p->ccrb != 0x02 || p->ccru != 0)
  779. continue;
  780. switch((p->did<<16)|p->vid){
  781. default:
  782. continue;
  783. case (0x3119<<16)|0x1106:
  784. break;
  785. }
  786. bar = p->mem[0].bar;
  787. port = bar & ~0x01;
  788. if(ioalloc(port, p->mem[0].size, 0, "vgbe") < 0){
  789. print("vgbe: port %#ux in use\n", port);
  790. continue;
  791. }
  792. ctlr = malloc(sizeof(Ctlr));
  793. ctlr->port = port;
  794. ctlr->pcidev = p;
  795. if(pcigetpms(p) > 0){
  796. pcisetpms(p, 0);
  797. for(i = 0; i < 6; i++)
  798. pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
  799. pcicfgw8(p, PciINTL, p->intl);
  800. pcicfgw8(p, PciLTR, p->ltr);
  801. pcicfgw8(p, PciCLS, p->cls);
  802. pcicfgw16(p, PciPCR, p->pcr);
  803. }
  804. if(vgbereset(ctlr)){
  805. iofree(port);
  806. free(ctlr);
  807. continue;
  808. }
  809. pcisetbme(p);
  810. if(vgbectlrhead != nil)
  811. vgbectlrtail->next = ctlr;
  812. else
  813. vgbectlrhead = ctlr;
  814. vgbectlrtail = ctlr;
  815. }
  816. }
  817. int
  818. vgbepnp(Ether* edev)
  819. {
  820. Ctlr *ctlr;
  821. if(vgbectlrhead == nil)
  822. vgbepci();
  823. /*
  824. * Any adapter matches if no edev->port is supplied,
  825. * otherwise the ports must match.
  826. */
  827. for(ctlr = vgbectlrhead; ctlr != nil; ctlr = ctlr->next){
  828. if(ctlr->active)
  829. continue;
  830. if(edev->port == 0 || edev->port == ctlr->port){
  831. ctlr->active = 1;
  832. break;
  833. }
  834. }
  835. if(ctlr == nil)
  836. return -1;
  837. edev->ctlr = ctlr;
  838. edev->port = ctlr->port;
  839. edev->irq = ctlr->pcidev->intl;
  840. edev->tbdf = ctlr->pcidev->tbdf;
  841. memmove(edev->ea, ctlr->ea, Eaddrlen);
  842. /*
  843. * Linkage to the generic ethernet driver.
  844. */
  845. edev->attach = vgbeattach;
  846. edev->transmit = vgbetransmit;
  847. edev->interrupt = vgbeinterrupt;
  848. edev->detach = vgbedetach;
  849. return 0;
  850. }