1a650be7dSDavid du Colombier /*
2a650be7dSDavid du Colombier * SMSC LAN95XX
3a650be7dSDavid du Colombier */
4a650be7dSDavid du Colombier
5a650be7dSDavid du Colombier #include <u.h>
6a650be7dSDavid du Colombier #include <libc.h>
7a650be7dSDavid du Colombier #include <fcall.h>
8a650be7dSDavid du Colombier #include <thread.h>
9a650be7dSDavid du Colombier #include "usb.h"
10a650be7dSDavid du Colombier #include "usbfs.h"
11a650be7dSDavid du Colombier #include "ether.h"
12a650be7dSDavid du Colombier
13a650be7dSDavid du Colombier enum {
14a650be7dSDavid du Colombier Doburst = 1,
15a650be7dSDavid du Colombier Resettime = 1000,
16a650be7dSDavid du Colombier E2pbusytime = 1000,
17a650be7dSDavid du Colombier Afcdefault = 0xF830A1,
18*e1c0af53SDavid du Colombier Hsburst = 24,
19a650be7dSDavid du Colombier Fsburst = 129,
20*e1c0af53SDavid du Colombier Defbulkdly = 1000,
21a650be7dSDavid du Colombier
22a650be7dSDavid du Colombier Ethp8021q = 0x8100,
23a650be7dSDavid du Colombier MACoffset = 1,
24a650be7dSDavid du Colombier PHYinternal = 1,
25a650be7dSDavid du Colombier Rxerror = 0x8000,
26a650be7dSDavid du Colombier Txfirst = 0x2000,
27a650be7dSDavid du Colombier Txlast = 0x1000,
28a650be7dSDavid du Colombier
29a650be7dSDavid du Colombier /* USB vendor requests */
30a650be7dSDavid du Colombier Writereg = 0xA0,
31a650be7dSDavid du Colombier Readreg = 0xA1,
32a650be7dSDavid du Colombier
33a650be7dSDavid du Colombier /* device registers */
34a650be7dSDavid du Colombier Intsts = 0x08,
35a650be7dSDavid du Colombier Txcfg = 0x10,
36a650be7dSDavid du Colombier Txon = 1<<2,
37a650be7dSDavid du Colombier Hwcfg = 0x14,
38a650be7dSDavid du Colombier Bir = 1<<12,
39a650be7dSDavid du Colombier Rxdoff = 3<<9,
40a650be7dSDavid du Colombier Mef = 1<<5,
41a650be7dSDavid du Colombier Lrst = 1<<3,
42a650be7dSDavid du Colombier Bce = 1<<1,
43a650be7dSDavid du Colombier Pmctrl = 0x20,
44a650be7dSDavid du Colombier Phyrst = 1<<4,
45a650be7dSDavid du Colombier Ledgpio = 0x24,
46a650be7dSDavid du Colombier Ledspd = 1<<24,
47a650be7dSDavid du Colombier Ledlnk = 1<<20,
48a650be7dSDavid du Colombier Ledfdx = 1<<16,
49a650be7dSDavid du Colombier Afccfg = 0x2C,
50a650be7dSDavid du Colombier E2pcmd = 0x30,
51a650be7dSDavid du Colombier Busy = 1<<31,
52a650be7dSDavid du Colombier Timeout = 1<<10,
53a650be7dSDavid du Colombier Read = 0,
54a650be7dSDavid du Colombier E2pdata = 0x34,
55a650be7dSDavid du Colombier Burstcap = 0x38,
56a650be7dSDavid du Colombier Intepctl = 0x68,
57a650be7dSDavid du Colombier Phyint = 1<<15,
58a650be7dSDavid du Colombier Bulkdelay = 0x6C,
59a650be7dSDavid du Colombier Maccr = 0x100,
60a650be7dSDavid du Colombier Mcpas = 1<<19,
61a650be7dSDavid du Colombier Prms = 1<<18,
62a650be7dSDavid du Colombier Hpfilt = 1<<13,
63a650be7dSDavid du Colombier Txen = 1<<3,
64a650be7dSDavid du Colombier Rxen = 1<<2,
65a650be7dSDavid du Colombier Addrh = 0x104,
66a650be7dSDavid du Colombier Addrl = 0x108,
67a650be7dSDavid du Colombier Hashh = 0x10C,
68a650be7dSDavid du Colombier Hashl = 0x110,
69a650be7dSDavid du Colombier MIIaddr = 0x114,
70a650be7dSDavid du Colombier MIIwrite= 1<<1,
71a650be7dSDavid du Colombier MIIread = 0<<1,
72a650be7dSDavid du Colombier MIIbusy = 1<<0,
73a650be7dSDavid du Colombier MIIdata = 0x118,
74a650be7dSDavid du Colombier Flow = 0x11C,
75a650be7dSDavid du Colombier Vlan1 = 0x120,
76a650be7dSDavid du Colombier Coecr = 0x130,
77a650be7dSDavid du Colombier Txcoe = 1<<16,
78a650be7dSDavid du Colombier Rxcoemd = 1<<1,
79a650be7dSDavid du Colombier Rxcoe = 1<<0,
80a650be7dSDavid du Colombier
81a650be7dSDavid du Colombier /* MII registers */
82a650be7dSDavid du Colombier Bmcr = 0,
83a650be7dSDavid du Colombier Bmcrreset= 1<<15,
84a650be7dSDavid du Colombier Speed100= 1<<13,
85a650be7dSDavid du Colombier Anenable= 1<<12,
86a650be7dSDavid du Colombier Anrestart= 1<<9,
87a650be7dSDavid du Colombier Fulldpx = 1<<8,
88a650be7dSDavid du Colombier Bmsr = 1,
89a650be7dSDavid du Colombier Advertise = 4,
90a650be7dSDavid du Colombier Adcsma = 0x0001,
91a650be7dSDavid du Colombier Ad10h = 0x0020,
92a650be7dSDavid du Colombier Ad10f = 0x0040,
93a650be7dSDavid du Colombier Ad100h = 0x0080,
94a650be7dSDavid du Colombier Ad100f = 0x0100,
95a650be7dSDavid du Colombier Adpause = 0x0400,
96a650be7dSDavid du Colombier Adpauseasym= 0x0800,
97a650be7dSDavid du Colombier Adall = Ad10h|Ad10f|Ad100h|Ad100f,
98a650be7dSDavid du Colombier Phyintsrc = 29,
99a650be7dSDavid du Colombier Phyintmask = 30,
100a650be7dSDavid du Colombier Anegcomp= 1<<6,
101a650be7dSDavid du Colombier Linkdown= 1<<4,
102a650be7dSDavid du Colombier };
103a650be7dSDavid du Colombier
104*e1c0af53SDavid du Colombier static int burstcap = Hsburst, bulkdelay = Defbulkdly;
105*e1c0af53SDavid du Colombier
106a650be7dSDavid du Colombier static int
wr(Dev * d,int reg,int val)107a650be7dSDavid du Colombier wr(Dev *d, int reg, int val)
108a650be7dSDavid du Colombier {
109a650be7dSDavid du Colombier int ret;
110a650be7dSDavid du Colombier
111a650be7dSDavid du Colombier ret = usbcmd(d, Rh2d|Rvendor|Rdev, Writereg, 0, reg,
112a650be7dSDavid du Colombier (uchar*)&val, sizeof(val));
113a650be7dSDavid du Colombier if(ret < 0)
114a650be7dSDavid du Colombier deprint(2, "%s: wr(%x, %x): %r", argv0, reg, val);
115a650be7dSDavid du Colombier return ret;
116a650be7dSDavid du Colombier }
117a650be7dSDavid du Colombier
118a650be7dSDavid du Colombier static int
rr(Dev * d,int reg)119a650be7dSDavid du Colombier rr(Dev *d, int reg)
120a650be7dSDavid du Colombier {
121a650be7dSDavid du Colombier int ret, rval;
122a650be7dSDavid du Colombier
123a650be7dSDavid du Colombier ret = usbcmd(d, Rd2h|Rvendor|Rdev, Readreg, 0, reg,
124a650be7dSDavid du Colombier (uchar*)&rval, sizeof(rval));
125a650be7dSDavid du Colombier if(ret < 0){
126a650be7dSDavid du Colombier fprint(2, "%s: rr(%x): %r", argv0, reg);
127a650be7dSDavid du Colombier return 0;
128a650be7dSDavid du Colombier }
129a650be7dSDavid du Colombier return rval;
130a650be7dSDavid du Colombier }
131a650be7dSDavid du Colombier
132a650be7dSDavid du Colombier static int
miird(Dev * d,int idx)133a650be7dSDavid du Colombier miird(Dev *d, int idx)
134a650be7dSDavid du Colombier {
135a650be7dSDavid du Colombier while(rr(d, MIIaddr) & MIIbusy)
136a650be7dSDavid du Colombier ;
137a650be7dSDavid du Colombier wr(d, MIIaddr, PHYinternal<<11 | idx<<6 | MIIread);
138a650be7dSDavid du Colombier while(rr(d, MIIaddr) & MIIbusy)
139a650be7dSDavid du Colombier ;
140a650be7dSDavid du Colombier return rr(d, MIIdata);
141a650be7dSDavid du Colombier }
142a650be7dSDavid du Colombier
143a650be7dSDavid du Colombier static void
miiwr(Dev * d,int idx,int val)144a650be7dSDavid du Colombier miiwr(Dev *d, int idx, int val)
145a650be7dSDavid du Colombier {
146a650be7dSDavid du Colombier while(rr(d, MIIaddr) & MIIbusy)
147a650be7dSDavid du Colombier ;
148a650be7dSDavid du Colombier wr(d, MIIdata, val);
149a650be7dSDavid du Colombier wr(d, MIIaddr, PHYinternal<<11 | idx<<6 | MIIwrite);
150a650be7dSDavid du Colombier while(rr(d, MIIaddr) & MIIbusy)
151a650be7dSDavid du Colombier ;
152a650be7dSDavid du Colombier }
153a650be7dSDavid du Colombier
154a650be7dSDavid du Colombier static int
eepromr(Dev * d,int off,uchar * buf,int len)155a650be7dSDavid du Colombier eepromr(Dev *d, int off, uchar *buf, int len)
156a650be7dSDavid du Colombier {
157a650be7dSDavid du Colombier int i, v;
158a650be7dSDavid du Colombier
159a650be7dSDavid du Colombier for(i = 0; i < E2pbusytime; i++)
160a650be7dSDavid du Colombier if((rr(d, E2pcmd) & Busy) == 0)
161a650be7dSDavid du Colombier break;
162a650be7dSDavid du Colombier if(i == E2pbusytime)
163a650be7dSDavid du Colombier return -1;
164a650be7dSDavid du Colombier for(i = 0; i < len; i++){
165a650be7dSDavid du Colombier wr(d, E2pcmd, Busy|Read|(i+off));
166a650be7dSDavid du Colombier while((v = rr(d, E2pcmd) & (Busy|Timeout)) == Busy)
167a650be7dSDavid du Colombier ;
168a650be7dSDavid du Colombier if(v & Timeout)
169a650be7dSDavid du Colombier return -1;
170a650be7dSDavid du Colombier buf[i] = rr(d, E2pdata);
171a650be7dSDavid du Colombier }
172a650be7dSDavid du Colombier return 0;
173a650be7dSDavid du Colombier }
174a650be7dSDavid du Colombier
175a650be7dSDavid du Colombier static void
phyinit(Dev * d)176a650be7dSDavid du Colombier phyinit(Dev *d)
177a650be7dSDavid du Colombier {
178a650be7dSDavid du Colombier int i;
179a650be7dSDavid du Colombier
180a650be7dSDavid du Colombier miiwr(d, Bmcr, Bmcrreset|Anenable);
181a650be7dSDavid du Colombier for(i = 0; i < Resettime/10; i++){
182a650be7dSDavid du Colombier if((miird(d, Bmcr) & Bmcrreset) == 0)
183a650be7dSDavid du Colombier break;
184a650be7dSDavid du Colombier sleep(10);
185a650be7dSDavid du Colombier }
186a650be7dSDavid du Colombier miiwr(d, Advertise, Adcsma|Adall|Adpause|Adpauseasym);
187a650be7dSDavid du Colombier // miiwr(d, Advertise, Adcsma|Ad10f|Ad10h|Adpause|Adpauseasym);
188a650be7dSDavid du Colombier miird(d, Phyintsrc);
189a650be7dSDavid du Colombier miiwr(d, Phyintmask, Anegcomp|Linkdown);
190a650be7dSDavid du Colombier miiwr(d, Bmcr, miird(d, Bmcr)|Anenable|Anrestart);
191a650be7dSDavid du Colombier }
192a650be7dSDavid du Colombier
193a650be7dSDavid du Colombier
194a650be7dSDavid du Colombier static int
doreset(Dev * d,int reg,int bit)195a650be7dSDavid du Colombier doreset(Dev *d, int reg, int bit)
196a650be7dSDavid du Colombier {
197a650be7dSDavid du Colombier int i;
198a650be7dSDavid du Colombier
199a650be7dSDavid du Colombier if(wr(d, reg, bit) < 0)
200a650be7dSDavid du Colombier return -1;
201a650be7dSDavid du Colombier for(i = 0; i < Resettime/10; i++){
202a650be7dSDavid du Colombier if((rr(d, reg) & bit) == 0)
203a650be7dSDavid du Colombier return 1;
204a650be7dSDavid du Colombier sleep(10);
205a650be7dSDavid du Colombier }
206a650be7dSDavid du Colombier return 0;
207a650be7dSDavid du Colombier }
208a650be7dSDavid du Colombier
209a650be7dSDavid du Colombier static int
getmac(Dev * d,uchar buf[])210a650be7dSDavid du Colombier getmac(Dev *d, uchar buf[])
211a650be7dSDavid du Colombier {
212a650be7dSDavid du Colombier int i;
213a650be7dSDavid du Colombier uchar ea[Eaddrlen];
214a650be7dSDavid du Colombier
215a650be7dSDavid du Colombier if(eepromr(d, MACoffset, ea, Eaddrlen) < 0)
216a650be7dSDavid du Colombier return -1;
217a650be7dSDavid du Colombier for(i = 0; i < Eaddrlen; i++)
2180cc6832dSDavid du Colombier if(ea[i] != 0 && ea[i] != 0xFF){
219a650be7dSDavid du Colombier memmove(buf, ea, Eaddrlen);
220a650be7dSDavid du Colombier break;
221a650be7dSDavid du Colombier }
222a650be7dSDavid du Colombier return Eaddrlen;
223a650be7dSDavid du Colombier }
224a650be7dSDavid du Colombier
225a650be7dSDavid du Colombier static int
smscinit(Ether * ether)226a650be7dSDavid du Colombier smscinit(Ether *ether)
227a650be7dSDavid du Colombier {
228a650be7dSDavid du Colombier Dev *d;
229a650be7dSDavid du Colombier
230a650be7dSDavid du Colombier if(ether->cid != S95xx)
231a650be7dSDavid du Colombier return -1;
232a650be7dSDavid du Colombier d = ether->dev;
233a650be7dSDavid du Colombier deprint(2, "%s: setting up SMSC95XX\n", argv0);
234a650be7dSDavid du Colombier if(!doreset(d, Hwcfg, Lrst) || !doreset(d, Pmctrl, Phyrst))
235a650be7dSDavid du Colombier return -1;
236a650be7dSDavid du Colombier if(getmac(d, ether->addr) < 0)
237a650be7dSDavid du Colombier return -1;
238a650be7dSDavid du Colombier wr(d, Addrl, GET4(ether->addr));
239a650be7dSDavid du Colombier wr(d, Addrh, GET2(ether->addr+4));
240a650be7dSDavid du Colombier if(Doburst){
241a650be7dSDavid du Colombier wr(d, Hwcfg, (rr(d,Hwcfg)&~Rxdoff)|Bir|Mef|Bce);
242*e1c0af53SDavid du Colombier wr(d, Burstcap, burstcap);
243*e1c0af53SDavid du Colombier wr(d, Bulkdelay, bulkdelay);
244a650be7dSDavid du Colombier }else{
245a650be7dSDavid du Colombier wr(d, Hwcfg, (rr(d,Hwcfg)&~(Rxdoff|Mef|Bce))|Bir);
246a650be7dSDavid du Colombier wr(d, Burstcap, 0);
247*e1c0af53SDavid du Colombier wr(d, Bulkdelay, 0);
248a650be7dSDavid du Colombier }
249a650be7dSDavid du Colombier wr(d, Intsts, ~0);
250a650be7dSDavid du Colombier wr(d, Ledgpio, Ledspd|Ledlnk|Ledfdx);
251a650be7dSDavid du Colombier wr(d, Flow, 0);
252a650be7dSDavid du Colombier wr(d, Afccfg, Afcdefault);
253a650be7dSDavid du Colombier wr(d, Vlan1, Ethp8021q);
254a650be7dSDavid du Colombier wr(d, Coecr, rr(d,Coecr)&~(Txcoe|Rxcoe)); /* TODO could offload checksums? */
255a650be7dSDavid du Colombier
256a650be7dSDavid du Colombier wr(d, Hashh, 0);
257a650be7dSDavid du Colombier wr(d, Hashl, 0);
258a650be7dSDavid du Colombier wr(d, Maccr, rr(d,Maccr)&~(Prms|Mcpas|Hpfilt));
259a650be7dSDavid du Colombier
260a650be7dSDavid du Colombier phyinit(d);
261a650be7dSDavid du Colombier
262a650be7dSDavid du Colombier wr(d, Intepctl, rr(d, Intepctl)|Phyint);
263a650be7dSDavid du Colombier wr(d, Maccr, rr(d, Maccr)|Txen|Rxen);
264a650be7dSDavid du Colombier wr(d, Txcfg, Txon);
265a650be7dSDavid du Colombier
266a650be7dSDavid du Colombier return 0;
267a650be7dSDavid du Colombier }
268a650be7dSDavid du Colombier
269a650be7dSDavid du Colombier static long
smscbread(Ether * e,Buf * bp)270a650be7dSDavid du Colombier smscbread(Ether *e, Buf *bp)
271a650be7dSDavid du Colombier {
272a650be7dSDavid du Colombier uint hd;
273a650be7dSDavid du Colombier int n, m;
274a650be7dSDavid du Colombier Buf *rbp;
275a650be7dSDavid du Colombier
276a650be7dSDavid du Colombier rbp = e->aux;
277a650be7dSDavid du Colombier if(rbp->ndata < 4){
278a650be7dSDavid du Colombier rbp->rp = rbp->data;
279*e1c0af53SDavid du Colombier rbp->ndata = read(e->epin->dfd, rbp->rp, Doburst? burstcap*512:
2800cc6832dSDavid du Colombier Maxpkt);
281a650be7dSDavid du Colombier if(rbp->ndata < 0)
282a650be7dSDavid du Colombier return -1;
283a650be7dSDavid du Colombier }
284a650be7dSDavid du Colombier if(rbp->ndata < 4){
285a650be7dSDavid du Colombier werrstr("short frame");
286a650be7dSDavid du Colombier fprint(2, "smsc short frame %d bytes\n", rbp->ndata);
287a650be7dSDavid du Colombier return 0;
288a650be7dSDavid du Colombier }
289a650be7dSDavid du Colombier hd = GET4(rbp->rp);
290*e1c0af53SDavid du Colombier rbp->rp += 4;
291*e1c0af53SDavid du Colombier rbp->ndata -= 4;
292a650be7dSDavid du Colombier n = hd >> 16;
293*e1c0af53SDavid du Colombier if(n < 6 || n > rbp->ndata){
294a650be7dSDavid du Colombier werrstr("frame length");
295a650be7dSDavid du Colombier fprint(2, "smsc length error packet %d buf %d\n", n, rbp->ndata);
296a650be7dSDavid du Colombier rbp->ndata = 0;
297a650be7dSDavid du Colombier return 0;
298a650be7dSDavid du Colombier }
299*e1c0af53SDavid du Colombier m = n;
300*e1c0af53SDavid du Colombier if(rbp->ndata - m < 4)
301*e1c0af53SDavid du Colombier m = rbp->ndata;
302a650be7dSDavid du Colombier if(hd & Rxerror){
303a650be7dSDavid du Colombier fprint(2, "smsc rx error %8.8ux\n", hd);
304a650be7dSDavid du Colombier n = 0;
305a650be7dSDavid du Colombier }else{
306a650be7dSDavid du Colombier bp->rp = bp->data + Hdrsize;
307*e1c0af53SDavid du Colombier memmove(bp->rp, rbp->rp, n);
308a650be7dSDavid du Colombier }
309a650be7dSDavid du Colombier bp->ndata = n;
310a650be7dSDavid du Colombier rbp->rp += m;
311a650be7dSDavid du Colombier rbp->ndata -= m;
312a650be7dSDavid du Colombier return n;
313a650be7dSDavid du Colombier }
314a650be7dSDavid du Colombier
315a650be7dSDavid du Colombier static long
smscbwrite(Ether * e,Buf * bp)316a650be7dSDavid du Colombier smscbwrite(Ether *e, Buf *bp)
317a650be7dSDavid du Colombier {
318a650be7dSDavid du Colombier int n;
319a650be7dSDavid du Colombier
320a650be7dSDavid du Colombier n = bp->ndata & 0x7FF;
321a650be7dSDavid du Colombier bp->rp -= 8;
322a650be7dSDavid du Colombier bp->ndata += 8;
323a650be7dSDavid du Colombier PUT4(bp->rp, n | Txfirst | Txlast);
324a650be7dSDavid du Colombier PUT4(bp->rp+4, n);
325a650be7dSDavid du Colombier n = write(e->epout->dfd, bp->rp, bp->ndata);
326a650be7dSDavid du Colombier return n;
327a650be7dSDavid du Colombier }
328a650be7dSDavid du Colombier
329853458f3SDavid du Colombier static int
smscpromiscuous(Ether * e,int on)330853458f3SDavid du Colombier smscpromiscuous(Ether *e, int on)
331853458f3SDavid du Colombier {
33219c1d8dfSDavid du Colombier Dev *d;
333853458f3SDavid du Colombier int rxctl;
334853458f3SDavid du Colombier
33519c1d8dfSDavid du Colombier d = e->dev;
33619c1d8dfSDavid du Colombier rxctl = rr(d, Maccr);
33719c1d8dfSDavid du Colombier if(on)
33819c1d8dfSDavid du Colombier rxctl |= Prms;
339853458f3SDavid du Colombier else
34019c1d8dfSDavid du Colombier rxctl &= ~Prms;
34119c1d8dfSDavid du Colombier return wr(d, Maccr, rxctl);
342853458f3SDavid du Colombier }
343853458f3SDavid du Colombier
344853458f3SDavid du Colombier static int
smscmulticast(Ether * e,uchar * addr,int on)345853458f3SDavid du Colombier smscmulticast(Ether *e, uchar *addr, int on)
346853458f3SDavid du Colombier {
347853458f3SDavid du Colombier int rxctl;
34819c1d8dfSDavid du Colombier Dev *d;
349853458f3SDavid du Colombier
35019c1d8dfSDavid du Colombier USED(addr, on);
351853458f3SDavid du Colombier /* BUG: should write multicast filter */
35219c1d8dfSDavid du Colombier d = e->dev;
35319c1d8dfSDavid du Colombier rxctl = rr(d, Maccr);
354853458f3SDavid du Colombier if(e->nmcasts != 0)
35519c1d8dfSDavid du Colombier rxctl |= Mcpas;
356853458f3SDavid du Colombier else
35719c1d8dfSDavid du Colombier rxctl &= ~Mcpas;
358853458f3SDavid du Colombier deprint(2, "%s: smscmulticast %d\n", argv0, e->nmcasts);
35919c1d8dfSDavid du Colombier return wr(d, Maccr, rxctl);
360853458f3SDavid du Colombier }
361853458f3SDavid du Colombier
362a650be7dSDavid du Colombier static void
smscfree(Ether * ether)363a650be7dSDavid du Colombier smscfree(Ether *ether)
364a650be7dSDavid du Colombier {
365a650be7dSDavid du Colombier free(ether->aux);
366a650be7dSDavid du Colombier ether->aux = nil;
367a650be7dSDavid du Colombier }
368a650be7dSDavid du Colombier
369a650be7dSDavid du Colombier int
smscreset(Ether * ether)370a650be7dSDavid du Colombier smscreset(Ether *ether)
371a650be7dSDavid du Colombier {
372a650be7dSDavid du Colombier Cinfo *ip;
373a650be7dSDavid du Colombier Dev *dev;
374a650be7dSDavid du Colombier
375a650be7dSDavid du Colombier dev = ether->dev;
376a650be7dSDavid du Colombier for(ip = cinfo; ip->vid != 0; ip++)
377a650be7dSDavid du Colombier if(ip->vid == dev->usb->vid && ip->did == dev->usb->did){
378a650be7dSDavid du Colombier ether->cid = ip->cid;
379a650be7dSDavid du Colombier if(smscinit(ether) < 0){
380a650be7dSDavid du Colombier deprint(2, "%s: smsc init failed: %r\n", argv0);
381a650be7dSDavid du Colombier return -1;
382a650be7dSDavid du Colombier }
383a650be7dSDavid du Colombier deprint(2, "%s: smsc reset done\n", argv0);
3840cc6832dSDavid du Colombier ether->name = "smsc";
3850cc6832dSDavid du Colombier if(Doburst){
386*e1c0af53SDavid du Colombier ether->bufsize = burstcap*512;
3870cc6832dSDavid du Colombier ether->aux = emallocz(sizeof(Buf) +
3880cc6832dSDavid du Colombier ether->bufsize - Maxpkt, 1);
3890cc6832dSDavid du Colombier }else{
3900cc6832dSDavid du Colombier ether->bufsize = Maxpkt;
3910cc6832dSDavid du Colombier ether->aux = emallocz(sizeof(Buf), 1);
3920cc6832dSDavid du Colombier }
393a650be7dSDavid du Colombier ether->free = smscfree;
394a650be7dSDavid du Colombier ether->bread = smscbread;
395a650be7dSDavid du Colombier ether->bwrite = smscbwrite;
396853458f3SDavid du Colombier ether->promiscuous = smscpromiscuous;
397853458f3SDavid du Colombier ether->multicast = smscmulticast;
398a650be7dSDavid du Colombier ether->mbps = 100; /* BUG */
399a650be7dSDavid du Colombier return 0;
400a650be7dSDavid du Colombier }
401a650be7dSDavid du Colombier return -1;
402a650be7dSDavid du Colombier }
403