2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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 Herb Peyerl.
16 * 4. The name of Herb Peyerl may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * if_ep.c,v 1.19 1995/01/24 20:53:45 davidg Exp
34 * Modified from the FreeBSD 1.1.5.1 version by:
36 * INRIA - Sophia Antipolis, France
37 * avega@sophia.inria.fr
41 * $FreeBSD: src/sys/dev/ep/if_ep.c,v 1.95.2.3 2002/03/06 07:26:35 imp Exp $
42 * $DragonFly: src/sys/dev/netif/ep/if_ep.c,v 1.25 2006/10/25 20:55:56 dillon Exp $
44 * Promiscuous mode added and interrupt logic slightly changed
45 * to reduce the number of adapter failures. Transceiver select
46 * logic changed to use value from EEPROM. Autoconfiguration
50 * Chelindbank (Chelyabinsk, Russia)
51 * babkin@hq.icb.chel.su
55 * Pccard support for 3C589 by:
61 * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
65 #include <sys/param.h>
66 #include <sys/kernel.h>
67 #include <sys/systm.h>
68 #include <sys/malloc.h>
70 #include <sys/socket.h>
71 #include <sys/sockio.h>
72 #include <sys/module.h>
75 #include <sys/thread2.h>
78 #include <net/ifq_var.h>
79 #include <net/if_arp.h>
80 #include <net/if_media.h>
81 #include <net/ethernet.h>
84 #include <netinet/in.h>
85 #include <netinet/if_ether.h>
87 #include <machine/clock.h>
91 #include "../elink_layer/elink.h"
93 /* Exported variables */
94 devclass_t ep_devclass
;
97 static char * ep_conn_type
[] = {"UTP", "AUI", "???", "BNC"};
98 static int if_media2ep_media
[] = { 0, 0, 0, UTP
, BNC
, AUI
};
101 static int ep_media2if_media
[] =
102 { IFM_10_T
, IFM_10_5
, IFM_NONE
, IFM_10_2
, IFM_NONE
};
105 static void ep_if_init (void *);
106 static int ep_if_ioctl(struct ifnet
*, u_long
, caddr_t
, struct ucred
*);
107 static void ep_if_start (struct ifnet
*);
108 static void ep_if_watchdog (struct ifnet
*);
110 /* if_media functions */
111 static int ep_ifmedia_upd (struct ifnet
*);
112 static void ep_ifmedia_sts (struct ifnet
*, struct ifmediareq
*);
114 static void epstop (struct ep_softc
*);
115 static void epread (struct ep_softc
*);
116 static int eeprom_rdy (struct ep_softc
*);
118 DECLARE_DUMMY_MODULE(if_ep
);
120 #define EP_FTST(sc, f) (sc->stat & (f))
121 #define EP_FSET(sc, f) (sc->stat |= (f))
122 #define EP_FRST(sc, f) (sc->stat &= ~(f))
125 eeprom_rdy(struct ep_softc
*sc
)
129 for (i
= 0; is_eeprom_busy(BASE
) && i
< MAX_EEPROMBUSY
; i
++) {
132 if (i
>= MAX_EEPROMBUSY
) {
133 if_printf(&sc
->arpcom
.ac_if
, "eeprom failed to come ready.\n");
140 * get_e: gets a 16 bits word from the EEPROM. we must have set the window
144 get_e(struct ep_softc
*sc
, int offset
)
148 outw(BASE
+ EP_W0_EEPROM_COMMAND
, (EEPROM_CMD_RD
<< sc
->epb
.cmd_off
) | offset
);
151 return (inw(BASE
+ EP_W0_EEPROM_DATA
));
155 ep_get_macaddr(struct ep_softc
*sc
, uint8_t *addr
)
158 u_int16_t
* macaddr
= (u_int16_t
*)addr
;
161 for(i
= EEPROM_NODE_ADDR_0
; i
<= EEPROM_NODE_ADDR_2
; i
++) {
162 macaddr
[i
] = htons(get_e(sc
, i
));
169 ep_alloc(device_t dev
)
171 struct ep_softc
* sc
= device_get_softc(dev
);
176 sc
->iobase
= bus_alloc_resource_any(dev
, SYS_RES_IOPORT
, &rid
,
179 device_printf(dev
, "No I/O space?!\n");
185 sc
->irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
, RF_ACTIVE
);
187 device_printf(dev
, "No irq?!\n");
192 if_initname(&sc
->arpcom
.ac_if
,
193 device_get_name(dev
), device_get_unit(dev
));
194 sc
->stat
= 0; /* 16 bit access */
196 sc
->ep_io_addr
= rman_get_start(sc
->iobase
);
198 sc
->ep_btag
= rman_get_bustag(sc
->iobase
);
199 sc
->ep_bhandle
= rman_get_bushandle(sc
->iobase
);
201 sc
->ep_connectors
= 0;
202 sc
->ep_connector
= 0;
206 sc
->epb
.prod_id
= get_e(sc
, EEPROM_PROD_ID
);
207 sc
->epb
.res_cfg
= get_e(sc
, EEPROM_RESOURCE_CFG
);
214 ep_get_media(struct ep_softc
*sc
)
219 config
= inw(BASE
+ EP_W0_CONFIG_CTRL
);
221 sc
->ep_connectors
|= AUI
;
223 sc
->ep_connectors
|= BNC
;
225 sc
->ep_connectors
|= UTP
;
227 if (!(sc
->ep_connectors
& 7)) {
229 if_printf(&sc
->arpcom
.ac_if
, "no connectors!\n");
233 * This works for most of the cards so we'll do it here.
234 * The cards that require something different can override
237 sc
->ep_connector
= inw(BASE
+ EP_W0_ADDRESS_CFG
) >> ACF_CONNECTOR_BITS
;
243 ep_free(device_t dev
)
245 struct ep_softc
* sc
= device_get_softc(dev
);
248 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, sc
->iobase
);
250 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->irq
);
256 ep_attach(struct ep_softc
*sc
)
258 struct ifnet
* ifp
= NULL
;
259 struct ifmedia
* ifm
= NULL
;
261 uint8_t ether_addr
[ETHER_ADDR_LEN
];
266 ep_get_macaddr(sc
, ether_addr
);
269 * Setup the station address
271 p
= (u_short
*)ether_addr
;
273 for (i
= 0; i
< 3; i
++) {
274 outw(BASE
+ EP_W2_ADDR_0
+ (i
* 2), ntohs(p
[i
]));
277 ifp
= &sc
->arpcom
.ac_if
;
280 ifp
->if_mtu
= ETHERMTU
;
281 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
282 ifp
->if_start
= ep_if_start
;
283 ifp
->if_ioctl
= ep_if_ioctl
;
284 ifp
->if_watchdog
= ep_if_watchdog
;
285 ifp
->if_init
= ep_if_init
;
286 ifq_set_maxlen(&ifp
->if_snd
, IFQ_MAXLEN
);
287 ifq_set_ready(&ifp
->if_snd
);
289 if (!sc
->epb
.mii_trans
) {
290 ifmedia_init(&sc
->ifmedia
, 0, ep_ifmedia_upd
, ep_ifmedia_sts
);
292 if (sc
->ep_connectors
& AUI
)
293 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
|IFM_10_5
, 0, NULL
);
294 if (sc
->ep_connectors
& UTP
)
295 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
|IFM_10_T
, 0, NULL
);
296 if (sc
->ep_connectors
& BNC
)
297 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
|IFM_10_2
, 0, NULL
);
298 if (!sc
->ep_connectors
)
299 ifmedia_add(&sc
->ifmedia
, IFM_ETHER
|IFM_NONE
, 0, NULL
);
301 ifmedia_set(&sc
->ifmedia
, IFM_ETHER
|ep_media2if_media
[sc
->ep_connector
]);
304 ifm
->ifm_media
= ifm
->ifm_cur
->ifm_media
;
308 ether_ifattach(ifp
, ether_addr
, NULL
);
310 #ifdef EP_LOCAL_STATS
311 sc
->rx_no_first
= sc
->rx_no_mbuf
= sc
->rx_bpf_disc
=
312 sc
->rx_overrunf
= sc
->rx_overrunl
= sc
->tx_underrun
= 0;
314 EP_FSET(sc
, F_RX_FIRST
);
315 sc
->top
= sc
->mcur
= 0;
321 * The order in here seems important. Otherwise we may not receive
325 ep_if_init(void *xsc
)
327 struct ep_softc
*sc
= xsc
;
328 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
336 while (inw(BASE
+ EP_STATUS
) & S_COMMAND_IN_PROGRESS
);
339 outw(BASE
+ EP_COMMAND
, STOP_TRANSCEIVER
);
341 outw(BASE
+ EP_W4_MEDIA_TYPE
, DISABLE_UTP
);
344 /* Disable the card */
345 outw(BASE
+ EP_W0_CONFIG_CTRL
, 0);
347 /* Enable the card */
348 outw(BASE
+ EP_W0_CONFIG_CTRL
, ENABLE_DRQ_IRQ
);
352 /* Reload the ether_addr. */
353 for (i
= 0; i
< 6; i
++)
354 outb(BASE
+ EP_W2_ADDR_0
+ i
, sc
->arpcom
.ac_enaddr
[i
]);
356 outw(BASE
+ EP_COMMAND
, RX_RESET
);
357 outw(BASE
+ EP_COMMAND
, TX_RESET
);
358 while (inw(BASE
+ EP_STATUS
) & S_COMMAND_IN_PROGRESS
);
360 /* Window 1 is operating window */
362 for (i
= 0; i
< 31; i
++)
363 inb(BASE
+ EP_W1_TX_STATUS
);
365 /* get rid of stray intr's */
366 outw(BASE
+ EP_COMMAND
, ACK_INTR
| 0xff);
368 outw(BASE
+ EP_COMMAND
, SET_RD_0_MASK
| S_5_INTS
);
370 outw(BASE
+ EP_COMMAND
, SET_INTR_MASK
| S_5_INTS
);
372 if (ifp
->if_flags
& IFF_PROMISC
)
373 outw(BASE
+ EP_COMMAND
, SET_RX_FILTER
| FIL_INDIVIDUAL
|
374 FIL_GROUP
| FIL_BRDCST
| FIL_ALL
);
376 outw(BASE
+ EP_COMMAND
, SET_RX_FILTER
| FIL_INDIVIDUAL
|
377 FIL_GROUP
| FIL_BRDCST
);
379 if (!sc
->epb
.mii_trans
) {
383 outw(BASE
+ EP_COMMAND
, RX_ENABLE
);
384 outw(BASE
+ EP_COMMAND
, TX_ENABLE
);
386 ifp
->if_flags
|= IFF_RUNNING
;
387 ifp
->if_flags
&= ~IFF_OACTIVE
; /* just in case */
389 #ifdef EP_LOCAL_STATS
390 sc
->rx_no_first
= sc
->rx_no_mbuf
=
391 sc
->rx_overrunf
= sc
->rx_overrunl
= sc
->tx_underrun
= 0;
393 EP_FSET(sc
, F_RX_FIRST
);
396 sc
->top
= sc
->mcur
= 0;
398 outw(BASE
+ EP_COMMAND
, SET_RX_EARLY_THRESH
| RX_INIT_EARLY_THRESH
);
399 outw(BASE
+ EP_COMMAND
, SET_TX_START_THRESH
| 16);
402 * Store up a bunch of mbuf's for use later. (MAX_MBS). First we free up
403 * any that we had in case we're being called from intr or somewhere
413 static const char padmap
[] = {0, 3, 2, 1};
416 ep_if_start(struct ifnet
*ifp
)
418 struct ep_softc
*sc
= ifp
->if_softc
;
428 while (inw(BASE
+ EP_STATUS
) & S_COMMAND_IN_PROGRESS
);
429 if (ifp
->if_flags
& IFF_OACTIVE
) {
436 /* Sneak a peek at the next packet */
437 m
= ifq_poll(&ifp
->if_snd
);
443 for (len
= 0, top
= m
; m
; m
= m
->m_next
)
447 pad
= padmap
[len
& 3];
450 * The 3c509 automatically pads short packets to minimum ethernet length,
451 * but we drop packets that are too large. Perhaps we should truncate
454 if (len
+ pad
> ETHER_MAX_LEN
) {
455 /* packet is obviously too large: toss it */
457 ifq_dequeue(&ifp
->if_snd
, m
);
461 if (inw(BASE
+ EP_W1_FREE_TX
) < len
+ pad
+ 4) {
462 /* no room in FIFO */
463 outw(BASE
+ EP_COMMAND
, SET_TX_AVAIL_THRESH
| (len
+ pad
+ 4));
465 if (inw(BASE
+ EP_W1_FREE_TX
) < len
+ pad
+ 4) {
466 ifp
->if_flags
|= IFF_OACTIVE
;
471 outw(BASE
+ EP_COMMAND
, SET_TX_AVAIL_THRESH
| EP_THRESH_DISABLE
);
474 ifq_dequeue(&ifp
->if_snd
, m
);
476 outw(BASE
+ EP_W1_TX_PIO_WR_1
, len
);
477 outw(BASE
+ EP_W1_TX_PIO_WR_1
, 0x0); /* Second dword meaningless */
479 if (EP_FTST(sc
, F_ACCESS_32_BITS
)) {
480 for (top
= m
; m
!= 0; m
= m
->m_next
) {
481 outsl(BASE
+ EP_W1_TX_PIO_WR_1
, mtod(m
, caddr_t
),
484 outsb(BASE
+ EP_W1_TX_PIO_WR_1
,
485 mtod(m
, caddr_t
) + (m
->m_len
& (~3)),
489 for (top
= m
; m
!= 0; m
= m
->m_next
) {
490 outsw(BASE
+ EP_W1_TX_PIO_WR_1
, mtod(m
, caddr_t
), m
->m_len
/ 2);
492 outb(BASE
+ EP_W1_TX_PIO_WR_1
,
493 *(mtod(m
, caddr_t
) + m
->m_len
- 1));
498 outb(BASE
+ EP_W1_TX_PIO_WR_1
, 0); /* Padding */
507 * Is another packet coming in? We don't want to overflow the tiny RX
511 if (inw(BASE
+ EP_W1_RX_STATUS
) & RX_BYTES_MASK
) {
513 * we check if we have packets left, in that case we prepare to come
516 if (!ifq_is_empty(&ifp
->if_snd
))
517 outw(BASE
+ EP_COMMAND
, SET_TX_AVAIL_THRESH
| 8);
528 struct ep_softc
*sc
= arg
;
529 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
533 * quick fix: Try to detect an interrupt when the card goes away.
535 if (sc
->gone
|| inw(BASE
+ EP_STATUS
) == 0xffff) {
539 outw(BASE
+ EP_COMMAND
, SET_INTR_MASK
); /* disable all Ints */
543 while ((status
= inw(BASE
+ EP_STATUS
)) & S_5_INTS
) {
545 /* first acknowledge all interrupt sources */
546 outw(BASE
+ EP_COMMAND
, ACK_INTR
| (status
& S_MASK
));
548 if (status
& (S_RX_COMPLETE
| S_RX_EARLY
))
550 if (status
& S_TX_AVAIL
) {
553 ifp
->if_flags
&= ~IFF_OACTIVE
;
555 inw(BASE
+ EP_W1_FREE_TX
);
558 if (status
& S_CARD_FAILURE
) {
560 #ifdef EP_LOCAL_STATS
562 if_printf(ifp
, "\n\tStatus: %x\n", status
);
564 printf("\tFIFO Diagnostic: %x\n", inw(BASE
+ EP_W4_FIFO_DIAG
));
565 printf("\tStat: %x\n", sc
->stat
);
566 printf("\tIpackets=%d, Opackets=%d\n",
567 ifp
->if_ipackets
, ifp
->if_opackets
);
568 printf("\tNOF=%d, NOMB=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
569 sc
->rx_no_first
, sc
->rx_no_mbuf
, sc
->rx_overrunf
,
570 sc
->rx_overrunl
, sc
->tx_underrun
);
574 if_printf(ifp
, "Status: %x (input buffer overflow)\n", status
);
583 if (status
& S_TX_COMPLETE
) {
585 /* we need ACK. we do it at the end */
587 * We need to read TX_STATUS until we get a 0 status in order to
588 * turn off the interrupt flag.
590 while ((status
= inb(BASE
+ EP_W1_TX_STATUS
)) & TXS_COMPLETE
) {
591 if (status
& TXS_SUCCES_INTR_REQ
);
592 else if (status
& (TXS_UNDERRUN
| TXS_JABBER
| TXS_MAX_COLLISION
)) {
593 outw(BASE
+ EP_COMMAND
, TX_RESET
);
594 if (status
& TXS_UNDERRUN
) {
595 #ifdef EP_LOCAL_STATS
599 if (status
& TXS_JABBER
);
600 else /* TXS_MAX_COLLISION - we shouldn't get here */
601 ++ifp
->if_collisions
;
604 outw(BASE
+ EP_COMMAND
, TX_ENABLE
);
606 * To have a tx_avail_int but giving the chance to the
609 if (!ifq_is_empty(&ifp
->if_snd
))
610 outw(BASE
+ EP_COMMAND
, SET_TX_AVAIL_THRESH
| 8);
612 outb(BASE
+ EP_W1_TX_STATUS
, 0x0); /* pops up the next
615 ifp
->if_flags
&= ~IFF_OACTIVE
;
617 inw(BASE
+ EP_W1_FREE_TX
);
619 } /* end TX_COMPLETE */
622 outw(BASE
+ EP_COMMAND
, C_INTR_LATCH
); /* ACK int Latch */
624 if ((status
= inw(BASE
+ EP_STATUS
)) & S_5_INTS
)
628 outw(BASE
+ EP_COMMAND
, SET_INTR_MASK
| S_5_INTS
);
632 epread(struct ep_softc
*sc
)
634 struct mbuf
*top
, *mcur
, *m
;
638 short rx_fifo2
, status
;
641 ifp
= &sc
->arpcom
.ac_if
;
642 status
= inw(BASE
+ EP_W1_RX_STATUS
);
646 if (status
& ERR_RX
) {
648 if (status
& ERR_RX_OVERRUN
) {
650 * we can think the rx latency is actually greather than we
653 #ifdef EP_LOCAL_STATS
654 if (EP_FTST(sc
, F_RX_FIRST
))
662 rx_fifo
= rx_fifo2
= status
& RX_BYTES_MASK
;
664 if (EP_FTST(sc
, F_RX_FIRST
)) {
665 m
= m_getl(rx_fifo
, MB_DONTWAIT
, MT_DATA
, M_PKTHDR
, NULL
);
668 sc
->top
= sc
->mcur
= top
= m
;
669 #define EROUND ((sizeof(struct ether_header) + 3) & ~3)
670 #define EOFF (EROUND - sizeof(struct ether_header))
673 /* Read what should be the header. */
674 insw(BASE
+ EP_W1_RX_PIO_RD_1
,
675 mtod(top
, caddr_t
), sizeof(struct ether_header
) / 2);
676 top
->m_len
= sizeof(struct ether_header
);
677 rx_fifo
-= sizeof(struct ether_header
);
678 sc
->cur_len
= rx_fifo2
;
680 /* come here if we didn't have a complete packet last time */
683 sc
->cur_len
+= rx_fifo2
;
686 /* Reads what is left in the RX FIFO */
687 while (rx_fifo
> 0) {
688 lenthisone
= min(rx_fifo
, M_TRAILINGSPACE(m
));
689 if (lenthisone
== 0) { /* no room in this one */
691 m
= m_getl(rx_fifo
, MB_DONTWAIT
, MT_DATA
, 0, NULL
);
696 lenthisone
= min(rx_fifo
, M_TRAILINGSPACE(m
));
698 if (EP_FTST(sc
, F_ACCESS_32_BITS
)) { /* default for EISA configured cards*/
699 insl(BASE
+ EP_W1_RX_PIO_RD_1
, mtod(m
, caddr_t
) + m
->m_len
,
701 m
->m_len
+= (lenthisone
& ~3);
703 insb(BASE
+ EP_W1_RX_PIO_RD_1
,
704 mtod(m
, caddr_t
) + m
->m_len
,
706 m
->m_len
+= (lenthisone
& 3);
708 insw(BASE
+ EP_W1_RX_PIO_RD_1
, mtod(m
, caddr_t
) + m
->m_len
,
710 m
->m_len
+= lenthisone
;
712 *(mtod(m
, caddr_t
) + m
->m_len
- 1) = inb(BASE
+ EP_W1_RX_PIO_RD_1
);
714 rx_fifo
-= lenthisone
;
717 if (status
& ERR_RX_INCOMPLETE
) { /* we haven't received the complete
720 #ifdef EP_LOCAL_STATS
721 sc
->rx_no_first
++; /* to know how often we come here */
723 EP_FRST(sc
, F_RX_FIRST
);
724 if (!((status
= inw(BASE
+ EP_W1_RX_STATUS
)) & ERR_RX_INCOMPLETE
)) {
725 /* we see if by now, the packet has completly arrived */
728 outw(BASE
+ EP_COMMAND
, SET_RX_EARLY_THRESH
| RX_NEXT_EARLY_THRESH
);
731 outw(BASE
+ EP_COMMAND
, RX_DISCARD_TOP_PACK
);
733 EP_FSET(sc
, F_RX_FIRST
);
734 top
->m_pkthdr
.rcvif
= &sc
->arpcom
.ac_if
;
735 top
->m_pkthdr
.len
= sc
->cur_len
;
737 ifp
->if_input(ifp
, top
);
739 while (inw(BASE
+ EP_STATUS
) & S_COMMAND_IN_PROGRESS
);
740 outw(BASE
+ EP_COMMAND
, SET_RX_EARLY_THRESH
| RX_INIT_EARLY_THRESH
);
744 outw(BASE
+ EP_COMMAND
, RX_DISCARD_TOP_PACK
);
748 #ifdef EP_LOCAL_STATS
752 EP_FSET(sc
, F_RX_FIRST
);
753 while (inw(BASE
+ EP_STATUS
) & S_COMMAND_IN_PROGRESS
);
754 outw(BASE
+ EP_COMMAND
, SET_RX_EARLY_THRESH
| RX_INIT_EARLY_THRESH
);
758 ep_ifmedia_upd(struct ifnet
*ifp
)
760 struct ep_softc
* sc
= ifp
->if_softc
;
764 outw(BASE
+ EP_COMMAND
, STOP_TRANSCEIVER
);
766 outw(BASE
+ EP_W4_MEDIA_TYPE
, DISABLE_UTP
);
769 switch (IFM_SUBTYPE(sc
->ifmedia
.ifm_media
)) {
771 if (sc
->ep_connectors
& UTP
) {
772 i
= ACF_CONNECTOR_UTP
;
774 outw(BASE
+ EP_W4_MEDIA_TYPE
, ENABLE_UTP
);
778 if (sc
->ep_connectors
& BNC
) {
779 i
= ACF_CONNECTOR_BNC
;
780 outw(BASE
+ EP_COMMAND
, START_TRANSCEIVER
);
781 DELAY(DELAY_MULTIPLE
* 1000);
785 if (sc
->ep_connectors
& AUI
)
786 i
= ACF_CONNECTOR_AUI
;
789 i
= sc
->ep_connector
;
790 if_printf(ifp
, "strange connector type in EEPROM: "
796 j
= inw(BASE
+ EP_W0_ADDRESS_CFG
) & 0x3fff;
797 outw(BASE
+ EP_W0_ADDRESS_CFG
, j
| (i
<< ACF_CONNECTOR_BITS
));
803 ep_ifmedia_sts(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
805 struct ep_softc
* sc
= ifp
->if_softc
;
807 ifmr
->ifm_active
= sc
->ifmedia
.ifm_media
;
813 ep_if_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
, struct ucred
*cr
)
815 struct ep_softc
* sc
= ifp
->if_softc
;
816 struct ifreq
* ifr
= (struct ifreq
*)data
;
823 if (((ifp
->if_flags
& IFF_UP
) == 0) &&
824 (ifp
->if_flags
& IFF_RUNNING
)) {
825 ifp
->if_flags
&= ~IFF_RUNNING
;
828 /* reinitialize card on any parameter change */
834 bcopy((caddr_t
) sc
->sc_addr
, (caddr_t
) & ifr
->ifr_data
,
835 sizeof(sc
->sc_addr
));
841 * The Etherlink III has no programmable multicast
842 * filter. We always initialize the card to be
843 * promiscuous to multicast, since we're always a
844 * member of the ALL-SYSTEMS group, so there's no
845 * need to process SIOC*MULTI requests.
851 if (!sc
->epb
.mii_trans
) {
852 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->ifmedia
, cmd
);
858 error
= ether_ioctl(ifp
, cmd
, data
);
868 ep_if_watchdog(struct ifnet
*ifp
)
870 struct ep_softc
*sc
= ifp
->if_softc
;
873 if_printf(ifp, "watchdog\n");
875 log(LOG_ERR, "%s: watchdog\n", ifp->if_xname);
883 ifp
->if_flags
&= ~IFF_OACTIVE
;
885 ep_intr(ifp
->if_softc
);
889 epstop(struct ep_softc
*sc
)
895 outw(BASE
+ EP_COMMAND
, RX_DISABLE
);
896 outw(BASE
+ EP_COMMAND
, RX_DISCARD_TOP_PACK
);
897 while (inw(BASE
+ EP_STATUS
) & S_COMMAND_IN_PROGRESS
);
898 outw(BASE
+ EP_COMMAND
, TX_DISABLE
);
899 outw(BASE
+ EP_COMMAND
, STOP_TRANSCEIVER
);
900 outw(BASE
+ EP_COMMAND
, RX_RESET
);
901 outw(BASE
+ EP_COMMAND
, TX_RESET
);
902 while (inw(BASE
+ EP_STATUS
) & S_COMMAND_IN_PROGRESS
);
903 outw(BASE
+ EP_COMMAND
, C_INTR_LATCH
);
904 outw(BASE
+ EP_COMMAND
, SET_RD_0_MASK
);
905 outw(BASE
+ EP_COMMAND
, SET_INTR_MASK
);
906 outw(BASE
+ EP_COMMAND
, SET_RX_FILTER
);