1 /* $NetBSD: smc90cx6.c,v 1.38 2001/07/07 15:57:53 thorpej Exp $ */
2 /* $FreeBSD: src/sys/dev/cm/smc90cx6.c,v 1.1.2.3 2003/02/05 18:42:14 fjoe Exp $ */
3 /* $DragonFly: src/sys/dev/netif/cm/Attic/smc90cx6.c,v 1.7 2004/02/13 02:44:47 joerg Exp $ */
6 * Copyright (c) 1994, 1995, 1998 The NetBSD Foundation, Inc.
9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Ignatios Souvatzis.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
42 * Chip core driver for the SMC90c26 / SMC90c56 (and SMC90c66 in '56
43 * compatibility mode) boards
46 /* #define CMSOFTCOPY */
47 #define CMRETRANSMIT /**/
48 /* #define CM_DEBUG */
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/sockio.h>
54 #include <sys/module.h>
55 #include <sys/kernel.h>
56 #include <sys/socket.h>
57 #include <sys/syslog.h>
60 #include <machine/bus.h>
62 #include <machine/resource.h>
64 #if defined(__DragonFly__) || __FreeBSD_version < 500000
65 #include <machine/clock.h>
69 #include <net/if_dl.h>
70 #include <net/if_types.h>
71 #include <net/if_arc.h>
73 #include "smc90cx6reg.h"
74 #include "smc90cx6var.h"
76 DECLARE_DUMMY_MODULE(if_cm);
77 MODULE_DEPEND(if_cm, arcnet, 1, 1, 1);
79 /* these should be elsewhere */
82 #define ARC_MIN_FORBID_LEN 254
83 #define ARC_MAX_FORBID_LEN 256
84 #define ARC_MAX_LEN 508
85 #define ARC_ADDR_LEN 1
87 /* for watchdog timer. This should be more than enough. */
88 #define ARCTIMEOUT (5*IFNET_SLOWHZ)
93 bus_space_read_1(rman_get_bustag((sc)->port_res), \
94 rman_get_bushandle((sc)->port_res), \
96 #define PUTREG(off, value) \
97 bus_space_write_1(rman_get_bustag((sc)->port_res), \
98 rman_get_bushandle((sc)->port_res), \
100 #define GETMEM(off) \
101 bus_space_read_1(rman_get_bustag((sc)->mem_res), \
102 rman_get_bushandle((sc)->mem_res), \
104 #define PUTMEM(off, value) \
105 bus_space_write_1(rman_get_bustag((sc)->mem_res), \
106 rman_get_bushandle((sc)->mem_res), \
109 devclass_t cm_devclass;
112 * This currently uses 2 bufs for tx, 2 for rx
116 * rx has a fillcount variable. If fillcount > (NRXBUF-1),
117 * rx can be switched off from rx hard int.
118 * Else rx is restarted on the other receiver.
119 * rx soft int counts down. if it is == (NRXBUF-1), it restarts
121 * To ensure packet ordering (we need that for 1201 later), we have a counter
122 * which is incremented modulo 256 on each receive and a per buffer
123 * variable, which is set to the counter on filling. The soft int can
124 * compare both values to determine the older packet.
126 * Transmit direction:
128 * cm_start checks tx_fillcount
131 * else fill tx_act ^ 1 && inc tx_fillcount
133 * check tx_fillcount again.
134 * case 2: set IFF_OACTIVE to stop arc_output from filling us.
137 * tint clears IFF_OCATIVE, decrements and checks tx_fillcount
138 * case 1: start tx on tx_act ^ 1, softcall cm_start
139 * case 0: softcall cm_start
141 * #define fill(i) get mbuf && copy mbuf to chip(i)
144 void cm_init (void *);
145 void cm_reset (struct cm_softc *);
146 void cm_start (struct ifnet *);
147 int cm_ioctl (struct ifnet *, unsigned long, caddr_t);
148 void cm_watchdog (struct ifnet *);
149 void cm_srint (void *vsc);
150 static void cm_tint (struct cm_softc *, int);
151 void cm_reconwatch(void *);
158 struct cm_softc *sc = device_get_softc(dev);
160 error = cm_alloc_port(dev, 0, CM_IO_PORTS);
164 if (GETREG(CMSTAT) == 0xff)
167 error = cm_alloc_memory(dev, 0, 0x800);
175 * Allocate a port resource with the given resource id.
178 cm_alloc_port(dev, rid, size)
183 struct cm_softc *sc = device_get_softc(dev);
184 struct resource *res;
186 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
187 0ul, ~0ul, size, RF_ACTIVE);
191 sc->port_used = size;
199 * Allocate a memory resource with the given resource id.
202 cm_alloc_memory(dev, rid, size)
207 struct cm_softc *sc = device_get_softc(dev);
208 struct resource *res;
210 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
211 0ul, ~0ul, size, RF_ACTIVE);
223 * Allocate an irq resource with the given resource id.
226 cm_alloc_irq(dev, rid)
230 struct cm_softc *sc = device_get_softc(dev);
231 struct resource *res;
233 res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
234 0ul, ~0ul, 1, RF_ACTIVE);
245 * Release all resources
248 cm_release_resources(dev)
251 struct cm_softc *sc = device_get_softc(dev);
254 bus_deactivate_resource(dev, SYS_RES_IOPORT,
255 sc->port_rid, sc->port_res);
256 bus_release_resource(dev, SYS_RES_IOPORT,
257 sc->port_rid, sc->port_res);
261 bus_deactivate_resource(dev, SYS_RES_MEMORY,
262 sc->mem_rid, sc->mem_res);
263 bus_release_resource(dev, SYS_RES_MEMORY,
264 sc->mem_rid, sc->mem_res);
268 bus_deactivate_resource(dev, SYS_RES_IRQ,
269 sc->irq_rid, sc->irq_res);
270 bus_release_resource(dev, SYS_RES_IRQ,
271 sc->irq_rid, sc->irq_res);
280 struct cm_softc *sc = device_get_softc(dev);
281 struct ifnet *ifp = &sc->sc_arccom.ac_if;
283 u_int8_t linkaddress;
288 * read the arcnet address from the board
294 } while (!(GETREG(CMSTAT) & CM_POR));
296 linkaddress = GETMEM(CMMACOFF);
298 /* clear the int mask... */
303 PUTREG(CMCMD, CM_CONF(CONF_LONG));
304 PUTREG(CMCMD, CM_CLR(CLR_POR|CLR_RECONFIG));
305 sc->sc_recontime = sc->sc_reconcount = 0;
307 /* and reenable kernel int level */
311 * set interface to stopped condition (reset)
316 if_initname(ifp, "cm", device_get_unit(dev));
317 ifp->if_output = arc_output;
318 ifp->if_start = cm_start;
319 ifp->if_ioctl = cm_ioctl;
320 ifp->if_watchdog = cm_watchdog;
321 ifp->if_init = cm_init;
322 /* XXX IFQ_SET_READY(&ifp->if_snd); */
323 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
325 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
327 arc_ifattach(ifp, linkaddress);
330 sc->sc_rxcookie = softintr_establish(IPL_SOFTNET, cm_srint, sc);
331 sc->sc_txcookie = softintr_establish(IPL_SOFTNET,
332 (void (*) (void *))cm_start, ifp);
335 #if defined(__DragonFly__) || __FreeBSD_version < 500000
336 callout_init(&sc->sc_recon_ch);
338 callout_init(&sc->sc_recon_ch, 0);
341 printf("%s: link addr 0x%02x (%d)\n",
342 ifp->if_xname, linkaddress, linkaddress);
354 struct cm_softc *sc = (struct cm_softc *)xsc;
358 ifp = &sc->sc_arccom.ac_if;
360 if ((ifp->if_flags & IFF_RUNNING) == 0) {
362 ifp->if_flags |= IFF_RUNNING;
370 * Reset the interface...
372 * this assumes that it is called inside a critical section...
382 ifp = &sc->sc_arccom.ac_if;
385 printf("%s: reset\n", ifp->if_xname);
387 /* stop and restart hardware */
392 } while (!(GETREG(CMSTAT) & CM_POR));
394 linkaddress = GETMEM(CMMACOFF);
396 #if defined(CM_DEBUG) && (CM_DEBUG > 2)
397 printf("%s: reset: card reset, link addr = 0x%02x (%d)\n",
398 ifp->if_xname, linkaddress, linkaddress);
401 /* tell the routing level about the (possibly changed) link address */
402 arc_storelladdr(ifp, linkaddress);
405 /* POR is NMI, but we need it below: */
406 sc->sc_intmask = CM_RECON|CM_POR;
407 PUTREG(CMSTAT, sc->sc_intmask);
408 PUTREG(CMCMD, CM_CONF(CONF_LONG));
411 printf("%s: reset: chip configured, status=0x%02x\n",
412 ifp->if_xname, GETREG(CMSTAT));
414 PUTREG(CMCMD, CM_CLR(CLR_POR|CLR_RECONFIG));
417 printf("%s: reset: bits cleared, status=0x%02x\n",
418 ifp->if_xname, GETREG(CMSTAT));
421 sc->sc_reconcount_excessive = ARC_EXCESSIVE_RECONS;
425 sc->sc_intmask |= CM_RI;
426 sc->sc_rx_fillcount = 0;
429 PUTREG(CMCMD, CM_RXBC(2));
430 PUTREG(CMSTAT, sc->sc_intmask);
433 printf("%s: reset: started receiver, status=0x%02x\n",
434 ifp->if_xname, GETREG(CMSTAT));
437 /* and init transmitter status */
439 sc->sc_tx_fillcount = 0;
441 ifp->if_flags |= IFF_RUNNING;
442 ifp->if_flags &= ~IFF_OACTIVE;
448 * Take interface offline
454 /* Stop the interrupts */
457 /* Stop the interface */
460 /* Stop watchdog timer */
461 sc->sc_arccom.ac_if.if_timer = 0;
465 * Start output on interface. Get another datagram to send
466 * off the interface queue, and copy it to the
467 * interface becore starting the output
469 * this assumes that it is called inside a critical section...
470 * XXX hm... does it still?
477 struct cm_softc *sc = ifp->if_softc;
481 int len, tlen, offset, s, buffer;
483 u_long copystart, lencopy, perbyte;
486 #if defined(CM_DEBUG) && (CM_DEBUG > 3)
487 printf("%s: start(%p)\n", ifp->if_xname, ifp);
490 if ((ifp->if_flags & IFF_RUNNING) == 0)
495 if (sc->sc_tx_fillcount >= 2) {
500 m = arc_frag_next(ifp);
501 buffer = sc->sc_tx_act ^ 1;
509 if (m->m_len < ARC_HDRLEN)
510 m = m_pullup(m, ARC_HDRLEN);/* gcc does structure padding */
511 printf("%s: start: filling %d from %d to %d type %d\n",
512 ifp->if_xname, buffer, mtod(m, u_char *)[0],
513 mtod(m, u_char *)[1], mtod(m, u_char *)[2]);
518 cm_ram_ptr = buffer * 512;
523 /* write the addresses to RAM and throw them away */
526 * Hardware does this: Yet Another Microsecond Saved.
527 * (btw, timing code says usually 2 microseconds)
528 * PUTMEM(cm_ram_ptr + 0, mtod(m, u_char *)[0]);
531 PUTMEM(cm_ram_ptr + 1, mtod(m, u_char *)[1]);
534 /* get total length left at this point */
535 tlen = m->m_pkthdr.len;
536 if (tlen < ARC_MIN_FORBID_LEN) {
538 PUTMEM(cm_ram_ptr + 2, offset);
540 PUTMEM(cm_ram_ptr + 2, 0);
541 if (tlen <= ARC_MAX_FORBID_LEN)
542 offset = 255; /* !!! */
544 if (tlen > ARC_MAX_LEN)
548 PUTMEM(cm_ram_ptr + 3, offset);
551 cm_ram_ptr += offset;
553 /* lets loop through the mbuf chain */
555 for (mp = m; mp; mp = mp->m_next) {
556 if ((len = mp->m_len)) { /* YAMS */
557 bus_space_write_region_1(
558 rman_get_bustag(sc->mem_res),
559 rman_get_bushandle(sc->mem_res),
560 cm_ram_ptr, mtod(mp, caddr_t), len);
566 sc->sc_broadcast[buffer] = (m->m_flags & M_BCAST) != 0;
567 sc->sc_retransmits[buffer] = (m->m_flags & M_BCAST) ? 1 : 5;
569 /* actually transmit the packet */
572 if (++sc->sc_tx_fillcount > 1) {
574 * We are filled up to the rim. No more bufs for the moment,
577 ifp->if_flags |= IFF_OACTIVE;
580 printf("%s: start: starting transmitter on buffer %d\n",
581 ifp->if_xname, buffer);
583 /* Transmitter was off, start it */
584 sc->sc_tx_act = buffer;
587 * We still can accept another buf, so don't:
588 * ifp->if_flags |= IFF_OACTIVE;
590 sc->sc_intmask |= CM_TA;
591 PUTREG(CMCMD, CM_TX(buffer));
592 PUTREG(CMSTAT, sc->sc_intmask);
594 sc->sc_arccom.ac_if.if_timer = ARCTIMEOUT;
600 * After 10 times reading the docs, I realized
601 * that in the case the receiver NAKs the buffer request,
602 * the hardware retries till shutdown.
603 * This is integrated now in the code above.
610 * Arcnet interface receiver soft interrupt:
611 * get the stuff out of any filled buffer we find.
617 struct cm_softc *sc = (struct cm_softc *)vsc;
618 int buffer, len, offset, s, type;
621 struct arc_header *ah;
624 ifp = &sc->sc_arccom.ac_if;
627 buffer = sc->sc_rx_act ^ 1;
630 /* Allocate header mbuf */
631 MGETHDR(m, M_DONTWAIT, MT_DATA);
635 * in case s.th. goes wrong with mem, drop it
636 * to make sure the receiver can be started again
637 * count it as input error (we dont have any other
644 m->m_pkthdr.rcvif = ifp;
647 * Align so that IP packet will be longword aligned. Here we
648 * assume that m_data of new packet is longword aligned.
649 * When implementing PHDS, we might have to change it to 2,
650 * (2*sizeof(ulong) - CM_HDRNEWLEN)), packet type dependent.
653 cm_ram_ptr = buffer * 512;
654 offset = GETMEM(cm_ram_ptr + 2);
658 offset = GETMEM(cm_ram_ptr + 3);
663 * first +2 bytes for align fixup below
664 * second +2 bytes are for src/dst addresses
666 if ((len + 2 + 2) > MHLEN) {
667 /* attach an mbuf cluster */
668 MCLGET(m, M_DONTWAIT);
670 /* Insist on getting a cluster */
671 if ((m->m_flags & M_EXT) == 0) {
682 type = GETMEM(cm_ram_ptr + offset);
683 m->m_data += 1 + arc_isphds(type);
684 /* mbuf filled with ARCnet addresses */
685 m->m_pkthdr.len = m->m_len = len + 2;
687 ah = mtod(m, struct arc_header *);
688 ah->arc_shost = GETMEM(cm_ram_ptr + 0);
689 ah->arc_dhost = GETMEM(cm_ram_ptr + 1);
691 bus_space_read_region_1(
692 rman_get_bustag(sc->mem_res), rman_get_bushandle(sc->mem_res),
693 cm_ram_ptr + offset, mtod(m, u_char *) + 2, len);
705 /* mark buffer as invalid by source id 0 */
706 PUTMEM(buffer << 9, 0);
709 if (--sc->sc_rx_fillcount == 2 - 1) {
711 /* was off, restart it on buffer just emptied */
712 sc->sc_rx_act = buffer;
713 sc->sc_intmask |= CM_RI;
715 /* this also clears the RI flag interupt: */
716 PUTREG(CMCMD, CM_RXBC(buffer));
717 PUTREG(CMSTAT, sc->sc_intmask);
720 printf("%s: srint: restarted rx on buf %d\n",
721 ifp->if_xname, buffer);
739 ifp = &(sc->sc_arccom.ac_if);
740 buffer = sc->sc_tx_act;
744 * Normal situtations first for fast path:
745 * If acknowledgement received ok or broadcast, we're ok.
749 if (isr & CM_TMA || sc->sc_broadcast[buffer])
750 sc->sc_arccom.ac_if.if_opackets++;
752 else if (ifp->if_flags & IFF_LINK2 && ifp->if_timer > 0
753 && --sc->sc_retransmits[buffer] > 0) {
754 /* retransmit same buffer */
755 PUTREG(CMCMD, CM_TX(buffer));
763 /* We know we can accept another buffer at this point. */
764 ifp->if_flags &= ~IFF_OACTIVE;
766 if (--sc->sc_tx_fillcount > 0) {
769 * start tx on other buffer.
770 * This also clears the int flag
773 sc->sc_tx_act = buffer;
777 * sc->sc_intmask |= CM_TA;
778 * PUTREG(CMSTAT, sc->sc_intmask);
780 PUTREG(CMCMD, CM_TX(buffer));
781 /* init watchdog timer */
782 ifp->if_timer = ARCTIMEOUT;
784 #if defined(CM_DEBUG) && (CM_DEBUG > 1)
785 printf("%s: tint: starting tx on buffer %d, status 0x%02x\n",
786 ifp->if_xname, buffer, GETREG(CMSTAT));
789 /* have to disable TX interrupt */
790 sc->sc_intmask &= ~CM_TA;
791 PUTREG(CMSTAT, sc->sc_intmask);
792 /* ... and watchdog timer */
796 printf("%s: tint: no more buffers to send, status 0x%02x\n",
797 ifp->if_xname, GETREG(CMSTAT));
803 /* schedule soft int to fill a new buffer for us */
804 softintr_schedule(sc->sc_txcookie);
806 /* call it directly */
812 * Our interrupt routine
818 struct cm_softc *sc = arg;
819 struct ifnet *ifp = &sc->sc_arccom.ac_if;
821 u_char isr, maskedisr;
825 isr = GETREG(CMSTAT);
826 maskedisr = isr & sc->sc_intmask;
831 #if defined(CM_DEBUG) && (CM_DEBUG > 1)
832 printf("%s: intr: status 0x%02x, intmask 0x%02x\n",
833 ifp->if_xname, isr, sc->sc_intmask);
836 if (maskedisr & CM_POR) {
838 * XXX We should never see this. Don't bother to store
840 * sc->sc_arccom.ac_anaddr = GETMEM(CMMACOFF);
842 PUTREG(CMCMD, CM_CLR(CLR_POR));
844 "%s: intr: got spurious power on reset int\n",
848 if (maskedisr & CM_RECON) {
851 * PUTREG(CMCMD, CM_CONF(CONF_LONG));
853 PUTREG(CMCMD, CM_CLR(CLR_RECONFIG));
854 sc->sc_arccom.ac_if.if_collisions++;
857 * If less than 2 seconds per reconfig:
858 * If ARC_EXCESSIVE_RECONFIGS
859 * since last burst, complain and set treshold for
860 * warnings to ARC_EXCESSIVE_RECONS_REWARN.
862 * This allows for, e.g., new stations on the cable, or
863 * cable switching as long as it is over after
864 * (normally) 16 seconds.
866 * XXX TODO: check timeout bits in status word and
867 * double time if necessary.
870 callout_stop(&sc->sc_recon_ch);
871 newsec = time_second;
872 if ((newsec - sc->sc_recontime <= 2) &&
873 (++sc->sc_reconcount == ARC_EXCESSIVE_RECONS)) {
875 "%s: excessive token losses, "
879 sc->sc_recontime = newsec;
880 callout_reset(&sc->sc_recon_ch, 15 * hz,
881 cm_reconwatch, (void *)sc);
884 if (maskedisr & CM_RI) {
885 #if defined(CM_DEBUG) && (CM_DEBUG > 1)
886 printf("%s: intr: hard rint, act %d\n",
887 ifp->if_xname, sc->sc_rx_act);
890 buffer = sc->sc_rx_act;
891 /* look if buffer is marked invalid: */
892 if (GETMEM(buffer * 512) == 0) {
894 * invalid marked buffer (or illegally
898 "%s: spurious RX interupt or sender 0 "
899 " (ignored)\n", ifp->if_xname);
901 * restart receiver on same buffer.
902 * XXX maybe better reset interface?
904 PUTREG(CMCMD, CM_RXBC(buffer));
906 if (++sc->sc_rx_fillcount > 1) {
907 sc->sc_intmask &= ~CM_RI;
908 PUTREG(CMSTAT, sc->sc_intmask);
911 sc->sc_rx_act = buffer;
914 * Start receiver on other receive
915 * buffer. This also clears the RI
918 PUTREG(CMCMD, CM_RXBC(buffer));
919 /* in RX intr, so mask is ok for RX */
922 printf("%s: strt rx for buf %d, "
925 sc->sc_rx_act, GETREG(CMSTAT));
931 * this one starts a soft int to copy out
934 softintr_schedule(sc->sc_rxcookie);
936 /* this one does the copy here */
941 if (maskedisr & CM_TA) {
944 isr = GETREG(CMSTAT);
945 maskedisr = isr & sc->sc_intmask;
947 #if defined(CM_DEBUG) && (CM_DEBUG > 1)
948 printf("%s: intr (exit): status 0x%02x, intmask 0x%02x\n",
949 ifp->if_xname, isr, sc->sc_intmask);
957 struct cm_softc *sc = arg;
958 struct ifnet *ifp = &sc->sc_arccom.ac_if;
960 if (sc->sc_reconcount >= ARC_EXCESSIVE_RECONS) {
961 sc->sc_reconcount = 0;
962 log(LOG_WARNING, "%s: token valid again.\n",
965 sc->sc_reconcount = 0;
970 * Process an ioctl request.
971 * This code needs some work - it looks pretty ugly.
974 cm_ioctl(ifp, command, data)
986 ifa = (struct ifaddr *)data;
987 ifr = (struct ifreq *)data;
990 #if defined(CM_DEBUG) && (CM_DEBUG > 2)
991 printf("%s: ioctl() called, cmd = 0x%lx\n",
992 ifp->if_xname, command);
1001 error = arc_ioctl(ifp, command, data);
1005 if ((ifp->if_flags & IFF_UP) == 0 &&
1006 (ifp->if_flags & IFF_RUNNING) != 0) {
1008 * If interface is marked down and it is running,
1012 ifp->if_flags &= ~IFF_RUNNING;
1013 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1014 (ifp->if_flags & IFF_RUNNING) == 0) {
1016 * If interface is marked up and it is stopped, then
1033 * watchdog routine for transmitter.
1035 * We need this, because else a receiver whose hardware is alive, but whose
1036 * software has not enabled the Receiver, would make our hardware wait forever
1037 * Discovered this after 20 times reading the docs.
1039 * Only thing we do is disable transmitter. We'll get an transmit timeout,
1040 * and the int handler will have to decide not to retransmit (in case
1041 * retransmission is implemented).
1043 * This one assumes being called inside splimp()
1050 struct cm_softc *sc = ifp->if_softc;
1052 PUTREG(CMCMD, CM_TXDIS);