Deleted Added
full compact
if_sn.c (60536) if_sn.c (63090)
1/*
2 * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Gardner Buchanan.
16 * 4. The name of Gardner Buchanan may not be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
1/*
2 * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Gardner Buchanan.
16 * 4. The name of Gardner Buchanan may not be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $FreeBSD: head/sys/dev/sn/if_sn.c 60536 2000-05-14 02:18:43Z archie $
31 * $FreeBSD: head/sys/dev/sn/if_sn.c 63090 2000-07-13 22:54:34Z archie $
32 */
33
34/*
35 * This is a driver for SMC's 9000 series of Ethernet adapters.
36 *
37 * This FreeBSD driver is derived from the smc9194 Linux driver by
38 * Erik Stahlman and is Copyright (C) 1996 by Erik Stahlman.
39 * This driver also shamelessly borrows from the FreeBSD ep driver
40 * which is Copyright (C) 1994 Herb Peyerl <hpeyerl@novatel.ca>
41 * All rights reserved.
42 *
43 * It is set up for my SMC91C92 equipped Ampro LittleBoard embedded
44 * PC. It is adapted from Erik Stahlman's Linux driver which worked
45 * with his EFA Info*Express SVC VLB adaptor. According to SMC's databook,
46 * it will work for the entire SMC 9xxx series. (Ha Ha)
47 *
48 * "Features" of the SMC chip:
49 * 4608 byte packet memory. (for the 91C92. Others have more)
50 * EEPROM for configuration
51 * AUI/TP selection
52 *
53 * Authors:
54 * Erik Stahlman erik@vt.edu
55 * Herb Peyerl hpeyerl@novatel.ca
56 * Andres Vega Garcia avega@sophia.inria.fr
57 * Serge Babkin babkin@hq.icb.chel.su
58 * Gardner Buchanan gbuchanan@shl.com
59 *
60 * Sources:
61 * o SMC databook
62 * o "smc9194.c:v0.10(FIXED) 02/15/96 by Erik Stahlman (erik@vt.edu)"
63 * o "if_ep.c,v 1.19 1995/01/24 20:53:45 davidg Exp"
64 *
65 * Known Bugs:
66 * o The hardware multicast filter isn't used yet.
67 * o Setting of the hardware address isn't supported.
68 * o Hardware padding isn't used.
69 */
70
71/*
72 * Modifications for Megahertz X-Jack Ethernet Card (XJ-10BT)
73 *
74 * Copyright (c) 1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org>
75 * BSD-nomads, Tokyo, Japan.
76 */
77/*
78 * Multicast support by Kei TANAKA <kei@pal.xerox.com>
79 * Special thanks to itojun@itojun.org
80 */
81
82#undef SN_DEBUG /* (by hosokawa) */
83
84#include <sys/param.h>
85#include <sys/systm.h>
86#include <sys/errno.h>
87#include <sys/sockio.h>
88#include <sys/mbuf.h>
89#include <sys/socket.h>
90#include <sys/syslog.h>
91
92#include <sys/module.h>
93#include <sys/bus.h>
94
95#include <machine/bus.h>
96#include <machine/resource.h>
97#include <sys/rman.h>
98
99#include <net/ethernet.h>
100#include <net/if.h>
101#include <net/if_arp.h>
102#include <net/if_dl.h>
103#include <net/if_types.h>
104#include <net/if_mib.h>
105
106#ifdef INET
107#include <netinet/in.h>
108#include <netinet/in_systm.h>
109#include <netinet/in_var.h>
110#include <netinet/ip.h>
111#endif
112
113#ifdef NS
114#include <netns/ns.h>
115#include <netns/ns_if.h>
116#endif
117
118#include <net/bpf.h>
119#include <net/bpfdesc.h>
120
121#include <machine/clock.h>
122
123#include <dev/sn/if_snreg.h>
124#include <dev/sn/if_snvar.h>
125
126/* Exported variables */
127devclass_t sn_devclass;
128
129static int snioctl(struct ifnet * ifp, u_long, caddr_t);
130
131static void snresume(struct ifnet *);
132
133void sninit(void *);
134void snread(struct ifnet *);
135void snreset(struct sn_softc *);
136void snstart(struct ifnet *);
137void snstop(struct sn_softc *);
138void snwatchdog(struct ifnet *);
139
140static void sn_setmcast(struct sn_softc *);
141static int sn_getmcf(struct arpcom *ac, u_char *mcf);
142static u_int smc_crc(u_char *);
143
144/* I (GB) have been unlucky getting the hardware padding
145 * to work properly.
146 */
147#define SW_PAD
148
149static const char *chip_ids[15] = {
150 NULL, NULL, NULL,
151 /* 3 */ "SMC91C90/91C92",
152 /* 4 */ "SMC91C94",
153 /* 5 */ "SMC91C95",
154 NULL,
155 /* 7 */ "SMC91C100",
156 NULL, NULL, NULL, NULL,
157 NULL, NULL, NULL
158};
159
160int
161sn_attach(device_t dev)
162{
163 struct sn_softc *sc = device_get_softc(dev);
164 struct ifnet *ifp = &sc->arpcom.ac_if;
165 u_short i;
166 u_char *p;
167 struct ifaddr *ifa;
168 struct sockaddr_dl *sdl;
169 int rev;
170 u_short address;
171 int j;
172
173 sn_activate(dev);
174
175 snstop(sc);
176
177 sc->dev = dev;
178 sc->pages_wanted = -1;
179
180 device_printf(dev, " ");
181
182 SMC_SELECT_BANK(3);
183 rev = inw(BASE + REVISION_REG_W);
184 if (chip_ids[(rev >> 4) & 0xF])
185 printf("%s ", chip_ids[(rev >> 4) & 0xF]);
186
187 SMC_SELECT_BANK(1);
188 i = inw(BASE + CONFIG_REG_W);
189 printf(i & CR_AUI_SELECT ? "AUI" : "UTP");
190
191 if (sc->pccard_enaddr)
192 for (j = 0; j < 3; j++) {
193 u_short w;
194
195 w = (u_short)sc->arpcom.ac_enaddr[j * 2] |
196 (((u_short)sc->arpcom.ac_enaddr[j * 2 + 1]) << 8);
197 outw(BASE + IAR_ADDR0_REG_W + j * 2, w);
198 }
199
200 /*
201 * Read the station address from the chip. The MAC address is bank 1,
202 * regs 4 - 9
203 */
204 SMC_SELECT_BANK(1);
205 p = (u_char *) & sc->arpcom.ac_enaddr;
206 for (i = 0; i < 6; i += 2) {
207 address = inw(BASE + IAR_ADDR0_REG_W + i);
208 p[i + 1] = address >> 8;
209 p[i] = address & 0xFF;
210 }
211 printf(" MAC address %6D\n", sc->arpcom.ac_enaddr, ":");
212 ifp->if_softc = sc;
213 ifp->if_unit = device_get_unit(dev);
214 ifp->if_name = "sn";
215 ifp->if_mtu = ETHERMTU;
216 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
217 ifp->if_output = ether_output;
218 ifp->if_start = snstart;
219 ifp->if_ioctl = snioctl;
220 ifp->if_watchdog = snwatchdog;
221 ifp->if_init = sninit;
222 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
223 ifp->if_timer = 0;
224
32 */
33
34/*
35 * This is a driver for SMC's 9000 series of Ethernet adapters.
36 *
37 * This FreeBSD driver is derived from the smc9194 Linux driver by
38 * Erik Stahlman and is Copyright (C) 1996 by Erik Stahlman.
39 * This driver also shamelessly borrows from the FreeBSD ep driver
40 * which is Copyright (C) 1994 Herb Peyerl <hpeyerl@novatel.ca>
41 * All rights reserved.
42 *
43 * It is set up for my SMC91C92 equipped Ampro LittleBoard embedded
44 * PC. It is adapted from Erik Stahlman's Linux driver which worked
45 * with his EFA Info*Express SVC VLB adaptor. According to SMC's databook,
46 * it will work for the entire SMC 9xxx series. (Ha Ha)
47 *
48 * "Features" of the SMC chip:
49 * 4608 byte packet memory. (for the 91C92. Others have more)
50 * EEPROM for configuration
51 * AUI/TP selection
52 *
53 * Authors:
54 * Erik Stahlman erik@vt.edu
55 * Herb Peyerl hpeyerl@novatel.ca
56 * Andres Vega Garcia avega@sophia.inria.fr
57 * Serge Babkin babkin@hq.icb.chel.su
58 * Gardner Buchanan gbuchanan@shl.com
59 *
60 * Sources:
61 * o SMC databook
62 * o "smc9194.c:v0.10(FIXED) 02/15/96 by Erik Stahlman (erik@vt.edu)"
63 * o "if_ep.c,v 1.19 1995/01/24 20:53:45 davidg Exp"
64 *
65 * Known Bugs:
66 * o The hardware multicast filter isn't used yet.
67 * o Setting of the hardware address isn't supported.
68 * o Hardware padding isn't used.
69 */
70
71/*
72 * Modifications for Megahertz X-Jack Ethernet Card (XJ-10BT)
73 *
74 * Copyright (c) 1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org>
75 * BSD-nomads, Tokyo, Japan.
76 */
77/*
78 * Multicast support by Kei TANAKA <kei@pal.xerox.com>
79 * Special thanks to itojun@itojun.org
80 */
81
82#undef SN_DEBUG /* (by hosokawa) */
83
84#include <sys/param.h>
85#include <sys/systm.h>
86#include <sys/errno.h>
87#include <sys/sockio.h>
88#include <sys/mbuf.h>
89#include <sys/socket.h>
90#include <sys/syslog.h>
91
92#include <sys/module.h>
93#include <sys/bus.h>
94
95#include <machine/bus.h>
96#include <machine/resource.h>
97#include <sys/rman.h>
98
99#include <net/ethernet.h>
100#include <net/if.h>
101#include <net/if_arp.h>
102#include <net/if_dl.h>
103#include <net/if_types.h>
104#include <net/if_mib.h>
105
106#ifdef INET
107#include <netinet/in.h>
108#include <netinet/in_systm.h>
109#include <netinet/in_var.h>
110#include <netinet/ip.h>
111#endif
112
113#ifdef NS
114#include <netns/ns.h>
115#include <netns/ns_if.h>
116#endif
117
118#include <net/bpf.h>
119#include <net/bpfdesc.h>
120
121#include <machine/clock.h>
122
123#include <dev/sn/if_snreg.h>
124#include <dev/sn/if_snvar.h>
125
126/* Exported variables */
127devclass_t sn_devclass;
128
129static int snioctl(struct ifnet * ifp, u_long, caddr_t);
130
131static void snresume(struct ifnet *);
132
133void sninit(void *);
134void snread(struct ifnet *);
135void snreset(struct sn_softc *);
136void snstart(struct ifnet *);
137void snstop(struct sn_softc *);
138void snwatchdog(struct ifnet *);
139
140static void sn_setmcast(struct sn_softc *);
141static int sn_getmcf(struct arpcom *ac, u_char *mcf);
142static u_int smc_crc(u_char *);
143
144/* I (GB) have been unlucky getting the hardware padding
145 * to work properly.
146 */
147#define SW_PAD
148
149static const char *chip_ids[15] = {
150 NULL, NULL, NULL,
151 /* 3 */ "SMC91C90/91C92",
152 /* 4 */ "SMC91C94",
153 /* 5 */ "SMC91C95",
154 NULL,
155 /* 7 */ "SMC91C100",
156 NULL, NULL, NULL, NULL,
157 NULL, NULL, NULL
158};
159
160int
161sn_attach(device_t dev)
162{
163 struct sn_softc *sc = device_get_softc(dev);
164 struct ifnet *ifp = &sc->arpcom.ac_if;
165 u_short i;
166 u_char *p;
167 struct ifaddr *ifa;
168 struct sockaddr_dl *sdl;
169 int rev;
170 u_short address;
171 int j;
172
173 sn_activate(dev);
174
175 snstop(sc);
176
177 sc->dev = dev;
178 sc->pages_wanted = -1;
179
180 device_printf(dev, " ");
181
182 SMC_SELECT_BANK(3);
183 rev = inw(BASE + REVISION_REG_W);
184 if (chip_ids[(rev >> 4) & 0xF])
185 printf("%s ", chip_ids[(rev >> 4) & 0xF]);
186
187 SMC_SELECT_BANK(1);
188 i = inw(BASE + CONFIG_REG_W);
189 printf(i & CR_AUI_SELECT ? "AUI" : "UTP");
190
191 if (sc->pccard_enaddr)
192 for (j = 0; j < 3; j++) {
193 u_short w;
194
195 w = (u_short)sc->arpcom.ac_enaddr[j * 2] |
196 (((u_short)sc->arpcom.ac_enaddr[j * 2 + 1]) << 8);
197 outw(BASE + IAR_ADDR0_REG_W + j * 2, w);
198 }
199
200 /*
201 * Read the station address from the chip. The MAC address is bank 1,
202 * regs 4 - 9
203 */
204 SMC_SELECT_BANK(1);
205 p = (u_char *) & sc->arpcom.ac_enaddr;
206 for (i = 0; i < 6; i += 2) {
207 address = inw(BASE + IAR_ADDR0_REG_W + i);
208 p[i + 1] = address >> 8;
209 p[i] = address & 0xFF;
210 }
211 printf(" MAC address %6D\n", sc->arpcom.ac_enaddr, ":");
212 ifp->if_softc = sc;
213 ifp->if_unit = device_get_unit(dev);
214 ifp->if_name = "sn";
215 ifp->if_mtu = ETHERMTU;
216 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
217 ifp->if_output = ether_output;
218 ifp->if_start = snstart;
219 ifp->if_ioctl = snioctl;
220 ifp->if_watchdog = snwatchdog;
221 ifp->if_init = sninit;
222 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
223 ifp->if_timer = 0;
224
225 if_attach(ifp);
226 ether_ifattach(ifp);
225 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
227
228 /*
229 * Fill the hardware address into ifa_addr if we find an AF_LINK
230 * entry. We need to do this so bpf's can get the hardware addr of
231 * this card. netstat likes this too!
232 */
233 ifa = TAILQ_FIRST(&ifp->if_addrhead);
234 while ((ifa != 0) && (ifa->ifa_addr != 0) &&
235 (ifa->ifa_addr->sa_family != AF_LINK))
236 ifa = TAILQ_NEXT(ifa, ifa_link);
237
238 if ((ifa != 0) && (ifa->ifa_addr != 0)) {
239 sdl = (struct sockaddr_dl *) ifa->ifa_addr;
240 sdl->sdl_type = IFT_ETHER;
241 sdl->sdl_alen = ETHER_ADDR_LEN;
242 sdl->sdl_slen = 0;
243 bcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
244 }
245
226
227 /*
228 * Fill the hardware address into ifa_addr if we find an AF_LINK
229 * entry. We need to do this so bpf's can get the hardware addr of
230 * this card. netstat likes this too!
231 */
232 ifa = TAILQ_FIRST(&ifp->if_addrhead);
233 while ((ifa != 0) && (ifa->ifa_addr != 0) &&
234 (ifa->ifa_addr->sa_family != AF_LINK))
235 ifa = TAILQ_NEXT(ifa, ifa_link);
236
237 if ((ifa != 0) && (ifa->ifa_addr != 0)) {
238 sdl = (struct sockaddr_dl *) ifa->ifa_addr;
239 sdl->sdl_type = IFT_ETHER;
240 sdl->sdl_alen = ETHER_ADDR_LEN;
241 sdl->sdl_slen = 0;
242 bcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
243 }
244
246 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
247
248 return 0;
249}
250
251
252/*
253 * Reset and initialize the chip
254 */
255void
256sninit(void *xsc)
257{
258 register struct sn_softc *sc = xsc;
259 register struct ifnet *ifp = &sc->arpcom.ac_if;
260 int s;
261 int flags;
262 int mask;
263
264 s = splimp();
265
266 /*
267 * This resets the registers mostly to defaults, but doesn't affect
268 * EEPROM. After the reset cycle, we pause briefly for the chip to
269 * be happy.
270 */
271 SMC_SELECT_BANK(0);
272 outw(BASE + RECV_CONTROL_REG_W, RCR_SOFTRESET);
273 SMC_DELAY();
274 outw(BASE + RECV_CONTROL_REG_W, 0x0000);
275 SMC_DELAY();
276 SMC_DELAY();
277
278 outw(BASE + TXMIT_CONTROL_REG_W, 0x0000);
279
280 /*
281 * Set the control register to automatically release succesfully
282 * transmitted packets (making the best use out of our limited
283 * memory) and to enable the EPH interrupt on certain TX errors.
284 */
285 SMC_SELECT_BANK(1);
286 outw(BASE + CONTROL_REG_W, (CTR_AUTO_RELEASE | CTR_TE_ENABLE |
287 CTR_CR_ENABLE | CTR_LE_ENABLE));
288
289 /* Set squelch level to 240mV (default 480mV) */
290 flags = inw(BASE + CONFIG_REG_W);
291 flags |= CR_SET_SQLCH;
292 outw(BASE + CONFIG_REG_W, flags);
293
294 /*
295 * Reset the MMU and wait for it to be un-busy.
296 */
297 SMC_SELECT_BANK(2);
298 outw(BASE + MMU_CMD_REG_W, MMUCR_RESET);
299 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
300 ;
301
302 /*
303 * Disable all interrupts
304 */
305 outb(BASE + INTR_MASK_REG_B, 0x00);
306
307 sn_setmcast(sc);
308
309 /*
310 * Set the transmitter control. We want it enabled.
311 */
312 flags = TCR_ENABLE;
313
314#ifndef SW_PAD
315 /*
316 * I (GB) have been unlucky getting this to work.
317 */
318 flags |= TCR_PAD_ENABLE;
319#endif /* SW_PAD */
320
321 outw(BASE + TXMIT_CONTROL_REG_W, flags);
322
323
324 /*
325 * Now, enable interrupts
326 */
327 SMC_SELECT_BANK(2);
328
329 mask = IM_EPH_INT |
330 IM_RX_OVRN_INT |
331 IM_RCV_INT |
332 IM_TX_INT;
333
334 outb(BASE + INTR_MASK_REG_B, mask);
335 sc->intr_mask = mask;
336 sc->pages_wanted = -1;
337
338
339 /*
340 * Mark the interface running but not active.
341 */
342 ifp->if_flags |= IFF_RUNNING;
343 ifp->if_flags &= ~IFF_OACTIVE;
344
345 /*
346 * Attempt to push out any waiting packets.
347 */
348 snstart(ifp);
349
350 splx(s);
351}
352
353
354void
355snstart(struct ifnet *ifp)
356{
357 register struct sn_softc *sc = ifp->if_softc;
358 register u_int len;
359 register struct mbuf *m;
360 struct mbuf *top;
361 int s, pad;
362 int mask;
363 u_short length;
364 u_short numPages;
365 u_char packet_no;
366 int time_out;
367
368 s = splimp();
369
370 if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) {
371 splx(s);
372 return;
373 }
374 if (sc->pages_wanted != -1) {
375 splx(s);
376 printf("sn%d: snstart() while memory allocation pending\n",
377 ifp->if_unit);
378 return;
379 }
380startagain:
381
382 /*
383 * Sneak a peek at the next packet
384 */
385 m = sc->arpcom.ac_if.if_snd.ifq_head;
386 if (m == 0) {
387 splx(s);
388 return;
389 }
390 /*
391 * Compute the frame length and set pad to give an overall even
392 * number of bytes. Below we assume that the packet length is even.
393 */
394 for (len = 0, top = m; m; m = m->m_next)
395 len += m->m_len;
396
397 pad = (len & 1);
398
399 /*
400 * We drop packets that are too large. Perhaps we should truncate
401 * them instead?
402 */
403 if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
404 printf("sn%d: large packet discarded (A)\n", ifp->if_unit);
405 ++sc->arpcom.ac_if.if_oerrors;
406 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
407 m_freem(m);
408 goto readcheck;
409 }
410#ifdef SW_PAD
411
412 /*
413 * If HW padding is not turned on, then pad to ETHER_MIN_LEN.
414 */
415 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
416 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
417
418#endif /* SW_PAD */
419
420 length = pad + len;
421
422 /*
423 * The MMU wants the number of pages to be the number of 256 byte
424 * 'pages', minus 1 (A packet can't ever have 0 pages. We also
425 * include space for the status word, byte count and control bytes in
426 * the allocation request.
427 */
428 numPages = (length + 6) >> 8;
429
430
431 /*
432 * Now, try to allocate the memory
433 */
434 SMC_SELECT_BANK(2);
435 outw(BASE + MMU_CMD_REG_W, MMUCR_ALLOC | numPages);
436
437 /*
438 * Wait a short amount of time to see if the allocation request
439 * completes. Otherwise, I enable the interrupt and wait for
440 * completion asyncronously.
441 */
442
443 time_out = MEMORY_WAIT_TIME;
444 do {
445 if (inb(BASE + INTR_STAT_REG_B) & IM_ALLOC_INT)
446 break;
447 } while (--time_out);
448
449 if (!time_out) {
450
451 /*
452 * No memory now. Oh well, wait until the chip finds memory
453 * later. Remember how many pages we were asking for and
454 * enable the allocation completion interrupt. Also set a
455 * watchdog in case we miss the interrupt. We mark the
456 * interface active since there is no point in attempting an
457 * snstart() until after the memory is available.
458 */
459 mask = inb(BASE + INTR_MASK_REG_B) | IM_ALLOC_INT;
460 outb(BASE + INTR_MASK_REG_B, mask);
461 sc->intr_mask = mask;
462
463 sc->arpcom.ac_if.if_timer = 1;
464 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
465 sc->pages_wanted = numPages;
466
467 splx(s);
468 return;
469 }
470 /*
471 * The memory allocation completed. Check the results.
472 */
473 packet_no = inb(BASE + ALLOC_RESULT_REG_B);
474 if (packet_no & ARR_FAILED) {
475 printf("sn%d: Memory allocation failed\n", ifp->if_unit);
476 goto startagain;
477 }
478 /*
479 * We have a packet number, so tell the card to use it.
480 */
481 outb(BASE + PACKET_NUM_REG_B, packet_no);
482
483 /*
484 * Point to the beginning of the packet
485 */
486 outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000);
487
488 /*
489 * Send the packet length (+6 for status, length and control byte)
490 * and the status word (set to zeros)
491 */
492 outw(BASE + DATA_REG_W, 0);
493 outb(BASE + DATA_REG_B, (length + 6) & 0xFF);
494 outb(BASE + DATA_REG_B, (length + 6) >> 8);
495
496 /*
497 * Get the packet from the kernel. This will include the Ethernet
498 * frame header, MAC Addresses etc.
499 */
500 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
501
502 /*
503 * Push out the data to the card.
504 */
505 for (top = m; m != 0; m = m->m_next) {
506
507 /*
508 * Push out words.
509 */
510 outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2);
511
512 /*
513 * Push out remaining byte.
514 */
515 if (m->m_len & 1)
516 outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1));
517 }
518
519 /*
520 * Push out padding.
521 */
522 while (pad > 1) {
523 outw(BASE + DATA_REG_W, 0);
524 pad -= 2;
525 }
526 if (pad)
527 outb(BASE + DATA_REG_B, 0);
528
529 /*
530 * Push out control byte and unused packet byte The control byte is 0
531 * meaning the packet is even lengthed and no special CRC handling is
532 * desired.
533 */
534 outw(BASE + DATA_REG_W, 0);
535
536 /*
537 * Enable the interrupts and let the chipset deal with it Also set a
538 * watchdog in case we miss the interrupt.
539 */
540 mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
541 outb(BASE + INTR_MASK_REG_B, mask);
542 sc->intr_mask = mask;
543
544 outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE);
545
546 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
547 sc->arpcom.ac_if.if_timer = 1;
548
549 if (ifp->if_bpf) {
550 bpf_mtap(ifp, top);
551 }
552
553 sc->arpcom.ac_if.if_opackets++;
554 m_freem(top);
555
556
557readcheck:
558
559 /*
560 * Is another packet coming in? We don't want to overflow the tiny
561 * RX FIFO. If nothing has arrived then attempt to queue another
562 * transmit packet.
563 */
564 if (inw(BASE + FIFO_PORTS_REG_W) & FIFO_REMPTY)
565 goto startagain;
566
567 splx(s);
568 return;
569}
570
571
572
573/* Resume a packet transmit operation after a memory allocation
574 * has completed.
575 *
576 * This is basically a hacked up copy of snstart() which handles
577 * a completed memory allocation the same way snstart() does.
578 * It then passes control to snstart to handle any other queued
579 * packets.
580 */
581static void
582snresume(struct ifnet *ifp)
583{
584 register struct sn_softc *sc = ifp->if_softc;
585 register u_int len;
586 register struct mbuf *m;
587 struct mbuf *top;
588 int pad;
589 int mask;
590 u_short length;
591 u_short numPages;
592 u_short pages_wanted;
593 u_char packet_no;
594
595 if (sc->pages_wanted < 0)
596 return;
597
598 pages_wanted = sc->pages_wanted;
599 sc->pages_wanted = -1;
600
601 /*
602 * Sneak a peek at the next packet
603 */
604 m = sc->arpcom.ac_if.if_snd.ifq_head;
605 if (m == 0) {
606 printf("sn%d: snresume() with nothing to send\n", ifp->if_unit);
607 return;
608 }
609 /*
610 * Compute the frame length and set pad to give an overall even
611 * number of bytes. Below we assume that the packet length is even.
612 */
613 for (len = 0, top = m; m; m = m->m_next)
614 len += m->m_len;
615
616 pad = (len & 1);
617
618 /*
619 * We drop packets that are too large. Perhaps we should truncate
620 * them instead?
621 */
622 if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
623 printf("sn%d: large packet discarded (B)\n", ifp->if_unit);
624 ++sc->arpcom.ac_if.if_oerrors;
625 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
626 m_freem(m);
627 return;
628 }
629#ifdef SW_PAD
630
631 /*
632 * If HW padding is not turned on, then pad to ETHER_MIN_LEN.
633 */
634 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
635 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
636
637#endif /* SW_PAD */
638
639 length = pad + len;
640
641
642 /*
643 * The MMU wants the number of pages to be the number of 256 byte
644 * 'pages', minus 1 (A packet can't ever have 0 pages. We also
645 * include space for the status word, byte count and control bytes in
646 * the allocation request.
647 */
648 numPages = (length + 6) >> 8;
649
650
651 SMC_SELECT_BANK(2);
652
653 /*
654 * The memory allocation completed. Check the results. If it failed,
655 * we simply set a watchdog timer and hope for the best.
656 */
657 packet_no = inb(BASE + ALLOC_RESULT_REG_B);
658 if (packet_no & ARR_FAILED) {
659 printf("sn%d: Memory allocation failed. Weird.\n", ifp->if_unit);
660 sc->arpcom.ac_if.if_timer = 1;
661 goto try_start;
662 }
663 /*
664 * We have a packet number, so tell the card to use it.
665 */
666 outb(BASE + PACKET_NUM_REG_B, packet_no);
667
668 /*
669 * Now, numPages should match the pages_wanted recorded when the
670 * memory allocation was initiated.
671 */
672 if (pages_wanted != numPages) {
673 printf("sn%d: memory allocation wrong size. Weird.\n", ifp->if_unit);
674 /*
675 * If the allocation was the wrong size we simply release the
676 * memory once it is granted. Wait for the MMU to be un-busy.
677 */
678 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
679 ;
680 outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
681
682 return;
683 }
684 /*
685 * Point to the beginning of the packet
686 */
687 outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000);
688
689 /*
690 * Send the packet length (+6 for status, length and control byte)
691 * and the status word (set to zeros)
692 */
693 outw(BASE + DATA_REG_W, 0);
694 outb(BASE + DATA_REG_B, (length + 6) & 0xFF);
695 outb(BASE + DATA_REG_B, (length + 6) >> 8);
696
697 /*
698 * Get the packet from the kernel. This will include the Ethernet
699 * frame header, MAC Addresses etc.
700 */
701 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
702
703 /*
704 * Push out the data to the card.
705 */
706 for (top = m; m != 0; m = m->m_next) {
707
708 /*
709 * Push out words.
710 */
711 outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2);
712
713 /*
714 * Push out remaining byte.
715 */
716 if (m->m_len & 1)
717 outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1));
718 }
719
720 /*
721 * Push out padding.
722 */
723 while (pad > 1) {
724 outw(BASE + DATA_REG_W, 0);
725 pad -= 2;
726 }
727 if (pad)
728 outb(BASE + DATA_REG_B, 0);
729
730 /*
731 * Push out control byte and unused packet byte The control byte is 0
732 * meaning the packet is even lengthed and no special CRC handling is
733 * desired.
734 */
735 outw(BASE + DATA_REG_W, 0);
736
737 /*
738 * Enable the interrupts and let the chipset deal with it Also set a
739 * watchdog in case we miss the interrupt.
740 */
741 mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
742 outb(BASE + INTR_MASK_REG_B, mask);
743 sc->intr_mask = mask;
744 outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE);
745
746 if (ifp->if_bpf) {
747 bpf_mtap(ifp, top);
748 }
749
750 sc->arpcom.ac_if.if_opackets++;
751 m_freem(top);
752
753try_start:
754
755 /*
756 * Now pass control to snstart() to queue any additional packets
757 */
758 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
759 snstart(ifp);
760
761 /*
762 * We've sent something, so we're active. Set a watchdog in case the
763 * TX_EMPTY interrupt is lost.
764 */
765 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
766 sc->arpcom.ac_if.if_timer = 1;
767
768 return;
769}
770
771
772void
773sn_intr(void *arg)
774{
775 int status, interrupts;
776 register struct sn_softc *sc = (struct sn_softc *) arg;
777 struct ifnet *ifp = &sc->arpcom.ac_if;
778 int x;
779
780 /*
781 * Chip state registers
782 */
783 u_char mask;
784 u_char packet_no;
785 u_short tx_status;
786 u_short card_stats;
787
788 /*
789 * if_ep.c did this, so I do too. Yet if_ed.c doesn't. I wonder...
790 */
791 x = splbio();
792
793 /*
794 * Clear the watchdog.
795 */
796 ifp->if_timer = 0;
797
798 SMC_SELECT_BANK(2);
799
800 /*
801 * Obtain the current interrupt mask and clear the hardware mask
802 * while servicing interrupts.
803 */
804 mask = inb(BASE + INTR_MASK_REG_B);
805 outb(BASE + INTR_MASK_REG_B, 0x00);
806
807 /*
808 * Get the set of interrupts which occurred and eliminate any which
809 * are masked.
810 */
811 interrupts = inb(BASE + INTR_STAT_REG_B);
812 status = interrupts & mask;
813
814 /*
815 * Now, process each of the interrupt types.
816 */
817
818 /*
819 * Receive Overrun.
820 */
821 if (status & IM_RX_OVRN_INT) {
822
823 /*
824 * Acknowlege Interrupt
825 */
826 SMC_SELECT_BANK(2);
827 outb(BASE + INTR_ACK_REG_B, IM_RX_OVRN_INT);
828
829 ++sc->arpcom.ac_if.if_ierrors;
830 }
831 /*
832 * Got a packet.
833 */
834 if (status & IM_RCV_INT) {
835#if 1
836 int packet_number;
837
838 SMC_SELECT_BANK(2);
839 packet_number = inw(BASE + FIFO_PORTS_REG_W);
840
841 if (packet_number & FIFO_REMPTY) {
842
843 /*
844 * we got called , but nothing was on the FIFO
845 */
846 printf("sn: Receive interrupt with nothing on FIFO\n");
847
848 goto out;
849 }
850#endif
851 snread(ifp);
852 }
853 /*
854 * An on-card memory allocation came through.
855 */
856 if (status & IM_ALLOC_INT) {
857
858 /*
859 * Disable this interrupt.
860 */
861 mask &= ~IM_ALLOC_INT;
862 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
863 snresume(&sc->arpcom.ac_if);
864 }
865 /*
866 * TX Completion. Handle a transmit error message. This will only be
867 * called when there is an error, because of the AUTO_RELEASE mode.
868 */
869 if (status & IM_TX_INT) {
870
871 /*
872 * Acknowlege Interrupt
873 */
874 SMC_SELECT_BANK(2);
875 outb(BASE + INTR_ACK_REG_B, IM_TX_INT);
876
877 packet_no = inw(BASE + FIFO_PORTS_REG_W);
878 packet_no &= FIFO_TX_MASK;
879
880 /*
881 * select this as the packet to read from
882 */
883 outb(BASE + PACKET_NUM_REG_B, packet_no);
884
885 /*
886 * Position the pointer to the first word from this packet
887 */
888 outw(BASE + POINTER_REG_W, PTR_AUTOINC | PTR_READ | 0x0000);
889
890 /*
891 * Fetch the TX status word. The value found here will be a
892 * copy of the EPH_STATUS_REG_W at the time the transmit
893 * failed.
894 */
895 tx_status = inw(BASE + DATA_REG_W);
896
897 if (tx_status & EPHSR_TX_SUC) {
898 device_printf(sc->dev,
899 "Successful packet caused interrupt\n");
900 } else {
901 ++sc->arpcom.ac_if.if_oerrors;
902 }
903
904 if (tx_status & EPHSR_LATCOL)
905 ++sc->arpcom.ac_if.if_collisions;
906
907 /*
908 * Some of these errors will have disabled transmit.
909 * Re-enable transmit now.
910 */
911 SMC_SELECT_BANK(0);
912
913#ifdef SW_PAD
914 outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE);
915#else
916 outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE | TCR_PAD_ENABLE);
917#endif /* SW_PAD */
918
919 /*
920 * kill the failed packet. Wait for the MMU to be un-busy.
921 */
922 SMC_SELECT_BANK(2);
923 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
924 ;
925 outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
926
927 /*
928 * Attempt to queue more transmits.
929 */
930 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
931 snstart(&sc->arpcom.ac_if);
932 }
933 /*
934 * Transmit underrun. We use this opportunity to update transmit
935 * statistics from the card.
936 */
937 if (status & IM_TX_EMPTY_INT) {
938
939 /*
940 * Acknowlege Interrupt
941 */
942 SMC_SELECT_BANK(2);
943 outb(BASE + INTR_ACK_REG_B, IM_TX_EMPTY_INT);
944
945 /*
946 * Disable this interrupt.
947 */
948 mask &= ~IM_TX_EMPTY_INT;
949
950 SMC_SELECT_BANK(0);
951 card_stats = inw(BASE + COUNTER_REG_W);
952
953 /*
954 * Single collisions
955 */
956 sc->arpcom.ac_if.if_collisions += card_stats & ECR_COLN_MASK;
957
958 /*
959 * Multiple collisions
960 */
961 sc->arpcom.ac_if.if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4;
962
963 SMC_SELECT_BANK(2);
964
965 /*
966 * Attempt to enqueue some more stuff.
967 */
968 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
969 snstart(&sc->arpcom.ac_if);
970 }
971 /*
972 * Some other error. Try to fix it by resetting the adapter.
973 */
974 if (status & IM_EPH_INT) {
975 snstop(sc);
976 sninit(sc);
977 }
978
979out:
980 /*
981 * Handled all interrupt sources.
982 */
983
984 SMC_SELECT_BANK(2);
985
986 /*
987 * Reestablish interrupts from mask which have not been deselected
988 * during this interrupt. Note that the hardware mask, which was set
989 * to 0x00 at the start of this service routine, may have been
990 * updated by one or more of the interrupt handers and we must let
991 * those new interrupts stay enabled here.
992 */
993 mask |= inb(BASE + INTR_MASK_REG_B);
994 outb(BASE + INTR_MASK_REG_B, mask);
995 sc->intr_mask = mask;
996
997 splx(x);
998}
999
1000void
1001snread(register struct ifnet *ifp)
1002{
1003 struct sn_softc *sc = ifp->if_softc;
1004 struct ether_header *eh;
1005 struct mbuf *m;
1006 short status;
1007 int packet_number;
1008 u_short packet_length;
1009 u_char *data;
1010
1011 SMC_SELECT_BANK(2);
1012#if 0
1013 packet_number = inw(BASE + FIFO_PORTS_REG_W);
1014
1015 if (packet_number & FIFO_REMPTY) {
1016
1017 /*
1018 * we got called , but nothing was on the FIFO
1019 */
1020 printf("sn: Receive interrupt with nothing on FIFO\n");
1021 return;
1022 }
1023#endif
1024read_another:
1025
1026 /*
1027 * Start reading from the start of the packet. Since PTR_RCV is set,
1028 * packet number is found in FIFO_PORTS_REG_W, FIFO_RX_MASK.
1029 */
1030 outw(BASE + POINTER_REG_W, PTR_READ | PTR_RCV | PTR_AUTOINC | 0x0000);
1031
1032 /*
1033 * First two words are status and packet_length
1034 */
1035 status = inw(BASE + DATA_REG_W);
1036 packet_length = inw(BASE + DATA_REG_W) & RLEN_MASK;
1037
1038 /*
1039 * The packet length contains 3 extra words: status, length, and a
1040 * extra word with the control byte.
1041 */
1042 packet_length -= 6;
1043
1044 /*
1045 * Account for receive errors and discard.
1046 */
1047 if (status & RS_ERRORS) {
1048 ++sc->arpcom.ac_if.if_ierrors;
1049 goto out;
1050 }
1051 /*
1052 * A packet is received.
1053 */
1054
1055 /*
1056 * Adjust for odd-length packet.
1057 */
1058 if (status & RS_ODDFRAME)
1059 packet_length++;
1060
1061 /*
1062 * Allocate a header mbuf from the kernel.
1063 */
1064 MGETHDR(m, M_DONTWAIT, MT_DATA);
1065 if (m == NULL)
1066 goto out;
1067
1068 m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
1069 m->m_pkthdr.len = m->m_len = packet_length;
1070
1071 /*
1072 * Attach an mbuf cluster
1073 */
1074 MCLGET(m, M_DONTWAIT);
1075
1076 /*
1077 * Insist on getting a cluster
1078 */
1079 if ((m->m_flags & M_EXT) == 0) {
1080 m_freem(m);
1081 ++sc->arpcom.ac_if.if_ierrors;
1082 printf("sn: snread() kernel memory allocation problem\n");
1083 goto out;
1084 }
1085 eh = mtod(m, struct ether_header *);
1086
1087 /*
1088 * Get packet, including link layer address, from interface.
1089 */
1090
1091 data = (u_char *) eh;
1092 insw(BASE + DATA_REG_W, data, packet_length >> 1);
1093 if (packet_length & 1) {
1094 data += packet_length & ~1;
1095 *data = inb(BASE + DATA_REG_B);
1096 }
1097 ++sc->arpcom.ac_if.if_ipackets;
1098
1099 /*
1100 * Remove link layer addresses and whatnot.
1101 */
1102 m->m_pkthdr.len = m->m_len = packet_length - sizeof(struct ether_header);
1103 m->m_data += sizeof(struct ether_header);
1104
1105 ether_input(&sc->arpcom.ac_if, eh, m);
1106
1107out:
1108
1109 /*
1110 * Error or good, tell the card to get rid of this packet Wait for
1111 * the MMU to be un-busy.
1112 */
1113 SMC_SELECT_BANK(2);
1114 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
1115 ;
1116 outw(BASE + MMU_CMD_REG_W, MMUCR_RELEASE);
1117
1118 /*
1119 * Check whether another packet is ready
1120 */
1121 packet_number = inw(BASE + FIFO_PORTS_REG_W);
1122 if (packet_number & FIFO_REMPTY) {
1123 return;
1124 }
1125 goto read_another;
1126}
1127
1128
1129/*
1130 * Handle IOCTLS. This function is completely stolen from if_ep.c
1131 * As with its progenitor, it does not handle hardware address
1132 * changes.
1133 */
1134static int
1135snioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
1136{
1137 struct sn_softc *sc = ifp->if_softc;
1138 int s, error = 0;
1139
1140 s = splimp();
1141
1142 switch (cmd) {
1143 case SIOCSIFADDR:
1144 case SIOCGIFADDR:
1145 case SIOCSIFMTU:
1146 error = ether_ioctl(ifp, cmd, data);
1147 break;
1148
1149 case SIOCSIFFLAGS:
1150 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
1151 ifp->if_flags &= ~IFF_RUNNING;
1152 snstop(sc);
1153 break;
1154 } else {
1155 /* reinitialize card on any parameter change */
1156 sninit(sc);
1157 break;
1158 }
1159 break;
1160
1161#ifdef notdef
1162 case SIOCGHWADDR:
1163 bcopy((caddr_t) sc->sc_addr, (caddr_t) & ifr->ifr_data,
1164 sizeof(sc->sc_addr));
1165 break;
1166#endif
1167
1168 case SIOCADDMULTI:
1169 /* update multicast filter list. */
1170 sn_setmcast(sc);
1171 error = 0;
1172 break;
1173 case SIOCDELMULTI:
1174 /* update multicast filter list. */
1175 sn_setmcast(sc);
1176 error = 0;
1177 break;
1178 default:
1179 error = EINVAL;
1180 }
1181
1182 splx(s);
1183
1184 return (error);
1185}
1186
1187void
1188snreset(struct sn_softc *sc)
1189{
1190 int s;
1191
1192 s = splimp();
1193 snstop(sc);
1194 sninit(sc);
1195
1196 splx(s);
1197}
1198
1199void
1200snwatchdog(struct ifnet *ifp)
1201{
1202 int s;
1203 s = splimp();
1204 sn_intr(ifp->if_softc);
1205 splx(s);
1206}
1207
1208
1209/* 1. zero the interrupt mask
1210 * 2. clear the enable receive flag
1211 * 3. clear the enable xmit flags
1212 */
1213void
1214snstop(struct sn_softc *sc)
1215{
1216
1217 struct ifnet *ifp = &sc->arpcom.ac_if;
1218
1219 /*
1220 * Clear interrupt mask; disable all interrupts.
1221 */
1222 SMC_SELECT_BANK(2);
1223 outb(BASE + INTR_MASK_REG_B, 0x00);
1224
1225 /*
1226 * Disable transmitter and Receiver
1227 */
1228 SMC_SELECT_BANK(0);
1229 outw(BASE + RECV_CONTROL_REG_W, 0x0000);
1230 outw(BASE + TXMIT_CONTROL_REG_W, 0x0000);
1231
1232 /*
1233 * Cancel watchdog.
1234 */
1235 ifp->if_timer = 0;
1236}
1237
1238
1239int
1240sn_activate(device_t dev)
1241{
1242 struct sn_softc *sc = device_get_softc(dev);
1243 int err;
1244
1245 sc->port_rid = 0;
1246 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
1247 0, ~0, SMC_IO_EXTENT, RF_ACTIVE);
1248 if (!sc->port_res) {
1249#ifdef SN_DEBUG
1250 device_printf(dev, "Cannot allocate ioport\n");
1251#endif
1252 return ENOMEM;
1253 }
1254
1255 sc->irq_rid = 0;
1256 sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
1257 0, ~0, 1, RF_ACTIVE);
1258 if (!sc->irq_res) {
1259#ifdef SN_DEBUG
1260 device_printf(dev, "Cannot allocate irq\n");
1261#endif
1262 sn_deactivate(dev);
1263 return ENOMEM;
1264 }
1265 if ((err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, sn_intr, sc,
1266 &sc->intrhand)) != 0) {
1267 sn_deactivate(dev);
1268 return err;
1269 }
1270
1271 sc->sn_io_addr = rman_get_start(sc->port_res);
1272 return (0);
1273}
1274
1275void
1276sn_deactivate(device_t dev)
1277{
1278 struct sn_softc *sc = device_get_softc(dev);
1279
1280 if (sc->intrhand)
1281 bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
1282 sc->intrhand = 0;
1283 if (sc->port_res)
1284 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
1285 sc->port_res);
1286 sc->port_res = 0;
1287 if (sc->irq_res)
1288 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1289 sc->irq_res);
1290 sc->irq_res = 0;
1291 return;
1292}
1293
1294/*
1295 * Function: sn_probe( device_t dev, int pccard )
1296 *
1297 * Purpose:
1298 * Tests to see if a given ioaddr points to an SMC9xxx chip.
1299 * Tries to cause as little damage as possible if it's not a SMC chip.
1300 * Returns a 0 on success
1301 *
1302 * Algorithm:
1303 * (1) see if the high byte of BANK_SELECT is 0x33
1304 * (2) compare the ioaddr with the base register's address
1305 * (3) see if I recognize the chip ID in the appropriate register
1306 *
1307 *
1308 */
1309int
1310sn_probe(device_t dev, int pccard)
1311{
1312 struct sn_softc *sc = device_get_softc(dev);
1313 u_int bank;
1314 u_short revision_register;
1315 u_short base_address_register;
1316 u_short ioaddr;
1317 int err;
1318
1319 if ((err = sn_activate(dev)) != 0)
1320 return err;
1321
1322 ioaddr = sc->sn_io_addr;
1323
1324 /*
1325 * First, see if the high byte is 0x33
1326 */
1327 bank = inw(ioaddr + BANK_SELECT_REG_W);
1328 if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
1329#ifdef SN_DEBUG
1330 device_printf(dev, "test1 failed\n");
1331#endif
1332 goto error;
1333 }
1334 /*
1335 * The above MIGHT indicate a device, but I need to write to further
1336 * test this. Go to bank 0, then test that the register still
1337 * reports the high byte is 0x33.
1338 */
1339 outw(ioaddr + BANK_SELECT_REG_W, 0x0000);
1340 bank = inw(ioaddr + BANK_SELECT_REG_W);
1341 if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
1342#ifdef SN_DEBUG
1343 device_printf(dev, "test2 failed\n");
1344#endif
1345 goto error;
1346 }
1347 /*
1348 * well, we've already written once, so hopefully another time won't
1349 * hurt. This time, I need to switch the bank register to bank 1, so
1350 * I can access the base address register. The contents of the
1351 * BASE_ADDR_REG_W register, after some jiggery pokery, is expected
1352 * to match the I/O port address where the adapter is being probed.
1353 */
1354 outw(ioaddr + BANK_SELECT_REG_W, 0x0001);
1355 base_address_register = inw(ioaddr + BASE_ADDR_REG_W);
1356
1357 /*
1358 * This test is nonsence on PC-card architecture, so if
1359 * pccard == 1, skip this test. (hosokawa)
1360 */
1361 if (!pccard && (ioaddr != (base_address_register >> 3 & 0x3E0))) {
1362
1363 /*
1364 * Well, the base address register didn't match. Must not
1365 * have been a SMC chip after all.
1366 */
1367 /*
1368 * printf("sn: ioaddr %x doesn't match card configuration
1369 * (%x)\n", ioaddr, base_address_register >> 3 & 0x3E0 );
1370 */
1371
1372#ifdef SN_DEBUG
1373 device_printf(dev, "test3 failed ioaddr = 0x%x, "
1374 "base_address_register = 0x%x\n", ioaddr,
1375 base_address_register >> 3 & 0x3E0);
1376#endif
1377 goto error;
1378 }
1379 /*
1380 * Check if the revision register is something that I recognize.
1381 * These might need to be added to later, as future revisions could
1382 * be added.
1383 */
1384 outw(ioaddr + BANK_SELECT_REG_W, 0x3);
1385 revision_register = inw(ioaddr + REVISION_REG_W);
1386 if (!chip_ids[(revision_register >> 4) & 0xF]) {
1387
1388 /*
1389 * I don't regonize this chip, so...
1390 */
1391#ifdef SN_DEBUG
1392 device_printf(dev, "test4 failed\n");
1393#endif
1394 goto error;
1395 }
1396 /*
1397 * at this point I'll assume that the chip is an SMC9xxx. It might be
1398 * prudent to check a listing of MAC addresses against the hardware
1399 * address, or do some other tests.
1400 */
1401 sn_deactivate(dev);
1402 return 0;
1403 error:
1404 sn_deactivate(dev);
1405 return ENXIO;
1406}
1407
1408#define MCFSZ 8
1409
1410static void
1411sn_setmcast(struct sn_softc *sc)
1412{
1413 struct ifnet *ifp = (struct ifnet *)sc;
1414 int flags;
1415
1416 /*
1417 * Set the receiver filter. We want receive enabled and auto strip
1418 * of CRC from received packet. If we are promiscuous then set that
1419 * bit too.
1420 */
1421 flags = RCR_ENABLE | RCR_STRIP_CRC;
1422
1423 if (ifp->if_flags & IFF_PROMISC) {
1424 flags |= RCR_PROMISC | RCR_ALMUL;
1425 } else if (ifp->if_flags & IFF_ALLMULTI) {
1426 flags |= RCR_ALMUL;
1427 } else {
1428 u_char mcf[MCFSZ];
1429 if (sn_getmcf(&sc->arpcom, mcf)) {
1430 /* set filter */
1431 SMC_SELECT_BANK(3);
1432 outw(BASE + MULTICAST1_REG_W,
1433 ((u_short)mcf[1] << 8) | mcf[0]);
1434 outw(BASE + MULTICAST2_REG_W,
1435 ((u_short)mcf[3] << 8) | mcf[2]);
1436 outw(BASE + MULTICAST3_REG_W,
1437 ((u_short)mcf[5] << 8) | mcf[4]);
1438 outw(BASE + MULTICAST4_REG_W,
1439 ((u_short)mcf[7] << 8) | mcf[6]);
1440 } else {
1441 flags |= RCR_ALMUL;
1442 }
1443 }
1444 SMC_SELECT_BANK(0);
1445 outw(BASE + RECV_CONTROL_REG_W, flags);
1446}
1447
1448static int
1449sn_getmcf(struct arpcom *ac, u_char *mcf)
1450{
1451 int i;
1452 register u_int index, index2;
1453 register u_char *af = (u_char *) mcf;
1454 struct ifmultiaddr *ifma;
1455
1456 bzero(mcf, MCFSZ);
1457
1458 for (ifma = ac->ac_if.if_multiaddrs.lh_first; ifma;
1459 ifma = ifma->ifma_link.le_next) {
1460 if (ifma->ifma_addr->sa_family != AF_LINK)
1461 return 0;
1462 index = smc_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)) & 0x3f;
1463 index2 = 0;
1464 for (i = 0; i < 6; i++) {
1465 index2 <<= 1;
1466 index2 |= (index & 0x01);
1467 index >>= 1;
1468 }
1469 af[index2 >> 3] |= 1 << (index2 & 7);
1470 }
1471 return 1; /* use multicast filter */
1472}
1473
1474static u_int
1475smc_crc(u_char *s)
1476{
1477 int perByte;
1478 int perBit;
1479 const u_int poly = 0xedb88320;
1480 u_int v = 0xffffffff;
1481 u_char c;
1482
1483 for (perByte = 0; perByte < ETHER_ADDR_LEN; perByte++) {
1484 c = s[perByte];
1485 for (perBit = 0; perBit < 8; perBit++) {
1486 v = (v >> 1)^(((v ^ c) & 0x01) ? poly : 0);
1487 c >>= 1;
1488 }
1489 }
1490 return v;
1491}
245 return 0;
246}
247
248
249/*
250 * Reset and initialize the chip
251 */
252void
253sninit(void *xsc)
254{
255 register struct sn_softc *sc = xsc;
256 register struct ifnet *ifp = &sc->arpcom.ac_if;
257 int s;
258 int flags;
259 int mask;
260
261 s = splimp();
262
263 /*
264 * This resets the registers mostly to defaults, but doesn't affect
265 * EEPROM. After the reset cycle, we pause briefly for the chip to
266 * be happy.
267 */
268 SMC_SELECT_BANK(0);
269 outw(BASE + RECV_CONTROL_REG_W, RCR_SOFTRESET);
270 SMC_DELAY();
271 outw(BASE + RECV_CONTROL_REG_W, 0x0000);
272 SMC_DELAY();
273 SMC_DELAY();
274
275 outw(BASE + TXMIT_CONTROL_REG_W, 0x0000);
276
277 /*
278 * Set the control register to automatically release succesfully
279 * transmitted packets (making the best use out of our limited
280 * memory) and to enable the EPH interrupt on certain TX errors.
281 */
282 SMC_SELECT_BANK(1);
283 outw(BASE + CONTROL_REG_W, (CTR_AUTO_RELEASE | CTR_TE_ENABLE |
284 CTR_CR_ENABLE | CTR_LE_ENABLE));
285
286 /* Set squelch level to 240mV (default 480mV) */
287 flags = inw(BASE + CONFIG_REG_W);
288 flags |= CR_SET_SQLCH;
289 outw(BASE + CONFIG_REG_W, flags);
290
291 /*
292 * Reset the MMU and wait for it to be un-busy.
293 */
294 SMC_SELECT_BANK(2);
295 outw(BASE + MMU_CMD_REG_W, MMUCR_RESET);
296 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
297 ;
298
299 /*
300 * Disable all interrupts
301 */
302 outb(BASE + INTR_MASK_REG_B, 0x00);
303
304 sn_setmcast(sc);
305
306 /*
307 * Set the transmitter control. We want it enabled.
308 */
309 flags = TCR_ENABLE;
310
311#ifndef SW_PAD
312 /*
313 * I (GB) have been unlucky getting this to work.
314 */
315 flags |= TCR_PAD_ENABLE;
316#endif /* SW_PAD */
317
318 outw(BASE + TXMIT_CONTROL_REG_W, flags);
319
320
321 /*
322 * Now, enable interrupts
323 */
324 SMC_SELECT_BANK(2);
325
326 mask = IM_EPH_INT |
327 IM_RX_OVRN_INT |
328 IM_RCV_INT |
329 IM_TX_INT;
330
331 outb(BASE + INTR_MASK_REG_B, mask);
332 sc->intr_mask = mask;
333 sc->pages_wanted = -1;
334
335
336 /*
337 * Mark the interface running but not active.
338 */
339 ifp->if_flags |= IFF_RUNNING;
340 ifp->if_flags &= ~IFF_OACTIVE;
341
342 /*
343 * Attempt to push out any waiting packets.
344 */
345 snstart(ifp);
346
347 splx(s);
348}
349
350
351void
352snstart(struct ifnet *ifp)
353{
354 register struct sn_softc *sc = ifp->if_softc;
355 register u_int len;
356 register struct mbuf *m;
357 struct mbuf *top;
358 int s, pad;
359 int mask;
360 u_short length;
361 u_short numPages;
362 u_char packet_no;
363 int time_out;
364
365 s = splimp();
366
367 if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) {
368 splx(s);
369 return;
370 }
371 if (sc->pages_wanted != -1) {
372 splx(s);
373 printf("sn%d: snstart() while memory allocation pending\n",
374 ifp->if_unit);
375 return;
376 }
377startagain:
378
379 /*
380 * Sneak a peek at the next packet
381 */
382 m = sc->arpcom.ac_if.if_snd.ifq_head;
383 if (m == 0) {
384 splx(s);
385 return;
386 }
387 /*
388 * Compute the frame length and set pad to give an overall even
389 * number of bytes. Below we assume that the packet length is even.
390 */
391 for (len = 0, top = m; m; m = m->m_next)
392 len += m->m_len;
393
394 pad = (len & 1);
395
396 /*
397 * We drop packets that are too large. Perhaps we should truncate
398 * them instead?
399 */
400 if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
401 printf("sn%d: large packet discarded (A)\n", ifp->if_unit);
402 ++sc->arpcom.ac_if.if_oerrors;
403 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
404 m_freem(m);
405 goto readcheck;
406 }
407#ifdef SW_PAD
408
409 /*
410 * If HW padding is not turned on, then pad to ETHER_MIN_LEN.
411 */
412 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
413 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
414
415#endif /* SW_PAD */
416
417 length = pad + len;
418
419 /*
420 * The MMU wants the number of pages to be the number of 256 byte
421 * 'pages', minus 1 (A packet can't ever have 0 pages. We also
422 * include space for the status word, byte count and control bytes in
423 * the allocation request.
424 */
425 numPages = (length + 6) >> 8;
426
427
428 /*
429 * Now, try to allocate the memory
430 */
431 SMC_SELECT_BANK(2);
432 outw(BASE + MMU_CMD_REG_W, MMUCR_ALLOC | numPages);
433
434 /*
435 * Wait a short amount of time to see if the allocation request
436 * completes. Otherwise, I enable the interrupt and wait for
437 * completion asyncronously.
438 */
439
440 time_out = MEMORY_WAIT_TIME;
441 do {
442 if (inb(BASE + INTR_STAT_REG_B) & IM_ALLOC_INT)
443 break;
444 } while (--time_out);
445
446 if (!time_out) {
447
448 /*
449 * No memory now. Oh well, wait until the chip finds memory
450 * later. Remember how many pages we were asking for and
451 * enable the allocation completion interrupt. Also set a
452 * watchdog in case we miss the interrupt. We mark the
453 * interface active since there is no point in attempting an
454 * snstart() until after the memory is available.
455 */
456 mask = inb(BASE + INTR_MASK_REG_B) | IM_ALLOC_INT;
457 outb(BASE + INTR_MASK_REG_B, mask);
458 sc->intr_mask = mask;
459
460 sc->arpcom.ac_if.if_timer = 1;
461 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
462 sc->pages_wanted = numPages;
463
464 splx(s);
465 return;
466 }
467 /*
468 * The memory allocation completed. Check the results.
469 */
470 packet_no = inb(BASE + ALLOC_RESULT_REG_B);
471 if (packet_no & ARR_FAILED) {
472 printf("sn%d: Memory allocation failed\n", ifp->if_unit);
473 goto startagain;
474 }
475 /*
476 * We have a packet number, so tell the card to use it.
477 */
478 outb(BASE + PACKET_NUM_REG_B, packet_no);
479
480 /*
481 * Point to the beginning of the packet
482 */
483 outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000);
484
485 /*
486 * Send the packet length (+6 for status, length and control byte)
487 * and the status word (set to zeros)
488 */
489 outw(BASE + DATA_REG_W, 0);
490 outb(BASE + DATA_REG_B, (length + 6) & 0xFF);
491 outb(BASE + DATA_REG_B, (length + 6) >> 8);
492
493 /*
494 * Get the packet from the kernel. This will include the Ethernet
495 * frame header, MAC Addresses etc.
496 */
497 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
498
499 /*
500 * Push out the data to the card.
501 */
502 for (top = m; m != 0; m = m->m_next) {
503
504 /*
505 * Push out words.
506 */
507 outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2);
508
509 /*
510 * Push out remaining byte.
511 */
512 if (m->m_len & 1)
513 outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1));
514 }
515
516 /*
517 * Push out padding.
518 */
519 while (pad > 1) {
520 outw(BASE + DATA_REG_W, 0);
521 pad -= 2;
522 }
523 if (pad)
524 outb(BASE + DATA_REG_B, 0);
525
526 /*
527 * Push out control byte and unused packet byte The control byte is 0
528 * meaning the packet is even lengthed and no special CRC handling is
529 * desired.
530 */
531 outw(BASE + DATA_REG_W, 0);
532
533 /*
534 * Enable the interrupts and let the chipset deal with it Also set a
535 * watchdog in case we miss the interrupt.
536 */
537 mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
538 outb(BASE + INTR_MASK_REG_B, mask);
539 sc->intr_mask = mask;
540
541 outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE);
542
543 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
544 sc->arpcom.ac_if.if_timer = 1;
545
546 if (ifp->if_bpf) {
547 bpf_mtap(ifp, top);
548 }
549
550 sc->arpcom.ac_if.if_opackets++;
551 m_freem(top);
552
553
554readcheck:
555
556 /*
557 * Is another packet coming in? We don't want to overflow the tiny
558 * RX FIFO. If nothing has arrived then attempt to queue another
559 * transmit packet.
560 */
561 if (inw(BASE + FIFO_PORTS_REG_W) & FIFO_REMPTY)
562 goto startagain;
563
564 splx(s);
565 return;
566}
567
568
569
570/* Resume a packet transmit operation after a memory allocation
571 * has completed.
572 *
573 * This is basically a hacked up copy of snstart() which handles
574 * a completed memory allocation the same way snstart() does.
575 * It then passes control to snstart to handle any other queued
576 * packets.
577 */
578static void
579snresume(struct ifnet *ifp)
580{
581 register struct sn_softc *sc = ifp->if_softc;
582 register u_int len;
583 register struct mbuf *m;
584 struct mbuf *top;
585 int pad;
586 int mask;
587 u_short length;
588 u_short numPages;
589 u_short pages_wanted;
590 u_char packet_no;
591
592 if (sc->pages_wanted < 0)
593 return;
594
595 pages_wanted = sc->pages_wanted;
596 sc->pages_wanted = -1;
597
598 /*
599 * Sneak a peek at the next packet
600 */
601 m = sc->arpcom.ac_if.if_snd.ifq_head;
602 if (m == 0) {
603 printf("sn%d: snresume() with nothing to send\n", ifp->if_unit);
604 return;
605 }
606 /*
607 * Compute the frame length and set pad to give an overall even
608 * number of bytes. Below we assume that the packet length is even.
609 */
610 for (len = 0, top = m; m; m = m->m_next)
611 len += m->m_len;
612
613 pad = (len & 1);
614
615 /*
616 * We drop packets that are too large. Perhaps we should truncate
617 * them instead?
618 */
619 if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
620 printf("sn%d: large packet discarded (B)\n", ifp->if_unit);
621 ++sc->arpcom.ac_if.if_oerrors;
622 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
623 m_freem(m);
624 return;
625 }
626#ifdef SW_PAD
627
628 /*
629 * If HW padding is not turned on, then pad to ETHER_MIN_LEN.
630 */
631 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
632 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
633
634#endif /* SW_PAD */
635
636 length = pad + len;
637
638
639 /*
640 * The MMU wants the number of pages to be the number of 256 byte
641 * 'pages', minus 1 (A packet can't ever have 0 pages. We also
642 * include space for the status word, byte count and control bytes in
643 * the allocation request.
644 */
645 numPages = (length + 6) >> 8;
646
647
648 SMC_SELECT_BANK(2);
649
650 /*
651 * The memory allocation completed. Check the results. If it failed,
652 * we simply set a watchdog timer and hope for the best.
653 */
654 packet_no = inb(BASE + ALLOC_RESULT_REG_B);
655 if (packet_no & ARR_FAILED) {
656 printf("sn%d: Memory allocation failed. Weird.\n", ifp->if_unit);
657 sc->arpcom.ac_if.if_timer = 1;
658 goto try_start;
659 }
660 /*
661 * We have a packet number, so tell the card to use it.
662 */
663 outb(BASE + PACKET_NUM_REG_B, packet_no);
664
665 /*
666 * Now, numPages should match the pages_wanted recorded when the
667 * memory allocation was initiated.
668 */
669 if (pages_wanted != numPages) {
670 printf("sn%d: memory allocation wrong size. Weird.\n", ifp->if_unit);
671 /*
672 * If the allocation was the wrong size we simply release the
673 * memory once it is granted. Wait for the MMU to be un-busy.
674 */
675 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
676 ;
677 outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
678
679 return;
680 }
681 /*
682 * Point to the beginning of the packet
683 */
684 outw(BASE + POINTER_REG_W, PTR_AUTOINC | 0x0000);
685
686 /*
687 * Send the packet length (+6 for status, length and control byte)
688 * and the status word (set to zeros)
689 */
690 outw(BASE + DATA_REG_W, 0);
691 outb(BASE + DATA_REG_B, (length + 6) & 0xFF);
692 outb(BASE + DATA_REG_B, (length + 6) >> 8);
693
694 /*
695 * Get the packet from the kernel. This will include the Ethernet
696 * frame header, MAC Addresses etc.
697 */
698 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
699
700 /*
701 * Push out the data to the card.
702 */
703 for (top = m; m != 0; m = m->m_next) {
704
705 /*
706 * Push out words.
707 */
708 outsw(BASE + DATA_REG_W, mtod(m, caddr_t), m->m_len / 2);
709
710 /*
711 * Push out remaining byte.
712 */
713 if (m->m_len & 1)
714 outb(BASE + DATA_REG_B, *(mtod(m, caddr_t) + m->m_len - 1));
715 }
716
717 /*
718 * Push out padding.
719 */
720 while (pad > 1) {
721 outw(BASE + DATA_REG_W, 0);
722 pad -= 2;
723 }
724 if (pad)
725 outb(BASE + DATA_REG_B, 0);
726
727 /*
728 * Push out control byte and unused packet byte The control byte is 0
729 * meaning the packet is even lengthed and no special CRC handling is
730 * desired.
731 */
732 outw(BASE + DATA_REG_W, 0);
733
734 /*
735 * Enable the interrupts and let the chipset deal with it Also set a
736 * watchdog in case we miss the interrupt.
737 */
738 mask = inb(BASE + INTR_MASK_REG_B) | (IM_TX_INT | IM_TX_EMPTY_INT);
739 outb(BASE + INTR_MASK_REG_B, mask);
740 sc->intr_mask = mask;
741 outw(BASE + MMU_CMD_REG_W, MMUCR_ENQUEUE);
742
743 if (ifp->if_bpf) {
744 bpf_mtap(ifp, top);
745 }
746
747 sc->arpcom.ac_if.if_opackets++;
748 m_freem(top);
749
750try_start:
751
752 /*
753 * Now pass control to snstart() to queue any additional packets
754 */
755 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
756 snstart(ifp);
757
758 /*
759 * We've sent something, so we're active. Set a watchdog in case the
760 * TX_EMPTY interrupt is lost.
761 */
762 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
763 sc->arpcom.ac_if.if_timer = 1;
764
765 return;
766}
767
768
769void
770sn_intr(void *arg)
771{
772 int status, interrupts;
773 register struct sn_softc *sc = (struct sn_softc *) arg;
774 struct ifnet *ifp = &sc->arpcom.ac_if;
775 int x;
776
777 /*
778 * Chip state registers
779 */
780 u_char mask;
781 u_char packet_no;
782 u_short tx_status;
783 u_short card_stats;
784
785 /*
786 * if_ep.c did this, so I do too. Yet if_ed.c doesn't. I wonder...
787 */
788 x = splbio();
789
790 /*
791 * Clear the watchdog.
792 */
793 ifp->if_timer = 0;
794
795 SMC_SELECT_BANK(2);
796
797 /*
798 * Obtain the current interrupt mask and clear the hardware mask
799 * while servicing interrupts.
800 */
801 mask = inb(BASE + INTR_MASK_REG_B);
802 outb(BASE + INTR_MASK_REG_B, 0x00);
803
804 /*
805 * Get the set of interrupts which occurred and eliminate any which
806 * are masked.
807 */
808 interrupts = inb(BASE + INTR_STAT_REG_B);
809 status = interrupts & mask;
810
811 /*
812 * Now, process each of the interrupt types.
813 */
814
815 /*
816 * Receive Overrun.
817 */
818 if (status & IM_RX_OVRN_INT) {
819
820 /*
821 * Acknowlege Interrupt
822 */
823 SMC_SELECT_BANK(2);
824 outb(BASE + INTR_ACK_REG_B, IM_RX_OVRN_INT);
825
826 ++sc->arpcom.ac_if.if_ierrors;
827 }
828 /*
829 * Got a packet.
830 */
831 if (status & IM_RCV_INT) {
832#if 1
833 int packet_number;
834
835 SMC_SELECT_BANK(2);
836 packet_number = inw(BASE + FIFO_PORTS_REG_W);
837
838 if (packet_number & FIFO_REMPTY) {
839
840 /*
841 * we got called , but nothing was on the FIFO
842 */
843 printf("sn: Receive interrupt with nothing on FIFO\n");
844
845 goto out;
846 }
847#endif
848 snread(ifp);
849 }
850 /*
851 * An on-card memory allocation came through.
852 */
853 if (status & IM_ALLOC_INT) {
854
855 /*
856 * Disable this interrupt.
857 */
858 mask &= ~IM_ALLOC_INT;
859 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
860 snresume(&sc->arpcom.ac_if);
861 }
862 /*
863 * TX Completion. Handle a transmit error message. This will only be
864 * called when there is an error, because of the AUTO_RELEASE mode.
865 */
866 if (status & IM_TX_INT) {
867
868 /*
869 * Acknowlege Interrupt
870 */
871 SMC_SELECT_BANK(2);
872 outb(BASE + INTR_ACK_REG_B, IM_TX_INT);
873
874 packet_no = inw(BASE + FIFO_PORTS_REG_W);
875 packet_no &= FIFO_TX_MASK;
876
877 /*
878 * select this as the packet to read from
879 */
880 outb(BASE + PACKET_NUM_REG_B, packet_no);
881
882 /*
883 * Position the pointer to the first word from this packet
884 */
885 outw(BASE + POINTER_REG_W, PTR_AUTOINC | PTR_READ | 0x0000);
886
887 /*
888 * Fetch the TX status word. The value found here will be a
889 * copy of the EPH_STATUS_REG_W at the time the transmit
890 * failed.
891 */
892 tx_status = inw(BASE + DATA_REG_W);
893
894 if (tx_status & EPHSR_TX_SUC) {
895 device_printf(sc->dev,
896 "Successful packet caused interrupt\n");
897 } else {
898 ++sc->arpcom.ac_if.if_oerrors;
899 }
900
901 if (tx_status & EPHSR_LATCOL)
902 ++sc->arpcom.ac_if.if_collisions;
903
904 /*
905 * Some of these errors will have disabled transmit.
906 * Re-enable transmit now.
907 */
908 SMC_SELECT_BANK(0);
909
910#ifdef SW_PAD
911 outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE);
912#else
913 outw(BASE + TXMIT_CONTROL_REG_W, TCR_ENABLE | TCR_PAD_ENABLE);
914#endif /* SW_PAD */
915
916 /*
917 * kill the failed packet. Wait for the MMU to be un-busy.
918 */
919 SMC_SELECT_BANK(2);
920 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
921 ;
922 outw(BASE + MMU_CMD_REG_W, MMUCR_FREEPKT);
923
924 /*
925 * Attempt to queue more transmits.
926 */
927 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
928 snstart(&sc->arpcom.ac_if);
929 }
930 /*
931 * Transmit underrun. We use this opportunity to update transmit
932 * statistics from the card.
933 */
934 if (status & IM_TX_EMPTY_INT) {
935
936 /*
937 * Acknowlege Interrupt
938 */
939 SMC_SELECT_BANK(2);
940 outb(BASE + INTR_ACK_REG_B, IM_TX_EMPTY_INT);
941
942 /*
943 * Disable this interrupt.
944 */
945 mask &= ~IM_TX_EMPTY_INT;
946
947 SMC_SELECT_BANK(0);
948 card_stats = inw(BASE + COUNTER_REG_W);
949
950 /*
951 * Single collisions
952 */
953 sc->arpcom.ac_if.if_collisions += card_stats & ECR_COLN_MASK;
954
955 /*
956 * Multiple collisions
957 */
958 sc->arpcom.ac_if.if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4;
959
960 SMC_SELECT_BANK(2);
961
962 /*
963 * Attempt to enqueue some more stuff.
964 */
965 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
966 snstart(&sc->arpcom.ac_if);
967 }
968 /*
969 * Some other error. Try to fix it by resetting the adapter.
970 */
971 if (status & IM_EPH_INT) {
972 snstop(sc);
973 sninit(sc);
974 }
975
976out:
977 /*
978 * Handled all interrupt sources.
979 */
980
981 SMC_SELECT_BANK(2);
982
983 /*
984 * Reestablish interrupts from mask which have not been deselected
985 * during this interrupt. Note that the hardware mask, which was set
986 * to 0x00 at the start of this service routine, may have been
987 * updated by one or more of the interrupt handers and we must let
988 * those new interrupts stay enabled here.
989 */
990 mask |= inb(BASE + INTR_MASK_REG_B);
991 outb(BASE + INTR_MASK_REG_B, mask);
992 sc->intr_mask = mask;
993
994 splx(x);
995}
996
997void
998snread(register struct ifnet *ifp)
999{
1000 struct sn_softc *sc = ifp->if_softc;
1001 struct ether_header *eh;
1002 struct mbuf *m;
1003 short status;
1004 int packet_number;
1005 u_short packet_length;
1006 u_char *data;
1007
1008 SMC_SELECT_BANK(2);
1009#if 0
1010 packet_number = inw(BASE + FIFO_PORTS_REG_W);
1011
1012 if (packet_number & FIFO_REMPTY) {
1013
1014 /*
1015 * we got called , but nothing was on the FIFO
1016 */
1017 printf("sn: Receive interrupt with nothing on FIFO\n");
1018 return;
1019 }
1020#endif
1021read_another:
1022
1023 /*
1024 * Start reading from the start of the packet. Since PTR_RCV is set,
1025 * packet number is found in FIFO_PORTS_REG_W, FIFO_RX_MASK.
1026 */
1027 outw(BASE + POINTER_REG_W, PTR_READ | PTR_RCV | PTR_AUTOINC | 0x0000);
1028
1029 /*
1030 * First two words are status and packet_length
1031 */
1032 status = inw(BASE + DATA_REG_W);
1033 packet_length = inw(BASE + DATA_REG_W) & RLEN_MASK;
1034
1035 /*
1036 * The packet length contains 3 extra words: status, length, and a
1037 * extra word with the control byte.
1038 */
1039 packet_length -= 6;
1040
1041 /*
1042 * Account for receive errors and discard.
1043 */
1044 if (status & RS_ERRORS) {
1045 ++sc->arpcom.ac_if.if_ierrors;
1046 goto out;
1047 }
1048 /*
1049 * A packet is received.
1050 */
1051
1052 /*
1053 * Adjust for odd-length packet.
1054 */
1055 if (status & RS_ODDFRAME)
1056 packet_length++;
1057
1058 /*
1059 * Allocate a header mbuf from the kernel.
1060 */
1061 MGETHDR(m, M_DONTWAIT, MT_DATA);
1062 if (m == NULL)
1063 goto out;
1064
1065 m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
1066 m->m_pkthdr.len = m->m_len = packet_length;
1067
1068 /*
1069 * Attach an mbuf cluster
1070 */
1071 MCLGET(m, M_DONTWAIT);
1072
1073 /*
1074 * Insist on getting a cluster
1075 */
1076 if ((m->m_flags & M_EXT) == 0) {
1077 m_freem(m);
1078 ++sc->arpcom.ac_if.if_ierrors;
1079 printf("sn: snread() kernel memory allocation problem\n");
1080 goto out;
1081 }
1082 eh = mtod(m, struct ether_header *);
1083
1084 /*
1085 * Get packet, including link layer address, from interface.
1086 */
1087
1088 data = (u_char *) eh;
1089 insw(BASE + DATA_REG_W, data, packet_length >> 1);
1090 if (packet_length & 1) {
1091 data += packet_length & ~1;
1092 *data = inb(BASE + DATA_REG_B);
1093 }
1094 ++sc->arpcom.ac_if.if_ipackets;
1095
1096 /*
1097 * Remove link layer addresses and whatnot.
1098 */
1099 m->m_pkthdr.len = m->m_len = packet_length - sizeof(struct ether_header);
1100 m->m_data += sizeof(struct ether_header);
1101
1102 ether_input(&sc->arpcom.ac_if, eh, m);
1103
1104out:
1105
1106 /*
1107 * Error or good, tell the card to get rid of this packet Wait for
1108 * the MMU to be un-busy.
1109 */
1110 SMC_SELECT_BANK(2);
1111 while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY) /* NOTHING */
1112 ;
1113 outw(BASE + MMU_CMD_REG_W, MMUCR_RELEASE);
1114
1115 /*
1116 * Check whether another packet is ready
1117 */
1118 packet_number = inw(BASE + FIFO_PORTS_REG_W);
1119 if (packet_number & FIFO_REMPTY) {
1120 return;
1121 }
1122 goto read_another;
1123}
1124
1125
1126/*
1127 * Handle IOCTLS. This function is completely stolen from if_ep.c
1128 * As with its progenitor, it does not handle hardware address
1129 * changes.
1130 */
1131static int
1132snioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
1133{
1134 struct sn_softc *sc = ifp->if_softc;
1135 int s, error = 0;
1136
1137 s = splimp();
1138
1139 switch (cmd) {
1140 case SIOCSIFADDR:
1141 case SIOCGIFADDR:
1142 case SIOCSIFMTU:
1143 error = ether_ioctl(ifp, cmd, data);
1144 break;
1145
1146 case SIOCSIFFLAGS:
1147 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
1148 ifp->if_flags &= ~IFF_RUNNING;
1149 snstop(sc);
1150 break;
1151 } else {
1152 /* reinitialize card on any parameter change */
1153 sninit(sc);
1154 break;
1155 }
1156 break;
1157
1158#ifdef notdef
1159 case SIOCGHWADDR:
1160 bcopy((caddr_t) sc->sc_addr, (caddr_t) & ifr->ifr_data,
1161 sizeof(sc->sc_addr));
1162 break;
1163#endif
1164
1165 case SIOCADDMULTI:
1166 /* update multicast filter list. */
1167 sn_setmcast(sc);
1168 error = 0;
1169 break;
1170 case SIOCDELMULTI:
1171 /* update multicast filter list. */
1172 sn_setmcast(sc);
1173 error = 0;
1174 break;
1175 default:
1176 error = EINVAL;
1177 }
1178
1179 splx(s);
1180
1181 return (error);
1182}
1183
1184void
1185snreset(struct sn_softc *sc)
1186{
1187 int s;
1188
1189 s = splimp();
1190 snstop(sc);
1191 sninit(sc);
1192
1193 splx(s);
1194}
1195
1196void
1197snwatchdog(struct ifnet *ifp)
1198{
1199 int s;
1200 s = splimp();
1201 sn_intr(ifp->if_softc);
1202 splx(s);
1203}
1204
1205
1206/* 1. zero the interrupt mask
1207 * 2. clear the enable receive flag
1208 * 3. clear the enable xmit flags
1209 */
1210void
1211snstop(struct sn_softc *sc)
1212{
1213
1214 struct ifnet *ifp = &sc->arpcom.ac_if;
1215
1216 /*
1217 * Clear interrupt mask; disable all interrupts.
1218 */
1219 SMC_SELECT_BANK(2);
1220 outb(BASE + INTR_MASK_REG_B, 0x00);
1221
1222 /*
1223 * Disable transmitter and Receiver
1224 */
1225 SMC_SELECT_BANK(0);
1226 outw(BASE + RECV_CONTROL_REG_W, 0x0000);
1227 outw(BASE + TXMIT_CONTROL_REG_W, 0x0000);
1228
1229 /*
1230 * Cancel watchdog.
1231 */
1232 ifp->if_timer = 0;
1233}
1234
1235
1236int
1237sn_activate(device_t dev)
1238{
1239 struct sn_softc *sc = device_get_softc(dev);
1240 int err;
1241
1242 sc->port_rid = 0;
1243 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
1244 0, ~0, SMC_IO_EXTENT, RF_ACTIVE);
1245 if (!sc->port_res) {
1246#ifdef SN_DEBUG
1247 device_printf(dev, "Cannot allocate ioport\n");
1248#endif
1249 return ENOMEM;
1250 }
1251
1252 sc->irq_rid = 0;
1253 sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
1254 0, ~0, 1, RF_ACTIVE);
1255 if (!sc->irq_res) {
1256#ifdef SN_DEBUG
1257 device_printf(dev, "Cannot allocate irq\n");
1258#endif
1259 sn_deactivate(dev);
1260 return ENOMEM;
1261 }
1262 if ((err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, sn_intr, sc,
1263 &sc->intrhand)) != 0) {
1264 sn_deactivate(dev);
1265 return err;
1266 }
1267
1268 sc->sn_io_addr = rman_get_start(sc->port_res);
1269 return (0);
1270}
1271
1272void
1273sn_deactivate(device_t dev)
1274{
1275 struct sn_softc *sc = device_get_softc(dev);
1276
1277 if (sc->intrhand)
1278 bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
1279 sc->intrhand = 0;
1280 if (sc->port_res)
1281 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
1282 sc->port_res);
1283 sc->port_res = 0;
1284 if (sc->irq_res)
1285 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1286 sc->irq_res);
1287 sc->irq_res = 0;
1288 return;
1289}
1290
1291/*
1292 * Function: sn_probe( device_t dev, int pccard )
1293 *
1294 * Purpose:
1295 * Tests to see if a given ioaddr points to an SMC9xxx chip.
1296 * Tries to cause as little damage as possible if it's not a SMC chip.
1297 * Returns a 0 on success
1298 *
1299 * Algorithm:
1300 * (1) see if the high byte of BANK_SELECT is 0x33
1301 * (2) compare the ioaddr with the base register's address
1302 * (3) see if I recognize the chip ID in the appropriate register
1303 *
1304 *
1305 */
1306int
1307sn_probe(device_t dev, int pccard)
1308{
1309 struct sn_softc *sc = device_get_softc(dev);
1310 u_int bank;
1311 u_short revision_register;
1312 u_short base_address_register;
1313 u_short ioaddr;
1314 int err;
1315
1316 if ((err = sn_activate(dev)) != 0)
1317 return err;
1318
1319 ioaddr = sc->sn_io_addr;
1320
1321 /*
1322 * First, see if the high byte is 0x33
1323 */
1324 bank = inw(ioaddr + BANK_SELECT_REG_W);
1325 if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
1326#ifdef SN_DEBUG
1327 device_printf(dev, "test1 failed\n");
1328#endif
1329 goto error;
1330 }
1331 /*
1332 * The above MIGHT indicate a device, but I need to write to further
1333 * test this. Go to bank 0, then test that the register still
1334 * reports the high byte is 0x33.
1335 */
1336 outw(ioaddr + BANK_SELECT_REG_W, 0x0000);
1337 bank = inw(ioaddr + BANK_SELECT_REG_W);
1338 if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
1339#ifdef SN_DEBUG
1340 device_printf(dev, "test2 failed\n");
1341#endif
1342 goto error;
1343 }
1344 /*
1345 * well, we've already written once, so hopefully another time won't
1346 * hurt. This time, I need to switch the bank register to bank 1, so
1347 * I can access the base address register. The contents of the
1348 * BASE_ADDR_REG_W register, after some jiggery pokery, is expected
1349 * to match the I/O port address where the adapter is being probed.
1350 */
1351 outw(ioaddr + BANK_SELECT_REG_W, 0x0001);
1352 base_address_register = inw(ioaddr + BASE_ADDR_REG_W);
1353
1354 /*
1355 * This test is nonsence on PC-card architecture, so if
1356 * pccard == 1, skip this test. (hosokawa)
1357 */
1358 if (!pccard && (ioaddr != (base_address_register >> 3 & 0x3E0))) {
1359
1360 /*
1361 * Well, the base address register didn't match. Must not
1362 * have been a SMC chip after all.
1363 */
1364 /*
1365 * printf("sn: ioaddr %x doesn't match card configuration
1366 * (%x)\n", ioaddr, base_address_register >> 3 & 0x3E0 );
1367 */
1368
1369#ifdef SN_DEBUG
1370 device_printf(dev, "test3 failed ioaddr = 0x%x, "
1371 "base_address_register = 0x%x\n", ioaddr,
1372 base_address_register >> 3 & 0x3E0);
1373#endif
1374 goto error;
1375 }
1376 /*
1377 * Check if the revision register is something that I recognize.
1378 * These might need to be added to later, as future revisions could
1379 * be added.
1380 */
1381 outw(ioaddr + BANK_SELECT_REG_W, 0x3);
1382 revision_register = inw(ioaddr + REVISION_REG_W);
1383 if (!chip_ids[(revision_register >> 4) & 0xF]) {
1384
1385 /*
1386 * I don't regonize this chip, so...
1387 */
1388#ifdef SN_DEBUG
1389 device_printf(dev, "test4 failed\n");
1390#endif
1391 goto error;
1392 }
1393 /*
1394 * at this point I'll assume that the chip is an SMC9xxx. It might be
1395 * prudent to check a listing of MAC addresses against the hardware
1396 * address, or do some other tests.
1397 */
1398 sn_deactivate(dev);
1399 return 0;
1400 error:
1401 sn_deactivate(dev);
1402 return ENXIO;
1403}
1404
1405#define MCFSZ 8
1406
1407static void
1408sn_setmcast(struct sn_softc *sc)
1409{
1410 struct ifnet *ifp = (struct ifnet *)sc;
1411 int flags;
1412
1413 /*
1414 * Set the receiver filter. We want receive enabled and auto strip
1415 * of CRC from received packet. If we are promiscuous then set that
1416 * bit too.
1417 */
1418 flags = RCR_ENABLE | RCR_STRIP_CRC;
1419
1420 if (ifp->if_flags & IFF_PROMISC) {
1421 flags |= RCR_PROMISC | RCR_ALMUL;
1422 } else if (ifp->if_flags & IFF_ALLMULTI) {
1423 flags |= RCR_ALMUL;
1424 } else {
1425 u_char mcf[MCFSZ];
1426 if (sn_getmcf(&sc->arpcom, mcf)) {
1427 /* set filter */
1428 SMC_SELECT_BANK(3);
1429 outw(BASE + MULTICAST1_REG_W,
1430 ((u_short)mcf[1] << 8) | mcf[0]);
1431 outw(BASE + MULTICAST2_REG_W,
1432 ((u_short)mcf[3] << 8) | mcf[2]);
1433 outw(BASE + MULTICAST3_REG_W,
1434 ((u_short)mcf[5] << 8) | mcf[4]);
1435 outw(BASE + MULTICAST4_REG_W,
1436 ((u_short)mcf[7] << 8) | mcf[6]);
1437 } else {
1438 flags |= RCR_ALMUL;
1439 }
1440 }
1441 SMC_SELECT_BANK(0);
1442 outw(BASE + RECV_CONTROL_REG_W, flags);
1443}
1444
1445static int
1446sn_getmcf(struct arpcom *ac, u_char *mcf)
1447{
1448 int i;
1449 register u_int index, index2;
1450 register u_char *af = (u_char *) mcf;
1451 struct ifmultiaddr *ifma;
1452
1453 bzero(mcf, MCFSZ);
1454
1455 for (ifma = ac->ac_if.if_multiaddrs.lh_first; ifma;
1456 ifma = ifma->ifma_link.le_next) {
1457 if (ifma->ifma_addr->sa_family != AF_LINK)
1458 return 0;
1459 index = smc_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)) & 0x3f;
1460 index2 = 0;
1461 for (i = 0; i < 6; i++) {
1462 index2 <<= 1;
1463 index2 |= (index & 0x01);
1464 index >>= 1;
1465 }
1466 af[index2 >> 3] |= 1 << (index2 & 7);
1467 }
1468 return 1; /* use multicast filter */
1469}
1470
1471static u_int
1472smc_crc(u_char *s)
1473{
1474 int perByte;
1475 int perBit;
1476 const u_int poly = 0xedb88320;
1477 u_int v = 0xffffffff;
1478 u_char c;
1479
1480 for (perByte = 0; perByte < ETHER_ADDR_LEN; perByte++) {
1481 c = s[perByte];
1482 for (perBit = 0; perBit < 8; perBit++) {
1483 v = (v >> 1)^(((v ^ c) & 0x01) ? poly : 0);
1484 c >>= 1;
1485 }
1486 }
1487 return v;
1488}