1/* $NetBSD: smc91cxx.c,v 1.93 2016/07/07 06:55:41 msaitoh Exp $ */
2
3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com>
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by Gardner Buchanan.
48 * 4. The name of Gardner Buchanan may not be used to endorse or promote
49 * products derived from this software without specific prior written
50 * permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 *
63 * from FreeBSD Id: if_sn.c,v 1.4 1996/03/18 15:47:16 gardner Exp
64 */
65
66/*
67 * Core driver for the SMC 91Cxx family of Ethernet chips.
68 *
69 * Memory allocation interrupt logic is drived from an SMC 91C90 driver
70 * written for NetBSD/amiga by Michael Hitch.
71 */
72
73#include <sys/cdefs.h>
74__KERNEL_RCSID(0, "$NetBSD: smc91cxx.c,v 1.93 2016/07/07 06:55:41 msaitoh Exp $");
75
76#include "opt_inet.h"
77
78#include <sys/param.h>
79#include <sys/systm.h>
80#include <sys/mbuf.h>
81#include <sys/syslog.h>
82#include <sys/socket.h>
83#include <sys/device.h>
84#include <sys/kernel.h>
85#include <sys/malloc.h>
86#include <sys/ioctl.h>
87#include <sys/errno.h>
88#include <sys/rndsource.h>
89
90#include <sys/bus.h>
91#include <sys/intr.h>
92
93#include <net/if.h>
94#include <net/if_dl.h>
95#include <net/if_ether.h>
96#include <net/if_media.h>
97
98#ifdef INET
99#include <netinet/in.h>
100#include <netinet/if_inarp.h>
101#include <netinet/in_systm.h>
102#include <netinet/in_var.h>
103#include <netinet/ip.h>
104#endif
105
106#include <net/bpf.h>
107#include <net/bpfdesc.h>
108
109#include <dev/mii/mii.h>
110#include <dev/mii/miivar.h>
111#include <dev/mii/mii_bitbang.h>
112
113#include <dev/ic/smc91cxxreg.h>
114#include <dev/ic/smc91cxxvar.h>
115
116#ifndef __BUS_SPACE_HAS_STREAM_METHODS
117#define bus_space_write_multi_stream_2 bus_space_write_multi_2
118#define bus_space_write_multi_stream_4 bus_space_write_multi_4
119#define bus_space_read_multi_stream_2 bus_space_read_multi_2
120#define bus_space_read_multi_stream_4 bus_space_read_multi_4
121
122#define bus_space_write_stream_4 bus_space_write_4
123#define bus_space_read_stream_4 bus_space_read_4
124#endif /* __BUS_SPACE_HAS_STREAM_METHODS */
125
126/* XXX Hardware padding doesn't work yet(?) */
127#define SMC91CXX_SW_PAD
128
129const char *smc91cxx_idstrs[] = {
130 NULL, /* 0 */
131 NULL, /* 1 */
132 NULL, /* 2 */
133 "SMC91C90/91C92", /* 3 */
134 "SMC91C94/91C96", /* 4 */
135 "SMC91C95", /* 5 */
136 NULL, /* 6 */
137 "SMC91C100", /* 7 */
138 "SMC91C100FD", /* 8 */
139 "SMC91C111", /* 9 */
140 NULL, /* 10 */
141 NULL, /* 11 */
142 NULL, /* 12 */
143 NULL, /* 13 */
144 NULL, /* 14 */
145 NULL, /* 15 */
146};
147
148/* Supported media types. */
149static const int smc91cxx_media[] = {
150 IFM_ETHER|IFM_10_T,
151 IFM_ETHER|IFM_10_5,
152};
153#define NSMC91CxxMEDIA (sizeof(smc91cxx_media) / sizeof(smc91cxx_media[0]))
154
155/*
156 * MII bit-bang glue.
157 */
158u_int32_t smc91cxx_mii_bitbang_read(device_t);
159void smc91cxx_mii_bitbang_write(device_t, u_int32_t);
160
161static const struct mii_bitbang_ops smc91cxx_mii_bitbang_ops = {
162 smc91cxx_mii_bitbang_read,
163 smc91cxx_mii_bitbang_write,
164 {
165 MR_MDO, /* MII_BIT_MDO */
166 MR_MDI, /* MII_BIT_MDI */
167 MR_MCLK, /* MII_BIT_MDC */
168 MR_MDOE, /* MII_BIT_DIR_HOST_PHY */
169 0, /* MII_BIT_DIR_PHY_HOST */
170 }
171};
172
173/* MII callbacks */
174int smc91cxx_mii_readreg(device_t, int, int);
175void smc91cxx_mii_writereg(device_t, int, int, int);
176void smc91cxx_statchg(struct ifnet *);
177void smc91cxx_tick(void *);
178
179int smc91cxx_mediachange(struct ifnet *);
180void smc91cxx_mediastatus(struct ifnet *, struct ifmediareq *);
181
182int smc91cxx_set_media(struct smc91cxx_softc *, int);
183
184void smc91cxx_init(struct smc91cxx_softc *);
185void smc91cxx_read(struct smc91cxx_softc *);
186void smc91cxx_reset(struct smc91cxx_softc *);
187void smc91cxx_start(struct ifnet *);
188uint8_t smc91cxx_copy_tx_frame(struct smc91cxx_softc *, struct mbuf *);
189void smc91cxx_resume(struct smc91cxx_softc *);
190void smc91cxx_stop(struct smc91cxx_softc *);
191void smc91cxx_watchdog(struct ifnet *);
192int smc91cxx_ioctl(struct ifnet *, u_long, void *);
193
194static inline int ether_cmp(const void *, const void *);
195static inline int
196ether_cmp(const void *va, const void *vb)
197{
198 const u_int8_t *a = va;
199 const u_int8_t *b = vb;
200
201 return ((a[5] != b[5]) || (a[4] != b[4]) || (a[3] != b[3]) ||
202 (a[2] != b[2]) || (a[1] != b[1]) || (a[0] != b[0]));
203}
204
205static inline void
206smc91cxx_intr_mask_write(bus_space_tag_t bst, bus_space_handle_t bsh,
207 uint8_t mask)
208{
209 KDASSERT((mask & IM_ERCV_INT) == 0);
210#ifdef SMC91CXX_NO_BYTE_WRITE
211 bus_space_write_2(bst, bsh, INTR_STAT_REG_B, mask << 8);
212#else
213 bus_space_write_1(bst, bsh, INTR_MASK_REG_B, mask);
214#endif
215 KDASSERT(!(bus_space_read_1(bst, bsh, INTR_MASK_REG_B) & IM_ERCV_INT));
216}
217
218static inline void
219smc91cxx_intr_ack_write(bus_space_tag_t bst, bus_space_handle_t bsh,
220 uint8_t ack, uint8_t mask)
221{
222#ifdef SMC91CXX_NO_BYTE_WRITE
223 bus_space_write_2(bst, bsh, INTR_ACK_REG_B, ack | (mask << 8));
224#else
225 bus_space_write_1(bst, bsh, INTR_ACK_REG_B, ack);
226#endif
227 KDASSERT(!(bus_space_read_1(bst, bsh, INTR_MASK_REG_B) & IM_ERCV_INT));
228}
229
230void
231smc91cxx_attach(struct smc91cxx_softc *sc, u_int8_t *myea)
232{
233 struct ifnet *ifp = &sc->sc_ec.ec_if;
234 bus_space_tag_t bst = sc->sc_bst;
235 bus_space_handle_t bsh = sc->sc_bsh;
236 struct ifmedia *ifm = &sc->sc_mii.mii_media;
237 const char *idstr;
238 u_int32_t miicapabilities;
239 u_int16_t tmp;
240 u_int8_t enaddr[ETHER_ADDR_LEN];
241 int i, aui, mult, scale, memsize;
242 char pbuf[9];
243
244 tmp = bus_space_read_2(bst, bsh, BANK_SELECT_REG_W);
245 /* check magic number */
246 if ((tmp & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
247 aprint_error_dev(sc->sc_dev,
248 "failed to detect chip, bsr=%04x\n", tmp);
249 return;
250 }
251
252 /* Make sure the chip is stopped. */
253 smc91cxx_stop(sc);
254
255 SMC_SELECT_BANK(sc, 3);
256 tmp = bus_space_read_2(bst, bsh, REVISION_REG_W);
257 sc->sc_chipid = RR_ID(tmp);
258 idstr = smc91cxx_idstrs[sc->sc_chipid];
259
260 aprint_normal_dev(sc->sc_dev, "");
261 if (idstr != NULL)
262 aprint_normal("%s, ", idstr);
263 else
264 aprint_normal("unknown chip id %d, ", sc->sc_chipid);
265 aprint_normal("revision %d, ", RR_REV(tmp));
266
267 SMC_SELECT_BANK(sc, 0);
268 switch (sc->sc_chipid) {
269 default:
270 mult = MCR_MEM_MULT(bus_space_read_2(bst, bsh, MEM_CFG_REG_W));
271 scale = MIR_SCALE_91C9x;
272 break;
273
274 case CHIP_91C111:
275 mult = MIR_MULT_91C111;
276 scale = MIR_SCALE_91C111;
277 }
278 memsize = bus_space_read_2(bst, bsh, MEM_INFO_REG_W) & MIR_TOTAL_MASK;
279 if (memsize == 255)
280 memsize++;
281 memsize *= scale * mult;
282
283 format_bytes(pbuf, sizeof(pbuf), memsize);
284 aprint_normal("buffer size: %s\n", pbuf);
285
286 /* Read the station address from the chip. */
287 SMC_SELECT_BANK(sc, 1);
288 if (myea == NULL) {
289 myea = enaddr;
290 for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
291 tmp = bus_space_read_2(bst, bsh, IAR_ADDR0_REG_W + i);
292 myea[i + 1] = (tmp >> 8) & 0xff;
293 myea[i] = tmp & 0xff;
294 }
295 }
296 aprint_normal_dev(sc->sc_dev, "MAC address %s, ",
297 ether_sprintf(myea));
298
299 /* Initialize the ifnet structure. */
300 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
301 ifp->if_softc = sc;
302 ifp->if_start = smc91cxx_start;
303 ifp->if_ioctl = smc91cxx_ioctl;
304 ifp->if_watchdog = smc91cxx_watchdog;
305 ifp->if_flags =
306 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
307 IFQ_SET_READY(&ifp->if_snd);
308
309 /* Attach the interface. */
310 if_attach(ifp);
311 ether_ifattach(ifp, myea);
312
313 /*
314 * Initialize our media structures and MII info. We will
315 * probe the MII if we are on the SMC91Cxx
316 */
317 sc->sc_mii.mii_ifp = ifp;
318 sc->sc_mii.mii_readreg = smc91cxx_mii_readreg;
319 sc->sc_mii.mii_writereg = smc91cxx_mii_writereg;
320 sc->sc_mii.mii_statchg = smc91cxx_statchg;
321 ifmedia_init(ifm, IFM_IMASK, smc91cxx_mediachange,
322 smc91cxx_mediastatus);
323
324 SMC_SELECT_BANK(sc, 1);
325 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
326
327 miicapabilities = BMSR_MEDIAMASK|BMSR_ANEG;
328 switch (sc->sc_chipid) {
329 case CHIP_91100:
330 /*
331 * The 91100 does not have full-duplex capabilities,
332 * even if the PHY does.
333 */
334 miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX);
335 /*FALLTHROUGH*/
336 case CHIP_91100FD:
337 case CHIP_91C111:
338 if (tmp & CR_MII_SELECT) {
339 aprint_normal("default media MII");
340 if (sc->sc_chipid == CHIP_91C111) {
341 aprint_normal(" (%s PHY)\n",
342 (tmp & CR_AUI_SELECT) ?
343 "external" : "internal");
344 sc->sc_internal_phy = !(tmp & CR_AUI_SELECT);
345 } else
346 aprint_normal("\n");
347 mii_attach(sc->sc_dev, &sc->sc_mii, miicapabilities,
348 MII_PHY_ANY, MII_OFFSET_ANY, 0);
349 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
350 ifmedia_add(&sc->sc_mii.mii_media,
351 IFM_ETHER|IFM_NONE, 0, NULL);
352 ifmedia_set(&sc->sc_mii.mii_media,
353 IFM_ETHER|IFM_NONE);
354 } else {
355 ifmedia_set(&sc->sc_mii.mii_media,
356 IFM_ETHER|IFM_AUTO);
357 }
358 sc->sc_flags |= SMC_FLAGS_HAS_MII;
359 break;
360 } else
361 if (sc->sc_chipid == CHIP_91C111) {
362 /*
363 * XXX: Should bring it out of low-power mode
364 */
365 aprint_normal("EPH interface in low power mode\n");
366 sc->sc_internal_phy = 0;
367 return;
368 }
369 /*FALLTHROUGH*/
370 default:
371 aprint_normal("default media %s\n",
372 (aui = (tmp & CR_AUI_SELECT)) ?
373 "AUI" : "UTP");
374 for (i = 0; i < NSMC91CxxMEDIA; i++)
375 ifmedia_add(ifm, smc91cxx_media[i], 0, NULL);
376 ifmedia_set(ifm, IFM_ETHER | (aui ? IFM_10_5 : IFM_10_T));
377 break;
378 }
379
380 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
381 RND_TYPE_NET, RND_FLAG_DEFAULT);
382
383 callout_init(&sc->sc_mii_callout, 0);
384
385 /* The attach is successful. */
386 sc->sc_flags |= SMC_FLAGS_ATTACHED;
387}
388
389/*
390 * Change media according to request.
391 */
392int
393smc91cxx_mediachange(struct ifnet *ifp)
394{
395 struct smc91cxx_softc *sc = ifp->if_softc;
396
397 return (smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_media));
398}
399
400int
401smc91cxx_set_media(struct smc91cxx_softc *sc, int media)
402{
403 bus_space_tag_t bst = sc->sc_bst;
404 bus_space_handle_t bsh = sc->sc_bsh;
405 u_int16_t tmp;
406 int rc;
407
408 /*
409 * If the interface is not currently powered on, just return.
410 * When it is enabled later, smc91cxx_init() will properly set
411 * up the media for us.
412 */
413 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0)
414 return (0);
415
416 if (IFM_TYPE(media) != IFM_ETHER)
417 return (EINVAL);
418
419 if ((sc->sc_flags & SMC_FLAGS_HAS_MII) == 0 ||
420 (rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
421 rc = 0;
422
423 switch (IFM_SUBTYPE(media)) {
424 case IFM_10_T:
425 case IFM_10_5:
426 SMC_SELECT_BANK(sc, 1);
427 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
428 if (IFM_SUBTYPE(media) == IFM_10_5)
429 tmp |= CR_AUI_SELECT;
430 else
431 tmp &= ~CR_AUI_SELECT;
432 bus_space_write_2(bst, bsh, CONFIG_REG_W, tmp);
433 delay(20000); /* XXX is this needed? */
434 break;
435
436 default:
437 return (EINVAL);
438 }
439
440 return rc;
441}
442
443/*
444 * Notify the world which media we're using.
445 */
446void
447smc91cxx_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
448{
449 struct smc91cxx_softc *sc = ifp->if_softc;
450 bus_space_tag_t bst = sc->sc_bst;
451 bus_space_handle_t bsh = sc->sc_bsh;
452 u_int16_t tmp;
453
454 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) {
455 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
456 ifmr->ifm_status = 0;
457 return;
458 }
459
460 /*
461 * If we have MII, go ask the PHY what's going on.
462 */
463 if (sc->sc_flags & SMC_FLAGS_HAS_MII) {
464 mii_pollstat(&sc->sc_mii);
465 ifmr->ifm_active = sc->sc_mii.mii_media_active;
466 ifmr->ifm_status = sc->sc_mii.mii_media_status;
467 return;
468 }
469
470 SMC_SELECT_BANK(sc, 1);
471 tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W);
472 ifmr->ifm_active =
473 IFM_ETHER | ((tmp & CR_AUI_SELECT) ? IFM_10_5 : IFM_10_T);
474}
475
476/*
477 * Reset and initialize the chip.
478 */
479void
480smc91cxx_init(struct smc91cxx_softc *sc)
481{
482 struct ifnet *ifp = &sc->sc_ec.ec_if;
483 bus_space_tag_t bst = sc->sc_bst;
484 bus_space_handle_t bsh = sc->sc_bsh;
485 u_int16_t tmp;
486 const u_int8_t *enaddr;
487 int s, i;
488
489 s = splnet();
490
491 /*
492 * This resets the registers mostly to defaults, but doesn't
493 * affect the EEPROM. The longest reset recovery time of those devices
494 * supported is the 91C111. Section 7.8 of its datasheet asks for 50ms.
495 */
496 SMC_SELECT_BANK(sc, 0);
497 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, RCR_SOFTRESET);
498 delay(5);
499 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0);
500 delay(50000);
501
502 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0);
503
504 /* Set the Ethernet address. */
505 SMC_SELECT_BANK(sc, 1);
506 enaddr = (const u_int8_t *)CLLADDR(ifp->if_sadl);
507 for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
508 tmp = enaddr[i + 1] << 8 | enaddr[i];
509 bus_space_write_2(bst, bsh, IAR_ADDR0_REG_W + i, tmp);
510 }
511
512 /*
513 * Set the control register to automatically release successfully
514 * transmitted packets (making the best use of our limited memory)
515 * and enable the EPH interrupt on certain TX errors.
516 */
517 bus_space_write_2(bst, bsh, CONTROL_REG_W, (CTR_AUTO_RELEASE |
518 CTR_TE_ENABLE | CTR_CR_ENABLE | CTR_LE_ENABLE));
519
520 /*
521 * Reset the MMU and wait for it to be un-busy.
522 */
523 SMC_SELECT_BANK(sc, 2);
524 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RESET);
525 sc->sc_txpacketno = ARR_FAILED;
526 for (;;) {
527 tmp = bus_space_read_2(bst, bsh, MMU_CMD_REG_W);
528 if (tmp == 0xffff) {
529 /* card went away! */
530 splx(s);
531 return;
532 }
533 if ((tmp & MMUCR_BUSY) == 0)
534 break;
535 }
536
537 /*
538 * Disable all interrupts.
539 */
540 smc91cxx_intr_mask_write(bst, bsh, 0);
541
542 /*
543 * On the 91c111, enable auto-negotiation, and set the LED
544 * status pins to something sane.
545 * XXX: Should be some way for MD code to decide the latter.
546 */
547 SMC_SELECT_BANK(sc, 0);
548 if (sc->sc_chipid == CHIP_91C111) {
549 bus_space_write_2(bst, bsh, RX_PHY_CONTROL_REG_W,
550 RPC_ANEG |
551 (RPC_LS_LINK_DETECT << RPC_LSA_SHIFT) |
552 (RPC_LS_TXRX << RPC_LSB_SHIFT));
553 }
554
555 /*
556 * Set current media.
557 */
558 smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_cur->ifm_media);
559
560 /*
561 * Set the receive filter. We want receive enable and auto
562 * strip of CRC from received packet. If we are in promisc. mode,
563 * then set that bit as well.
564 *
565 * XXX Initialize multicast filter. For now, we just accept
566 * XXX all multicast.
567 */
568 SMC_SELECT_BANK(sc, 0);
569
570 tmp = RCR_ENABLE | RCR_STRIP_CRC | RCR_ALMUL;
571 if (ifp->if_flags & IFF_PROMISC)
572 tmp |= RCR_PROMISC;
573
574 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, tmp);
575
576 /*
577 * Set transmitter control to "enabled".
578 */
579 tmp = TCR_ENABLE;
580
581#ifndef SMC91CXX_SW_PAD
582 /*
583 * Enable hardware padding of transmitted packets.
584 * XXX doesn't work?
585 */
586 tmp |= TCR_PAD_ENABLE;
587#endif
588
589 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, tmp);
590
591 /*
592 * Now, enable interrupts.
593 */
594 SMC_SELECT_BANK(sc, 2);
595
596 sc->sc_intmask = IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT;
597 if (sc->sc_chipid == CHIP_91C111 && sc->sc_internal_phy) {
598 sc->sc_intmask |= IM_MD_INT;
599 }
600 smc91cxx_intr_mask_write(bst, bsh, sc->sc_intmask);
601
602 /* Interface is now running, with no output active. */
603 ifp->if_flags |= IFF_RUNNING;
604 ifp->if_flags &= ~IFF_OACTIVE;
605
606 if (sc->sc_flags & SMC_FLAGS_HAS_MII) {
607 /* Start the one second clock. */
608 callout_reset(&sc->sc_mii_callout, hz, smc91cxx_tick, sc);
609 }
610
611 /*
612 * Attempt to start any pending transmission.
613 */
614 smc91cxx_start(ifp);
615
616 splx(s);
617}
618
619/*
620 * Start output on an interface.
621 * Must be called at splnet or interrupt level.
622 */
623void
624smc91cxx_start(struct ifnet *ifp)
625{
626 struct smc91cxx_softc *sc = ifp->if_softc;
627 bus_space_tag_t bst = sc->sc_bst;
628 bus_space_handle_t bsh = sc->sc_bsh;
629 u_int len;
630 struct mbuf *m;
631 u_int16_t length, npages;
632 u_int16_t oddbyte;
633 u_int8_t packetno;
634 int timo, pad;
635
636 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
637 return;
638
639 again:
640 /*
641 * Peek at the next packet.
642 */
643 IFQ_POLL(&ifp->if_snd, m);
644 if (m == NULL)
645 return;
646
647 /*
648 * Compute the frame length and set pad to give an overall even
649 * number of bytes. Below, we assume that the packet length
650 * is even.
651 */
652 for (len = 0; m != NULL; m = m->m_next)
653 len += m->m_len;
654
655 /*
656 * We drop packets that are too large. Perhaps we should
657 * truncate them instead?
658 */
659 if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN)) {
660 printf("%s: large packet discarded\n",
661 device_xname(sc->sc_dev));
662 ifp->if_oerrors++;
663 IFQ_DEQUEUE(&ifp->if_snd, m);
664 m_freem(m);
665 goto readcheck;
666 }
667
668 pad = 0;
669#ifdef SMC91CXX_SW_PAD
670 /*
671 * Not using hardware padding; pad to ETHER_MIN_LEN.
672 */
673 if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN))
674 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
675#endif
676
677 length = pad + len;
678
679 /*
680 * The MMU has a 256 byte page size. The MMU expects us to
681 * ask for "npages - 1". We include space for the status word,
682 * byte count, and control bytes in the allocation request.
683 */
684 npages = ((length & ~1) + 6) >> 8;
685
686 /*
687 * Now allocate the memory.
688 */
689 SMC_SELECT_BANK(sc, 2);
690 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ALLOC | npages);
691
692 timo = MEMORY_WAIT_TIME;
693 if (__predict_false((sc->sc_txpacketno & ARR_FAILED) == 0)) {
694 packetno = sc->sc_txpacketno;
695 sc->sc_txpacketno = ARR_FAILED;
696 } else {
697 do {
698 if (bus_space_read_1(bst, bsh,
699 INTR_STAT_REG_B) & IM_ALLOC_INT)
700 break;
701 delay(1);
702 } while (--timo);
703 }
704
705 packetno = bus_space_read_1(bst, bsh, ALLOC_RESULT_REG_B);
706
707 if (packetno & ARR_FAILED || timo == 0) {
708 /*
709 * No transmit memory is available. Record the number
710 * of requested pages and enable the allocation completion
711 * interrupt. Set up the watchdog timer in case we miss
712 * the interrupt. Mark the interface as active so that
713 * no one else attempts to transmit while we're allocating
714 * memory.
715 */
716 sc->sc_intmask |= IM_ALLOC_INT;
717 smc91cxx_intr_mask_write(bst, bsh, sc->sc_intmask);
718 ifp->if_timer = 5;
719 ifp->if_flags |= IFF_OACTIVE;
720
721 return;
722 }
723
724 /*
725 * We have a packet number - set the data window.
726 */
727 bus_space_write_2(bst, bsh, PACKET_NUM_REG_B, packetno);
728
729 /*
730 * Point to the beginning of the packet.
731 */
732 bus_space_write_2(bst, bsh, POINTER_REG_W, PTR_AUTOINC /* | 0x0000 */);
733
734 /*
735 * Send the packet length (+6 for stats, length, and control bytes)
736 * and the status word (set to zeros).
737 */
738 bus_space_write_2(bst, bsh, DATA_REG_W, 0);
739 bus_space_write_2(bst, bsh, DATA_REG_W, (length + 6) & 0x7ff);
740
741 /*
742 * Get the packet from the kernel. This will include the Ethernet
743 * frame header, MAC address, etc.
744 */
745 IFQ_DEQUEUE(&ifp->if_snd, m);
746
747 /*
748 * Push the packet out to the card. The copying function only does
749 * whole words and returns the straggling byte (if any).
750 */
751 oddbyte = smc91cxx_copy_tx_frame(sc, m);
752
753#ifdef SMC91CXX_SW_PAD
754 if (pad > 1 && (pad & 1)) {
755 bus_space_write_2(bst, bsh, DATA_REG_W, oddbyte);
756 oddbyte = 0;
757 pad -= 1;
758 }
759
760 /*
761 * Push out padding.
762 */
763 while (pad > 1) {
764 bus_space_write_2(bst, bsh, DATA_REG_W, 0);
765 pad -= 2;
766 }
767#endif
768
769 /*
770 * Push out control byte and unused packet byte. The control byte
771 * denotes whether this is an odd or even length packet, and that
772 * no special CRC handling is necessary.
773 */
774 bus_space_write_2(bst, bsh, DATA_REG_W,
775 oddbyte | ((length & 1) ? (CTLB_ODD << 8) : 0));
776
777 /*
778 * Enable transmit interrupts and let the chip go. Set a watchdog
779 * in case we miss the interrupt.
780 */
781 sc->sc_intmask |= IM_TX_INT | IM_TX_EMPTY_INT;
782 smc91cxx_intr_mask_write(bst, bsh, sc->sc_intmask);
783
784 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_ENQUEUE);
785
786 ifp->if_timer = 5;
787
788 /* Hand off a copy to the bpf. */
789 bpf_mtap(ifp, m);
790
791 ifp->if_opackets++;
792 m_freem(m);
793
794 readcheck:
795 /*
796 * Check for incoming packets. We don't want to overflow the small
797 * RX FIFO. If nothing has arrived, attempt to queue another
798 * transmit packet.
799 */
800 if (bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) & FIFO_REMPTY)
801 goto again;
802}
803
804/*
805 * Squirt a (possibly misaligned) mbuf to the device
806 */
807uint8_t
808smc91cxx_copy_tx_frame(struct smc91cxx_softc *sc, struct mbuf *m0)
809{
810 bus_space_tag_t bst = sc->sc_bst;
811 bus_space_handle_t bsh = sc->sc_bsh;
812 struct mbuf *m;
813 int len, leftover;
814 u_int16_t dbuf;
815 u_int8_t *p;
816#ifdef DIAGNOSTIC
817 u_int8_t *lim;
818#endif
819
820 /* start out with no leftover data */
821 leftover = 0;
822 dbuf = 0;
823
824 /* Process the chain of mbufs */
825 for (m = m0; m != NULL; m = m->m_next) {
826 /*
827 * Process all of the data in a single mbuf.
828 */
829 p = mtod(m, u_int8_t *);
830 len = m->m_len;
831#ifdef DIAGNOSTIC
832 lim = p + len;
833#endif
834
835 while (len > 0) {
836 if (leftover) {
837 /*
838 * Data left over (from mbuf or realignment).
839 * Buffer the next byte, and write it and
840 * the leftover data out.
841 */
842 dbuf |= *p++ << 8;
843 len--;
844 bus_space_write_2(bst, bsh, DATA_REG_W, dbuf);
845 leftover = 0;
846 } else if ((long) p & 1) {
847 /*
848 * Misaligned data. Buffer the next byte.
849 */
850 dbuf = *p++;
851 len--;
852 leftover = 1;
853 } else {
854 /*
855 * Aligned data. This is the case we like.
856 *
857 * Write-region out as much as we can, then
858 * buffer the remaining byte (if any).
859 */
860 leftover = len & 1;
861 len &= ~1;
862 bus_space_write_multi_stream_2(bst, bsh,
863 DATA_REG_W, (u_int16_t *)p, len >> 1);
864 p += len;
865
866 if (leftover)
867 dbuf = *p++;
868 len = 0;
869 }
870 }
871 if (len < 0)
872 panic("smc91cxx_copy_tx_frame: negative len");
873#ifdef DIAGNOSTIC
874 if (p != lim)
875 panic("smc91cxx_copy_tx_frame: p != lim");
876#endif
877 }
878
879 return dbuf;
880}
881
882/*
883 * Interrupt service routine.
884 */
885int
886smc91cxx_intr(void *arg)
887{
888 struct smc91cxx_softc *sc = arg;
889 struct ifnet *ifp = &sc->sc_ec.ec_if;
890 bus_space_tag_t bst = sc->sc_bst;
891 bus_space_handle_t bsh = sc->sc_bsh;
892 u_int8_t mask, interrupts, status;
893 u_int16_t packetno, tx_status, card_stats;
894 u_int16_t v;
895
896 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 ||
897 !device_is_active(sc->sc_dev))
898 return (0);
899
900 SMC_SELECT_BANK(sc, 2);
901
902 /*
903 * Obtain the current interrupt status and mask.
904 */
905 v = bus_space_read_2(bst, bsh, INTR_STAT_REG_B);
906
907 /*
908 * Get the set of interrupt which occurred and eliminate any
909 * which are not enabled.
910 */
911 mask = v >> 8;
912 interrupts = v & 0xff;
913 KDASSERT(mask == sc->sc_intmask);
914 status = interrupts & mask;
915
916 /* Ours? */
917 if (status == 0)
918 return (0);
919
920 /*
921 * It's ours; disable all interrupts while we process them.
922 */
923 smc91cxx_intr_mask_write(bst, bsh, 0);
924
925 /*
926 * Receive overrun interrupts.
927 */
928 if (status & IM_RX_OVRN_INT) {
929 smc91cxx_intr_ack_write(bst, bsh, IM_RX_OVRN_INT, 0);
930 ifp->if_ierrors++;
931 }
932
933 /*
934 * Receive interrupts.
935 */
936 if (status & IM_RCV_INT) {
937 smc91cxx_read(sc);
938 }
939
940 /*
941 * Memory allocation interrupts.
942 */
943 if (status & IM_ALLOC_INT) {
944 /* Disable this interrupt. */
945 mask &= ~IM_ALLOC_INT;
946 sc->sc_intmask &= ~IM_ALLOC_INT;
947
948 /*
949 * Save allocated packet number for use in start
950 */
951 packetno = bus_space_read_1(bst, bsh, ALLOC_RESULT_REG_B);
952 KASSERT(sc->sc_txpacketno & ARR_FAILED);
953 sc->sc_txpacketno = packetno;
954
955 /*
956 * We can transmit again!
957 */
958 ifp->if_flags &= ~IFF_OACTIVE;
959 ifp->if_timer = 0;
960 }
961
962 /*
963 * Transmit complete interrupt. Handle transmission error messages.
964 * This will only be called on error condition because of AUTO RELEASE
965 * mode.
966 */
967 if (status & IM_TX_INT) {
968 smc91cxx_intr_ack_write(bst, bsh, IM_TX_INT, 0);
969
970 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W) &
971 FIFO_TX_MASK;
972
973 /*
974 * Select this as the packet to read from.
975 */
976 bus_space_write_2(bst, bsh, PACKET_NUM_REG_B, packetno);
977
978 /*
979 * Position the pointer to the beginning of the packet, wait
980 * for preload.
981 */
982 bus_space_write_2(bst, bsh, POINTER_REG_W,
983 PTR_AUTOINC | PTR_READ /* | 0x0000 */);
984 delay(1);
985
986 /*
987 * Fetch the TX status word. This will be a copy of
988 * the EPH_STATUS_REG_W at the time of the transmission
989 * failure.
990 */
991 tx_status = bus_space_read_2(bst, bsh, DATA_REG_W);
992
993 if (tx_status & EPHSR_TX_SUC) {
994 static struct timeval txsuc_last;
995 static int txsuc_count;
996 if (ppsratecheck(&txsuc_last, &txsuc_count, 1))
997 printf("%s: successful packet caused TX"
998 " interrupt?!\n", device_xname(sc->sc_dev));
999 } else
1000 ifp->if_oerrors++;
1001
1002 if (tx_status & EPHSR_LATCOL)
1003 ifp->if_collisions++;
1004
1005 /* Disable this interrupt (start will reenable if needed). */
1006 mask &= ~IM_TX_INT;
1007 sc->sc_intmask &= ~IM_TX_INT;
1008
1009 /*
1010 * Some of these errors disable the transmitter; reenable it.
1011 */
1012 SMC_SELECT_BANK(sc, 0);
1013#ifdef SMC91CXX_SW_PAD
1014 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, TCR_ENABLE);
1015#else
1016 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W,
1017 TCR_ENABLE | TCR_PAD_ENABLE);
1018#endif
1019
1020 /*
1021 * Kill the failed packet and wait for the MMU to unbusy.
1022 */
1023 SMC_SELECT_BANK(sc, 2);
1024 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
1025 /* XXX bound this loop! */ ;
1026 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_FREEPKT);
1027
1028 ifp->if_timer = 0;
1029 }
1030
1031 /*
1032 * Transmit underrun interrupts. We use this opportunity to
1033 * update transmit statistics from the card.
1034 */
1035 if (status & IM_TX_EMPTY_INT) {
1036 smc91cxx_intr_ack_write(bst, bsh, IM_TX_EMPTY_INT, 0);
1037
1038 /* Disable this interrupt. */
1039 mask &= ~IM_TX_EMPTY_INT;
1040 sc->sc_intmask &= ~IM_TX_EMPTY_INT;
1041
1042 SMC_SELECT_BANK(sc, 0);
1043 card_stats = bus_space_read_2(bst, bsh, COUNTER_REG_W);
1044
1045 /* Single collisions. */
1046 ifp->if_collisions += card_stats & ECR_COLN_MASK;
1047
1048 /* Multiple collisions. */
1049 ifp->if_collisions += (card_stats & ECR_MCOLN_MASK) >> 4;
1050
1051 SMC_SELECT_BANK(sc, 2);
1052
1053 ifp->if_timer = 0;
1054 }
1055
1056 /*
1057 * Internal PHY status change
1058 */
1059 if (sc->sc_chipid == CHIP_91C111 && sc->sc_internal_phy &&
1060 (status & IM_MD_INT)) {
1061
1062 /*
1063 * Internal PHY status change
1064 */
1065 smc91cxx_intr_ack_write(bst, bsh, IM_MD_INT, 0);
1066 mii_pollstat(&sc->sc_mii);
1067 }
1068
1069 /*
1070 * Other errors. Reset the interface.
1071 */
1072 if (status & IM_EPH_INT) {
1073 smc91cxx_stop(sc);
1074 smc91cxx_init(sc);
1075 }
1076
1077 /*
1078 * Attempt to queue more packets for transmission.
1079 */
1080 smc91cxx_start(ifp);
1081
1082 /*
1083 * Reenable the interrupts we wish to receive now that processing
1084 * is complete.
1085 */
1086 mask |= sc->sc_intmask;
1087 smc91cxx_intr_mask_write(bst, bsh, mask);
1088
1089 if (status)
1090 rnd_add_uint32(&sc->rnd_source, status);
1091
1092 return (1);
1093}
1094
1095/*
1096 * Read a packet from the card and pass it up to the kernel.
1097 * NOTE! WE EXPECT TO BE IN REGISTER WINDOW 2!
1098 */
1099void
1100smc91cxx_read(struct smc91cxx_softc *sc)
1101{
1102 struct ifnet *ifp = &sc->sc_ec.ec_if;
1103 bus_space_tag_t bst = sc->sc_bst;
1104 bus_space_handle_t bsh = sc->sc_bsh;
1105 struct ether_header *eh;
1106 struct mbuf *m;
1107 u_int16_t status, packetno, packetlen;
1108 u_int8_t *data;
1109 u_int32_t dr;
1110 bool first = true;
1111
1112 again:
1113 /*
1114 * Set data pointer to the beginning of the packet. Since
1115 * PTR_RCV is set, the packet number will be found automatically
1116 * in FIFO_PORTS_REG_W, FIFO_RX_MASK.
1117 */
1118 packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W);
1119 if (packetno & FIFO_REMPTY) {
1120 if (first) {
1121 aprint_error_dev(sc->sc_dev,
1122 "receive interrupt on empty fifo\n");
1123 }
1124 return;
1125 }
1126 first = false;
1127
1128 bus_space_write_2(bst, bsh, POINTER_REG_W,
1129 PTR_READ | PTR_RCV | PTR_AUTOINC /* | 0x0000 */);
1130 delay(1);
1131
1132 /*
1133 * First two words are status and packet length.
1134 */
1135 dr = bus_space_read_4(bst, bsh, DATA_REG_W);
1136 status = (u_int16_t)dr;
1137 packetlen = (u_int16_t)(dr >> 16);
1138
1139 packetlen &= RLEN_MASK;
1140 if (packetlen < ETHER_MIN_LEN - ETHER_CRC_LEN + 6 || packetlen > 1534) {
1141 ifp->if_ierrors++;
1142 goto out;
1143 }
1144
1145 /*
1146 * The packet length includes 3 extra words: status, length,
1147 * and an extra word that includes the control byte.
1148 */
1149 packetlen -= 6;
1150
1151 /*
1152 * Account for receive errors and discard.
1153 */
1154 if (status & RS_ERRORS) {
1155 ifp->if_ierrors++;
1156 goto out;
1157 }
1158
1159 /*
1160 * Adjust for odd-length packet.
1161 */
1162 if (status & RS_ODDFRAME)
1163 packetlen++;
1164
1165 /*
1166 * Allocate a header mbuf.
1167 */
1168 MGETHDR(m, M_DONTWAIT, MT_DATA);
1169 if (m == NULL)
1170 goto out;
1171 m_set_rcvif(m, ifp);
1172 m->m_pkthdr.len = packetlen;
1173
1174 /*
1175 * Always put the packet in a cluster.
1176 * XXX should chain small mbufs if less than threshold.
1177 */
1178 MCLGET(m, M_DONTWAIT);
1179 if ((m->m_flags & M_EXT) == 0) {
1180 m_freem(m);
1181 ifp->if_ierrors++;
1182 aprint_error_dev(sc->sc_dev,
1183 "can't allocate cluster for incoming packet\n");
1184 goto out;
1185 }
1186
1187 /*
1188 * Pull the packet off the interface. Make sure the payload
1189 * is aligned.
1190 */
1191 if ((sc->sc_flags & SMC_FLAGS_32BIT_READ) == 0) {
1192 m->m_data = (char *) ALIGN(mtod(m, char *) +
1193 sizeof(struct ether_header)) - sizeof(struct ether_header);
1194
1195 eh = mtod(m, struct ether_header *);
1196 data = mtod(m, u_int8_t *);
1197 KASSERT(trunc_page((uintptr_t)data) ==
1198 trunc_page((uintptr_t)data + packetlen - 1));
1199 if (packetlen > 1)
1200 bus_space_read_multi_stream_2(bst, bsh, DATA_REG_W,
1201 (u_int16_t *)data, packetlen >> 1);
1202 if (packetlen & 1) {
1203 data += packetlen & ~1;
1204 *data = bus_space_read_1(bst, bsh, DATA_REG_B);
1205 }
1206 } else {
1207 m->m_data = (void *) ALIGN(mtod(m, void *));
1208 eh = mtod(m, struct ether_header *);
1209 data = mtod(m, u_int8_t *);
1210 KASSERT(trunc_page((uintptr_t)data) ==
1211 trunc_page((uintptr_t)data + packetlen - 1));
1212 if (packetlen > 3)
1213 bus_space_read_multi_stream_4(bst, bsh, DATA_REG_W,
1214 (u_int32_t *)data, packetlen >> 2);
1215 if (packetlen & 3) {
1216 data += packetlen & ~3;
1217 *((u_int32_t *)data) =
1218 bus_space_read_stream_4(bst, bsh, DATA_REG_W);
1219 }
1220 }
1221
1222 ifp->if_ipackets++;
1223
1224 /*
1225 * Make sure to behave as IFF_SIMPLEX in all cases.
1226 * This is to cope with SMC91C92 (Megahertz XJ10BT), which
1227 * loops back packets to itself on promiscuous mode.
1228 * (should be ensured by chipset configuration)
1229 */
1230 if ((ifp->if_flags & IFF_PROMISC) != 0) {
1231 /*
1232 * Drop packet looped back from myself.
1233 */
1234 if (ether_cmp(eh->ether_shost, CLLADDR(ifp->if_sadl)) == 0) {
1235 m_freem(m);
1236 goto out;
1237 }
1238 }
1239
1240 m->m_pkthdr.len = m->m_len = packetlen;
1241
1242 /*
1243 * Hand the packet off to bpf listeners.
1244 */
1245 bpf_mtap(ifp, m);
1246
1247 if_percpuq_enqueue(ifp->if_percpuq, m);
1248
1249 out:
1250 /*
1251 * Tell the card to free the memory occupied by this packet.
1252 */
1253 while (bus_space_read_2(bst, bsh, MMU_CMD_REG_W) & MMUCR_BUSY)
1254 /* XXX bound this loop! */ ;
1255 bus_space_write_2(bst, bsh, MMU_CMD_REG_W, MMUCR_RELEASE);
1256
1257 /*
1258 * Check for another packet.
1259 */
1260 goto again;
1261}
1262
1263/*
1264 * Process an ioctl request.
1265 */
1266int
1267smc91cxx_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1268{
1269 struct smc91cxx_softc *sc = ifp->if_softc;
1270 struct ifaddr *ifa = (struct ifaddr *)data;
1271 struct ifreq *ifr = (struct ifreq *)data;
1272 int s, error = 0;
1273
1274 s = splnet();
1275
1276 switch (cmd) {
1277 case SIOCINITIFADDR:
1278 if ((error = smc91cxx_enable(sc)) != 0)
1279 break;
1280 ifp->if_flags |= IFF_UP;
1281 smc91cxx_init(sc);
1282 switch (ifa->ifa_addr->sa_family) {
1283#ifdef INET
1284 case AF_INET:
1285 arp_ifinit(ifp, ifa);
1286 break;
1287#endif
1288 default:
1289 break;
1290 }
1291 break;
1292
1293
1294 case SIOCSIFFLAGS:
1295 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1296 break;
1297 /* XXX re-use ether_ioctl() */
1298 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
1299 case IFF_RUNNING:
1300 /*
1301 * If interface is marked down and it is running,
1302 * stop it.
1303 */
1304 smc91cxx_stop(sc);
1305 ifp->if_flags &= ~IFF_RUNNING;
1306 smc91cxx_disable(sc);
1307 break;
1308 case IFF_UP:
1309 /*
1310 * If interface is marked up and it is stopped,
1311 * start it.
1312 */
1313 if ((error = smc91cxx_enable(sc)) != 0)
1314 break;
1315 smc91cxx_init(sc);
1316 break;
1317 case IFF_UP|IFF_RUNNING:
1318 /*
1319 * Reset the interface to pick up changes in any
1320 * other flags that affect hardware registers.
1321 */
1322 smc91cxx_reset(sc);
1323 break;
1324 case 0:
1325 break;
1326 }
1327 break;
1328
1329 case SIOCADDMULTI:
1330 case SIOCDELMULTI:
1331 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) {
1332 error = EIO;
1333 break;
1334 }
1335
1336 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
1337 /*
1338 * Multicast list has changed; set the hardware
1339 * filter accordingly.
1340 */
1341 if (ifp->if_flags & IFF_RUNNING)
1342 smc91cxx_reset(sc);
1343 error = 0;
1344 }
1345 break;
1346
1347 case SIOCGIFMEDIA:
1348 case SIOCSIFMEDIA:
1349 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1350 break;
1351
1352 default:
1353 error = ether_ioctl(ifp, cmd, data);
1354 break;
1355 }
1356
1357 splx(s);
1358 return (error);
1359}
1360
1361/*
1362 * Reset the interface.
1363 */
1364void
1365smc91cxx_reset(struct smc91cxx_softc *sc)
1366{
1367 int s;
1368
1369 s = splnet();
1370 smc91cxx_stop(sc);
1371 smc91cxx_init(sc);
1372 splx(s);
1373}
1374
1375/*
1376 * Watchdog timer.
1377 */
1378void
1379smc91cxx_watchdog(struct ifnet *ifp)
1380{
1381 struct smc91cxx_softc *sc = ifp->if_softc;
1382
1383 log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev));
1384 ifp->if_oerrors++;
1385 smc91cxx_reset(sc);
1386}
1387
1388/*
1389 * Stop output on the interface.
1390 */
1391void
1392smc91cxx_stop(struct smc91cxx_softc *sc)
1393{
1394 bus_space_tag_t bst = sc->sc_bst;
1395 bus_space_handle_t bsh = sc->sc_bsh;
1396
1397 /*
1398 * Clear interrupt mask; disable all interrupts.
1399 */
1400 SMC_SELECT_BANK(sc, 2);
1401 smc91cxx_intr_mask_write(bst, bsh, 0);
1402
1403 /*
1404 * Disable transmitter and receiver.
1405 */
1406 SMC_SELECT_BANK(sc, 0);
1407 bus_space_write_2(bst, bsh, RECV_CONTROL_REG_W, 0);
1408 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, 0);
1409
1410 /*
1411 * Cancel watchdog timer.
1412 */
1413 sc->sc_ec.ec_if.if_timer = 0;
1414}
1415
1416/*
1417 * Enable power on the interface.
1418 */
1419int
1420smc91cxx_enable(struct smc91cxx_softc *sc)
1421{
1422
1423 if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 && sc->sc_enable != NULL) {
1424 if ((*sc->sc_enable)(sc) != 0) {
1425 aprint_error_dev(sc->sc_dev, "device enable failed\n");
1426 return (EIO);
1427 }
1428 }
1429
1430 sc->sc_flags |= SMC_FLAGS_ENABLED;
1431 return (0);
1432}
1433
1434/*
1435 * Disable power on the interface.
1436 */
1437void
1438smc91cxx_disable(struct smc91cxx_softc *sc)
1439{
1440
1441 if ((sc->sc_flags & SMC_FLAGS_ENABLED) != 0 && sc->sc_disable != NULL) {
1442 (*sc->sc_disable)(sc);
1443 sc->sc_flags &= ~SMC_FLAGS_ENABLED;
1444 }
1445}
1446
1447int
1448smc91cxx_activate(device_t self, enum devact act)
1449{
1450 struct smc91cxx_softc *sc = device_private(self);
1451
1452 switch (act) {
1453 case DVACT_DEACTIVATE:
1454 if_deactivate(&sc->sc_ec.ec_if);
1455 return 0;
1456 default:
1457 return EOPNOTSUPP;
1458 }
1459}
1460
1461int
1462smc91cxx_detach(device_t self, int flags)
1463{
1464 struct smc91cxx_softc *sc = device_private(self);
1465 struct ifnet *ifp = &sc->sc_ec.ec_if;
1466
1467 /* Succeed now if there's no work to do. */
1468 if ((sc->sc_flags & SMC_FLAGS_ATTACHED) == 0)
1469 return (0);
1470
1471 /* smc91cxx_disable() checks SMC_FLAGS_ENABLED */
1472 smc91cxx_disable(sc);
1473
1474 /* smc91cxx_attach() never fails */
1475
1476 /* Delete all media. */
1477 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
1478
1479 rnd_detach_source(&sc->rnd_source);
1480
1481 ether_ifdetach(ifp);
1482 if_detach(ifp);
1483
1484 return (0);
1485}
1486
1487u_int32_t
1488smc91cxx_mii_bitbang_read(device_t self)
1489{
1490 struct smc91cxx_softc *sc = device_private(self);
1491
1492 /* We're already in bank 3. */
1493 return (bus_space_read_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W));
1494}
1495
1496void
1497smc91cxx_mii_bitbang_write(device_t self, u_int32_t val)
1498{
1499 struct smc91cxx_softc *sc = device_private(self);
1500
1501 /* We're already in bank 3. */
1502 bus_space_write_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W, val);
1503}
1504
1505int
1506smc91cxx_mii_readreg(device_t self, int phy, int reg)
1507{
1508 struct smc91cxx_softc *sc = device_private(self);
1509 int val;
1510
1511 SMC_SELECT_BANK(sc, 3);
1512
1513 val = mii_bitbang_readreg(self, &smc91cxx_mii_bitbang_ops, phy, reg);
1514
1515 SMC_SELECT_BANK(sc, 2);
1516
1517 return (val);
1518}
1519
1520void
1521smc91cxx_mii_writereg(device_t self, int phy, int reg, int val)
1522{
1523 struct smc91cxx_softc *sc = device_private(self);
1524
1525 SMC_SELECT_BANK(sc, 3);
1526
1527 mii_bitbang_writereg(self, &smc91cxx_mii_bitbang_ops, phy, reg, val);
1528
1529 SMC_SELECT_BANK(sc, 2);
1530}
1531
1532void
1533smc91cxx_statchg(struct ifnet *ifp)
1534{
1535 struct smc91cxx_softc *sc = ifp->if_softc;
1536 bus_space_tag_t bst = sc->sc_bst;
1537 bus_space_handle_t bsh = sc->sc_bsh;
1538 int mctl;
1539
1540 SMC_SELECT_BANK(sc, 0);
1541 mctl = bus_space_read_2(bst, bsh, TXMIT_CONTROL_REG_W);
1542 if (sc->sc_mii.mii_media_active & IFM_FDX)
1543 mctl |= TCR_SWFDUP;
1544 else
1545 mctl &= ~TCR_SWFDUP;
1546 bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, mctl);
1547 SMC_SELECT_BANK(sc, 2); /* back to operating window */
1548}
1549
1550/*
1551 * One second timer, used to tick the MII.
1552 */
1553void
1554smc91cxx_tick(void *arg)
1555{
1556 struct smc91cxx_softc *sc = arg;
1557 int s;
1558
1559#ifdef DIAGNOSTIC
1560 if ((sc->sc_flags & SMC_FLAGS_HAS_MII) == 0)
1561 panic("smc91cxx_tick");
1562#endif
1563
1564 if (!device_is_active(sc->sc_dev))
1565 return;
1566
1567 s = splnet();
1568 mii_tick(&sc->sc_mii);
1569 splx(s);
1570
1571 callout_reset(&sc->sc_mii_callout, hz, smc91cxx_tick, sc);
1572}
1573