2 * Asix USB ether adapters
3 * I got no documentation for it, thus the bits
4 * come from other systems; it's likely this is
5 * doing more than needed in some places and
6 * less than required in others.
19 Cswmii = 0x06, /* set sw mii */
20 Crmii = 0x07, /* read mii reg */
21 Cwmii = 0x08, /* write mii reg */
22 Chwmii = 0x0a, /* set hw mii */
23 Creeprom = 0x0b, /* read eeprom */
24 Cwdis = 0x0e, /* write disable */
25 Cwena = 0x0d, /* write enable */
26 Crrxctl = 0x0f, /* read rx ctl */
27 Cwrxctl = 0x10, /* write rx ctl */
28 Cwipg = 0x12, /* write ipg */
29 Crmac = 0x13, /* read mac addr */
30 Crphy = 0x19, /* read phy id */
31 Cwmedium = 0x1b, /* write medium mode */
32 Crgpio = 0x1e, /* read gpio */
33 Cwgpio = 0x1f, /* write gpios */
34 Creset = 0x20, /* reset */
35 Cwphy = 0x22, /* select phy */
44 Gpiogpo1en = 0x04, /* gpio1 enable */,
45 Gpiogpo1 = 0x08, /* gpio1 value */
46 Gpiogpo2en = 0x10, /* gpio2 enable */
47 Gpiogpo2 = 0x20, /* gpio2 value */
48 Gpiorse = 0x80, /* gpio reload serial eeprom */
51 Pembed = 0x10, /* embedded phy */
53 Mfd = 0x002, /* media */
60 Mall772 = Mfd|Mrfc|Mtfc|Mps|Mac|Mre,
61 Mall178 = Mps|Mfd|Mac|Mrfc|Mtfc|Mjfe|Mre,
63 Ipgdflt = 0x15|0x0c|0x12, /* default ipg0, 1, 2 */
67 Rxctlamall = 0x02, /* all multicast */
68 Rxctlprom = 0x01, /* promiscuous */
71 Miibmcr = 0x00, /* basic mode ctrl reg. */
72 Bmcrreset = 0x8000, /* reset */
73 Bmcranena = 0x1000, /* auto neg. enable */
74 Bmcrar = 0x0200, /* announce restart */
76 Miiad = 0x04, /* advertise reg. */
85 Adall = Ad10h|Ad10f|Ad100h|Ad100f,
87 Miimctl = 0x14, /* marvell ctl */
99 asixset(Dev *d, int c, int v)
104 r = Rh2d|Rvendor|Rdev;
105 ec = usbcmd(d, r, c, v, 0, nil, 0);
107 fprint(2, "%s: asixset %x %x: %r\n", argv0, c, v);
112 asixget(Dev *d, int c, uchar *buf, int l)
117 r = Rd2h|Rvendor|Rdev;
118 ec = usbcmd(d, r, c, 0, 0, buf, l);
120 fprint(2, "%s: asixget %x: %r\n", argv0, c);
129 if(asixget(d, Crgpio, &c, 1) < 0)
139 if(asixget(d, Crphy, buf, sizeof(buf)) < 0)
149 memset(buf, 0, sizeof(buf));
150 if(asixget(d, Crrxctl, buf, sizeof(buf)) < 0)
156 miiread(Dev *d, int phy, int reg)
161 r = Rd2h|Rvendor|Rdev;
162 if(usbcmd(d, r, Crmii, phy, reg, v, 2) < 0){
163 fprint(2, "%s: miiwrite: %r\n", argv0);
174 miiwrite(Dev *d, int phy, int reg, int val)
179 if(asixset(d, Cswmii, 0) < 0)
181 r = Rh2d|Rvendor|Rdev;
183 if(usbcmd(d, r, Cwmii, phy, reg, v, 2) < 0){
184 fprint(2, "%s: miiwrite: %#x %#x %r\n", argv0, reg, val);
187 if(asixset(d, Chwmii, 0) < 0)
193 eepromread(Dev *d, int i)
199 r = Rd2h|Rvendor|Rdev;
200 ec = usbcmd(d, r, Creeprom, i, 0, buf, sizeof(buf));
202 fprint(2, "%s: eepromread %d: %r\n", argv0, i);
216 b = allocb(Maxpkt+4);
217 if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){
226 hd = (hd>>16) ^ 0xFFFF;
227 if((n != hd) || (n > BLEN(b)))
233 etheriq(copyblock(b, n), 1);
241 asixtransmit(Dev *ep, Block *b)
247 hd = n | (n<<16)^0xFFFF0000;
251 if((n % ep->maxpkt) == 0){
252 PUT4(b->wp, 0xFFFF0000);
255 write(ep->dfd, b->rp, BLEN(b));
260 asixpromiscuous(Dev *d, int on)
269 return asixset(d, Cwrxctl, rxctl);
273 asixmulticast(Dev *d, uchar*, int)
281 rxctl &= ~Rxctlamall;
282 return asixset(d, Cwrxctl, rxctl);
295 asixset(d, Cwena, 0);
296 ee17 = eepromread(d, 0x0017);
297 asixset(d, Cwdis, 0);
298 asixset(d, Cwgpio, Gpiorse|Gpiogpo1|Gpiogpo1en);
299 if((ee17 >> 8) != 1){
300 asixset(d, Cwgpio, 0x003c);
301 asixset(d, Cwgpio, 0x001c);
302 asixset(d, Cwgpio, 0x003c);
304 asixset(d, Cwgpio, Gpiogpo1en);
305 asixset(d, Cwgpio, Gpiogpo1|Gpiogpo1en);
307 asixset(d, Creset, Rclear);
309 asixset(d, Creset, Rippd|Rprl);
311 asixset(d, Cwrxctl, 0);
312 if(asixget(d, Crmac, macaddr, 6) < 0)
315 if(ee17 < 0 || (ee17 & 0x7) == 0){
316 miiwrite(d, asixphy, Miimctl, Mtxrxdly);
319 miiwrite(d, asixphy, Miibmcr, Bmcrreset|Bmcranena);
320 miiwrite(d, asixphy, Miiad, Adall|Adcsma|Adpause);
321 miiwrite(d, asixphy, Miic1000, Ad1000f);
322 bmcr = miiread(d, asixphy, Miibmcr);
323 if((bmcr & Bmcranena) != 0){
325 miiwrite(d, asixphy, Miibmcr, bmcr);
327 asixset(d, Cwmedium, Mall178);
328 asixset(d, Cwrxctl, Rxctlso|Rxctlab);
330 epreceive = asixreceive;
331 eptransmit = asixtransmit;
332 eppromiscuous = asixpromiscuous;
333 epmulticast = asixmulticast;
344 if(asixset(d, Cwgpio, Gpiorse|Gpiogpo2|Gpiogpo2en) < 0)
347 if((asixphy & Pmask) == Pembed){
348 /* embedded 10/100 ethernet */
349 rc = asixset(d, Cwphy, 1);
351 rc = asixset(d, Cwphy, 0);
354 if(asixset(d, Creset, Rippd|Rprl) < 0)
357 if((asixphy & Pmask) == Pembed)
358 rc = asixset(d, Creset, Riprl);
360 rc = asixset(d, Creset, Rprte);
365 if(asixset(d, Cwrxctl, 0) < 0)
367 if(asixget(d, Crmac, macaddr, 6) < 0)
369 if(asixset(d, Creset, Rprl) < 0)
372 if(asixset(d, Creset, Riprl|Rprl) < 0)
376 miiwrite(d, asixphy, Miibmcr, Bmcrreset);
377 miiwrite(d, asixphy, Miiad, Adall|Adcsma);
378 bmcr = miiread(d, asixphy, Miibmcr);
379 if((bmcr & Bmcranena) != 0){
381 miiwrite(d, asixphy, Miibmcr, bmcr);
383 if(asixset(d, Cwmedium, Mall772) < 0)
385 if(asixset(d, Cwipg, Ipgdflt) < 0)
387 if(asixset(d, Cwrxctl, Rxctlso|Rxctlab) < 0)
390 epreceive = asixreceive;
391 eptransmit = asixtransmit;
392 eppromiscuous = asixpromiscuous;
393 epmulticast = asixmulticast;