Deleted Added
full compact
if_ep.c (121399) if_ep.c (121492)
1/*
2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
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

--- 15 unchanged lines hidden (view full) ---

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.
29 */
30
31#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
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

--- 15 unchanged lines hidden (view full) ---

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.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/dev/ep/if_ep.c 121399 2003-10-23 05:33:53Z imp $");
32__FBSDID("$FreeBSD: head/sys/dev/ep/if_ep.c 121492 2003-10-25 04:09:49Z imp $");
33
34/*
35 * Modified from the FreeBSD 1.1.5.1 version by:
36 * Andres Vega Garcia
37 * INRIA - Sophia Antipolis, France
38 * avega@sophia.inria.fr
39 */
40

--- 15 unchanged lines hidden (view full) ---

56 */
57
58/*
59 * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
60 * <mdodd@FreeBSD.org>
61 */
62
63#include <sys/cdefs.h>
33
34/*
35 * Modified from the FreeBSD 1.1.5.1 version by:
36 * Andres Vega Garcia
37 * INRIA - Sophia Antipolis, France
38 * avega@sophia.inria.fr
39 */
40

--- 15 unchanged lines hidden (view full) ---

56 */
57
58/*
59 * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
60 * <mdodd@FreeBSD.org>
61 */
62
63#include <sys/cdefs.h>
64__FBSDID("$FreeBSD: head/sys/dev/ep/if_ep.c 121399 2003-10-23 05:33:53Z imp $");
64__FBSDID("$FreeBSD: head/sys/dev/ep/if_ep.c 121492 2003-10-25 04:09:49Z imp $");
65
66#include <sys/param.h>
67#include <sys/systm.h>
68#include <sys/mbuf.h>
69#include <sys/socket.h>
70#include <sys/sockio.h>
71#include <sys/bus.h>
72

--- 12 unchanged lines hidden (view full) ---

85
86/* Exported variables */
87devclass_t ep_devclass;
88
89static int ep_media2if_media[] =
90{IFM_10_T, IFM_10_5, IFM_NONE, IFM_10_2, IFM_NONE};
91
92/* if functions */
65
66#include <sys/param.h>
67#include <sys/systm.h>
68#include <sys/mbuf.h>
69#include <sys/socket.h>
70#include <sys/sockio.h>
71#include <sys/bus.h>
72

--- 12 unchanged lines hidden (view full) ---

85
86/* Exported variables */
87devclass_t ep_devclass;
88
89static int ep_media2if_media[] =
90{IFM_10_T, IFM_10_5, IFM_NONE, IFM_10_2, IFM_NONE};
91
92/* if functions */
93static void ep_if_init(void *);
94static int ep_if_ioctl(struct ifnet *, u_long, caddr_t);
95static void ep_if_start(struct ifnet *);
96static void ep_if_watchdog(struct ifnet *);
93static void epinit(void *);
94static int epioctl(struct ifnet *, u_long, caddr_t);
95static void epstart(struct ifnet *);
96static void epwatchdog(struct ifnet *);
97
97
98static void epstart_body(struct ifnet *);
99static void epinit_body(struct ep_softc *);
100
98/* if_media functions */
99static int ep_ifmedia_upd(struct ifnet *);
100static void ep_ifmedia_sts(struct ifnet *, struct ifmediareq *);
101
102static void epstop(struct ep_softc *);
103static void epread(struct ep_softc *);
104static int eeprom_rdy(struct ep_softc *);
105

--- 23 unchanged lines hidden (view full) ---

129 */
130int
131get_e(struct ep_softc *sc, u_int16_t offset, u_int16_t *result)
132{
133
134 if (eeprom_rdy(sc))
135 return (ENXIO);
136
101/* if_media functions */
102static int ep_ifmedia_upd(struct ifnet *);
103static void ep_ifmedia_sts(struct ifnet *, struct ifmediareq *);
104
105static void epstop(struct ep_softc *);
106static void epread(struct ep_softc *);
107static int eeprom_rdy(struct ep_softc *);
108

--- 23 unchanged lines hidden (view full) ---

132 */
133int
134get_e(struct ep_softc *sc, u_int16_t offset, u_int16_t *result)
135{
136
137 if (eeprom_rdy(sc))
138 return (ENXIO);
139
137 EP_WRITE_2(sc, EP_W0_EEPROM_COMMAND,
140 CSR_WRITE_2(sc, EP_W0_EEPROM_COMMAND,
138 (EEPROM_CMD_RD << sc->epb.cmd_off) | offset);
139
140 if (eeprom_rdy(sc))
141 return (ENXIO);
142
141 (EEPROM_CMD_RD << sc->epb.cmd_off) | offset);
142
143 if (eeprom_rdy(sc))
144 return (ENXIO);
145
143 (*result) = EP_READ_2(sc, EP_W0_EEPROM_DATA);
146 (*result) = CSR_READ_2(sc, EP_W0_EEPROM_DATA);
144
145 return (0);
146}
147
148int
149ep_get_macaddr(struct ep_softc *sc, u_char *addr)
150{
151 int i;

--- 66 unchanged lines hidden (view full) ---

218}
219
220void
221ep_get_media(struct ep_softc *sc)
222{
223 u_int16_t config;
224
225 GO_WINDOW(0);
147
148 return (0);
149}
150
151int
152ep_get_macaddr(struct ep_softc *sc, u_char *addr)
153{
154 int i;

--- 66 unchanged lines hidden (view full) ---

221}
222
223void
224ep_get_media(struct ep_softc *sc)
225{
226 u_int16_t config;
227
228 GO_WINDOW(0);
226 config = EP_READ_2(sc, EP_W0_CONFIG_CTRL);
229 config = CSR_READ_2(sc, EP_W0_CONFIG_CTRL);
227 if (config & IS_AUI)
228 sc->ep_connectors |= AUI;
229 if (config & IS_BNC)
230 sc->ep_connectors |= BNC;
231 if (config & IS_UTP)
232 sc->ep_connectors |= UTP;
233
234 if (!(sc->ep_connectors & 7))
235 if (bootverbose)
236 device_printf(sc->dev, "no connectors!\n");
237
238 /*
239 * This works for most of the cards so we'll do it here.
240 * The cards that require something different can override
241 * this later on.
242 */
230 if (config & IS_AUI)
231 sc->ep_connectors |= AUI;
232 if (config & IS_BNC)
233 sc->ep_connectors |= BNC;
234 if (config & IS_UTP)
235 sc->ep_connectors |= UTP;
236
237 if (!(sc->ep_connectors & 7))
238 if (bootverbose)
239 device_printf(sc->dev, "no connectors!\n");
240
241 /*
242 * This works for most of the cards so we'll do it here.
243 * The cards that require something different can override
244 * this later on.
245 */
243 sc->ep_connector = EP_READ_2(sc, EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
246 sc->ep_connector = CSR_READ_2(sc, EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
244}
245
246void
247ep_free(device_t dev)
248{
249 struct ep_softc *sc = device_get_softc(dev);
250
251 if (sc->ep_intrhand)

--- 10 unchanged lines hidden (view full) ---

262 struct ifnet *ifp = NULL;
263 struct ifmedia *ifm = NULL;
264 u_short *p;
265 int i;
266 int attached;
267 int error;
268
269 sc->gone = 0;
247}
248
249void
250ep_free(device_t dev)
251{
252 struct ep_softc *sc = device_get_softc(dev);
253
254 if (sc->ep_intrhand)

--- 10 unchanged lines hidden (view full) ---

265 struct ifnet *ifp = NULL;
266 struct ifmedia *ifm = NULL;
267 u_short *p;
268 int i;
269 int attached;
270 int error;
271
272 sc->gone = 0;
270
273 mtx_init(&sc->sc_mtx, device_get_nameunit(sc->dev), MTX_NETWORK_LOCK,
274 MTX_DEF);
271 error = ep_get_macaddr(sc, (u_char *)&sc->arpcom.ac_enaddr);
272 if (error) {
273 device_printf(sc->dev, "Unable to get Ethernet address!\n");
275 error = ep_get_macaddr(sc, (u_char *)&sc->arpcom.ac_enaddr);
276 if (error) {
277 device_printf(sc->dev, "Unable to get Ethernet address!\n");
278 mtx_destroy(&sc->sc_mtx);
274 return (ENXIO);
275 }
276 /*
277 * Setup the station address
278 */
279 p = (u_short *)&sc->arpcom.ac_enaddr;
280 GO_WINDOW(2);
281 for (i = 0; i < 3; i++)
279 return (ENXIO);
280 }
281 /*
282 * Setup the station address
283 */
284 p = (u_short *)&sc->arpcom.ac_enaddr;
285 GO_WINDOW(2);
286 for (i = 0; i < 3; i++)
282 EP_WRITE_2(sc, EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
287 CSR_WRITE_2(sc, EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
283
284 device_printf(sc->dev, "Ethernet address %6D\n",
285 sc->arpcom.ac_enaddr, ":");
286
287 ifp = &sc->arpcom.ac_if;
288 attached = (ifp->if_softc != 0);
289
290 ifp->if_softc = sc;
291 ifp->if_unit = sc->unit;
292 ifp->if_name = "ep";
293 ifp->if_mtu = ETHERMTU;
294 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
295 ifp->if_output = ether_output;
288
289 device_printf(sc->dev, "Ethernet address %6D\n",
290 sc->arpcom.ac_enaddr, ":");
291
292 ifp = &sc->arpcom.ac_if;
293 attached = (ifp->if_softc != 0);
294
295 ifp->if_softc = sc;
296 ifp->if_unit = sc->unit;
297 ifp->if_name = "ep";
298 ifp->if_mtu = ETHERMTU;
299 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
300 ifp->if_output = ether_output;
296 ifp->if_start = ep_if_start;
297 ifp->if_ioctl = ep_if_ioctl;
298 ifp->if_watchdog = ep_if_watchdog;
299 ifp->if_init = ep_if_init;
301 ifp->if_start = epstart;
302 ifp->if_ioctl = epioctl;
303 ifp->if_watchdog = epwatchdog;
304 ifp->if_init = epinit;
300 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
301
302 if (!sc->epb.mii_trans) {
303 ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts);
304
305 if (sc->ep_connectors & AUI)
306 ifmedia_add(&sc->ifmedia,
307 IFM_ETHER | IFM_10_5, 0, NULL);

--- 45 unchanged lines hidden (view full) ---

353 if (bus_child_present(dev))
354 epstop(sc);
355
356 ifp->if_flags &= ~IFF_RUNNING;
357 ether_ifdetach(ifp);
358
359 sc->gone = 1;
360 ep_free(dev);
305 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
306
307 if (!sc->epb.mii_trans) {
308 ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts);
309
310 if (sc->ep_connectors & AUI)
311 ifmedia_add(&sc->ifmedia,
312 IFM_ETHER | IFM_10_5, 0, NULL);

--- 45 unchanged lines hidden (view full) ---

358 if (bus_child_present(dev))
359 epstop(sc);
360
361 ifp->if_flags &= ~IFF_RUNNING;
362 ether_ifdetach(ifp);
363
364 sc->gone = 1;
365 ep_free(dev);
366 mtx_destroy(&sc->sc_mtx);
361
362 return (0);
363}
364
367
368 return (0);
369}
370
371static void
372epinit(void *xsc)
373{
374 struct ep_softc *sc = xsc;
375 EP_LOCK(sc);
376 epinit_body(sc);
377 EP_UNLOCK(sc);
378}
379
365/*
366 * The order in here seems important. Otherwise we may not receive
367 * interrupts. ?!
368 */
369static void
380/*
381 * The order in here seems important. Otherwise we may not receive
382 * interrupts. ?!
383 */
384static void
370ep_if_init(void *xsc)
385epinit_body(struct ep_softc *sc)
371{
386{
372 struct ep_softc *sc = xsc;
373 struct ifnet *ifp = &sc->arpcom.ac_if;
387 struct ifnet *ifp = &sc->arpcom.ac_if;
374 int s, i;
388 int i;
375
376 if (sc->gone)
377 return;
378
389
390 if (sc->gone)
391 return;
392
379 s = splimp();
380 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
393 EP_BUSY_WAIT;
381
382 GO_WINDOW(0);
394
395 GO_WINDOW(0);
383 EP_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
396 CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
384 GO_WINDOW(4);
397 GO_WINDOW(4);
385 EP_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
398 CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
386 GO_WINDOW(0);
387
388 /* Disable the card */
399 GO_WINDOW(0);
400
401 /* Disable the card */
389 EP_WRITE_2(sc, EP_W0_CONFIG_CTRL, 0);
402 CSR_WRITE_2(sc, EP_W0_CONFIG_CTRL, 0);
390
391 /* Enable the card */
403
404 /* Enable the card */
392 EP_WRITE_2(sc, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
405 CSR_WRITE_2(sc, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
393
394 GO_WINDOW(2);
395
396 /* Reload the ether_addr. */
397 for (i = 0; i < 6; i++)
406
407 GO_WINDOW(2);
408
409 /* Reload the ether_addr. */
410 for (i = 0; i < 6; i++)
398 EP_WRITE_1(sc, EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
411 CSR_WRITE_1(sc, EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
399
412
400 EP_WRITE_2(sc, EP_COMMAND, RX_RESET);
401 EP_WRITE_2(sc, EP_COMMAND, TX_RESET);
402 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
413 CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
414 CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
415 EP_BUSY_WAIT;
403
404 /* Window 1 is operating window */
405 GO_WINDOW(1);
406 for (i = 0; i < 31; i++)
416
417 /* Window 1 is operating window */
418 GO_WINDOW(1);
419 for (i = 0; i < 31; i++)
407 EP_READ_1(sc, EP_W1_TX_STATUS);
420 CSR_READ_1(sc, EP_W1_TX_STATUS);
408
409 /* get rid of stray intr's */
421
422 /* get rid of stray intr's */
410 EP_WRITE_2(sc, EP_COMMAND, ACK_INTR | 0xff);
423 CSR_WRITE_2(sc, EP_COMMAND, ACK_INTR | 0xff);
411
424
412 EP_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
425 CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
413
426
414 EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
427 CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
415
416 if (ifp->if_flags & IFF_PROMISC)
428
429 if (ifp->if_flags & IFF_PROMISC)
417 EP_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
418 FIL_GROUP | FIL_BRDCST | FIL_ALL);
430 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
431 FIL_MULTICAST | FIL_BRDCST | FIL_PROMISC);
419 else
432 else
420 EP_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
421 FIL_GROUP | FIL_BRDCST);
433 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
434 FIL_MULTICAST | FIL_BRDCST);
422
423 if (!sc->epb.mii_trans)
424 ep_ifmedia_upd(ifp);
425
435
436 if (!sc->epb.mii_trans)
437 ep_ifmedia_upd(ifp);
438
426 EP_WRITE_2(sc, EP_COMMAND, RX_ENABLE);
427 EP_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
439 CSR_WRITE_2(sc, EP_COMMAND, RX_ENABLE);
440 CSR_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
428
429 ifp->if_flags |= IFF_RUNNING;
430 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
431
432#ifdef EP_LOCAL_STATS
433 sc->rx_no_first = sc->rx_no_mbuf =
434 sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0;
435#endif
436 EP_FSET(sc, F_RX_FIRST);
437 if (sc->top) {
438 m_freem(sc->top);
439 sc->top = sc->mcur = 0;
440 }
441
442 ifp->if_flags |= IFF_RUNNING;
443 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
444
445#ifdef EP_LOCAL_STATS
446 sc->rx_no_first = sc->rx_no_mbuf =
447 sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0;
448#endif
449 EP_FSET(sc, F_RX_FIRST);
450 if (sc->top) {
451 m_freem(sc->top);
452 sc->top = sc->mcur = 0;
453 }
441 EP_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
442 EP_WRITE_2(sc, EP_COMMAND, SET_TX_START_THRESH | 16);
454 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
455 CSR_WRITE_2(sc, EP_COMMAND, SET_TX_START_THRESH | 16);
443
444 /*
445 * Store up a bunch of mbuf's for use later. (MAX_MBS).
446 * First we free up any that we had in case we're being
447 * called from intr or somewhere else.
448 */
449
450 GO_WINDOW(1);
456
457 /*
458 * Store up a bunch of mbuf's for use later. (MAX_MBS).
459 * First we free up any that we had in case we're being
460 * called from intr or somewhere else.
461 */
462
463 GO_WINDOW(1);
451 ep_if_start(ifp);
452
453 splx(s);
464 epstart_body(ifp);
454}
455
456static void
465}
466
467static void
457ep_if_start(struct ifnet *ifp)
468epstart(struct ifnet *ifp)
458{
459 struct ep_softc *sc;
469{
470 struct ep_softc *sc;
471 sc = ifp->if_softc;
472 EP_LOCK(sc);
473 epstart_body(ifp);
474 EP_UNLOCK(sc);
475}
476
477static void
478epstart_body(struct ifnet *ifp)
479{
480 struct ep_softc *sc;
460 u_int len;
461 struct mbuf *m, *m0;
481 u_int len;
482 struct mbuf *m, *m0;
462 int s, pad;
483 int pad;
463
464 sc = ifp->if_softc;
465 if (sc->gone)
466 return;
467
484
485 sc = ifp->if_softc;
486 if (sc->gone)
487 return;
488
468 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
489 EP_BUSY_WAIT;
469 if (ifp->if_flags & IFF_OACTIVE)
470 return;
490 if (ifp->if_flags & IFF_OACTIVE)
491 return;
471
472startagain:
473 /* Sneak a peek at the next packet */
474 IF_DEQUEUE(&ifp->if_snd, m0);
475 if (m0 == NULL)
476 return;
477 for (len = 0, m = m0; m != NULL; m = m->m_next)
478 len += m->m_len;
479

--- 5 unchanged lines hidden (view full) ---

485 * Perhaps we should truncate them instead?
486 */
487 if (len + pad > ETHER_MAX_LEN) {
488 /* packet is obviously too large: toss it */
489 ifp->if_oerrors++;
490 m_freem(m0);
491 goto readcheck;
492 }
492startagain:
493 /* Sneak a peek at the next packet */
494 IF_DEQUEUE(&ifp->if_snd, m0);
495 if (m0 == NULL)
496 return;
497 for (len = 0, m = m0; m != NULL; m = m->m_next)
498 len += m->m_len;
499

--- 5 unchanged lines hidden (view full) ---

505 * Perhaps we should truncate them instead?
506 */
507 if (len + pad > ETHER_MAX_LEN) {
508 /* packet is obviously too large: toss it */
509 ifp->if_oerrors++;
510 m_freem(m0);
511 goto readcheck;
512 }
493 if (EP_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
513 if (CSR_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
494 /* no room in FIFO */
514 /* no room in FIFO */
495 EP_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
515 CSR_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
496 /* make sure */
516 /* make sure */
497 if (EP_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
517 if (CSR_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
498 ifp->if_flags |= IFF_OACTIVE;
499 IF_PREPEND(&ifp->if_snd, m0);
518 ifp->if_flags |= IFF_OACTIVE;
519 IF_PREPEND(&ifp->if_snd, m0);
500 return;
520 goto done;
501 }
502 } else
521 }
522 } else
503 EP_WRITE_2(sc, EP_COMMAND,
523 CSR_WRITE_2(sc, EP_COMMAND,
504 SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
505
524 SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
525
506 s = splhigh();
526 /* XXX 4.x and earlier would splhigh here */
507
527
508 EP_WRITE_2(sc, EP_W1_TX_PIO_WR_1, len);
528 CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, len);
509 /* Second dword meaningless */
529 /* Second dword meaningless */
510 EP_WRITE_2(sc, EP_W1_TX_PIO_WR_1, 0x0);
530 CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, 0x0);
511
512 if (EP_FTST(sc, F_ACCESS_32_BITS)) {
513 for (m = m0; m != NULL; m = m->m_next) {
514 if (m->m_len > 3)
531
532 if (EP_FTST(sc, F_ACCESS_32_BITS)) {
533 for (m = m0; m != NULL; m = m->m_next) {
534 if (m->m_len > 3)
515 EP_WRITE_MULTI_4(sc, EP_W1_TX_PIO_WR_1,
535 CSR_WRITE_MULTI_4(sc, EP_W1_TX_PIO_WR_1,
516 mtod(m, uint32_t *), m->m_len / 4);
517 if (m->m_len & 3)
536 mtod(m, uint32_t *), m->m_len / 4);
537 if (m->m_len & 3)
518 EP_WRITE_MULTI_1(sc, EP_W1_TX_PIO_WR_1,
538 CSR_WRITE_MULTI_1(sc, EP_W1_TX_PIO_WR_1,
519 mtod(m, uint8_t *)+(m->m_len & (~3)),
520 m->m_len & 3);
521 }
522 } else {
523 for (m = m0; m != NULL; m = m->m_next) {
524 if (m->m_len > 1)
539 mtod(m, uint8_t *)+(m->m_len & (~3)),
540 m->m_len & 3);
541 }
542 } else {
543 for (m = m0; m != NULL; m = m->m_next) {
544 if (m->m_len > 1)
525 EP_WRITE_MULTI_2(sc, EP_W1_TX_PIO_WR_1,
545 CSR_WRITE_MULTI_2(sc, EP_W1_TX_PIO_WR_1,
526 mtod(m, uint16_t *), m->m_len / 2);
527 if (m->m_len & 1)
546 mtod(m, uint16_t *), m->m_len / 2);
547 if (m->m_len & 1)
528 EP_WRITE_1(sc, EP_W1_TX_PIO_WR_1,
548 CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1,
529 *(mtod(m, uint8_t *)+m->m_len - 1));
530 }
531 }
532
533 while (pad--)
549 *(mtod(m, uint8_t *)+m->m_len - 1));
550 }
551 }
552
553 while (pad--)
534 EP_WRITE_1(sc, EP_W1_TX_PIO_WR_1, 0); /* Padding */
554 CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1, 0); /* Padding */
535
555
536 splx(s);
556 /* XXX and drop splhigh here */
537
538 BPF_MTAP(ifp, m0);
539
540 ifp->if_timer = 2;
541 ifp->if_opackets++;
542 m_freem(m0);
543
544 /*
545 * Is another packet coming in? We don't want to overflow
546 * the tiny RX fifo.
547 */
548readcheck:
557
558 BPF_MTAP(ifp, m0);
559
560 ifp->if_timer = 2;
561 ifp->if_opackets++;
562 m_freem(m0);
563
564 /*
565 * Is another packet coming in? We don't want to overflow
566 * the tiny RX fifo.
567 */
568readcheck:
549 if (EP_READ_2(sc, EP_W1_RX_STATUS) & RX_BYTES_MASK) {
569 if (CSR_READ_2(sc, EP_W1_RX_STATUS) & RX_BYTES_MASK) {
550 /*
551 * we check if we have packets left, in that case
552 * we prepare to come back later
553 */
554 if (ifp->if_snd.ifq_head)
570 /*
571 * we check if we have packets left, in that case
572 * we prepare to come back later
573 */
574 if (ifp->if_snd.ifq_head)
555 EP_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
556 return;
575 CSR_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
576 goto done;
557 }
558 goto startagain;
577 }
578 goto startagain;
579done:;
580 return;
559}
560
561void
562ep_intr(void *arg)
563{
564 struct ep_softc *sc;
565 int status;
566 struct ifnet *ifp;
581}
582
583void
584ep_intr(void *arg)
585{
586 struct ep_softc *sc;
587 int status;
588 struct ifnet *ifp;
567 int x;
568
589
569 x = splbio();
570
571 sc = (struct ep_softc *) arg;
590 sc = (struct ep_softc *) arg;
591 EP_LOCK(sc);
592 /* XXX 4.x splbio'd here to reduce interruptability */
572
573 /*
574 * quick fix: Try to detect an interrupt when the card goes away.
575 */
593
594 /*
595 * quick fix: Try to detect an interrupt when the card goes away.
596 */
576 if (sc->gone || EP_READ_2(sc, EP_STATUS) == 0xffff) {
577 splx(x);
597 if (sc->gone || CSR_READ_2(sc, EP_STATUS) == 0xffff) {
598 EP_UNLOCK(sc);
578 return;
579 }
580 ifp = &sc->arpcom.ac_if;
581
599 return;
600 }
601 ifp = &sc->arpcom.ac_if;
602
582 EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK); /* disable all Ints */
603 CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK); /* disable all Ints */
583
584rescan:
585
604
605rescan:
606
586 while ((status = EP_READ_2(sc, EP_STATUS)) & S_5_INTS) {
607 while ((status = CSR_READ_2(sc, EP_STATUS)) & S_5_INTS) {
587
588 /* first acknowledge all interrupt sources */
608
609 /* first acknowledge all interrupt sources */
589 EP_WRITE_2(sc, EP_COMMAND, ACK_INTR | (status & S_MASK));
610 CSR_WRITE_2(sc, EP_COMMAND, ACK_INTR | (status & S_MASK));
590
591 if (status & (S_RX_COMPLETE | S_RX_EARLY))
592 epread(sc);
593 if (status & S_TX_AVAIL) {
594 /* we need ACK */
595 ifp->if_timer = 0;
596 ifp->if_flags &= ~IFF_OACTIVE;
597 GO_WINDOW(1);
611
612 if (status & (S_RX_COMPLETE | S_RX_EARLY))
613 epread(sc);
614 if (status & S_TX_AVAIL) {
615 /* we need ACK */
616 ifp->if_timer = 0;
617 ifp->if_flags &= ~IFF_OACTIVE;
618 GO_WINDOW(1);
598 EP_READ_2(sc, EP_W1_FREE_TX);
599 ep_if_start(ifp);
619 CSR_READ_2(sc, EP_W1_FREE_TX);
620 epstart_body(ifp);
600 }
601 if (status & S_CARD_FAILURE) {
602 ifp->if_timer = 0;
603#ifdef EP_LOCAL_STATS
604 printf("\nep%d:\n\tStatus: %x\n", sc->unit, status);
605 GO_WINDOW(4);
606 printf("\tFIFO Diagnostic: %x\n",
621 }
622 if (status & S_CARD_FAILURE) {
623 ifp->if_timer = 0;
624#ifdef EP_LOCAL_STATS
625 printf("\nep%d:\n\tStatus: %x\n", sc->unit, status);
626 GO_WINDOW(4);
627 printf("\tFIFO Diagnostic: %x\n",
607 EP_READ_2(sc, EP_W4_FIFO_DIAG));
628 CSR_READ_2(sc, EP_W4_FIFO_DIAG));
608 printf("\tStat: %x\n", sc->stat);
609 printf("\tIpackets=%d, Opackets=%d\n",
610 ifp->if_ipackets, ifp->if_opackets);
611 printf("\tNOF=%d, NOMB=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
612 sc->rx_no_first, sc->rx_no_mbuf, sc->rx_overrunf,
613 sc->rx_overrunl, sc->tx_underrun);
614#else
615
616#ifdef DIAGNOSTIC
617 printf("ep%d: Status: %x (input buffer overflow)\n",
618 sc->unit, status);
619#else
620 ++ifp->if_ierrors;
621#endif
622
623#endif
629 printf("\tStat: %x\n", sc->stat);
630 printf("\tIpackets=%d, Opackets=%d\n",
631 ifp->if_ipackets, ifp->if_opackets);
632 printf("\tNOF=%d, NOMB=%d, RXOF=%d, RXOL=%d, TXU=%d\n",
633 sc->rx_no_first, sc->rx_no_mbuf, sc->rx_overrunf,
634 sc->rx_overrunl, sc->tx_underrun);
635#else
636
637#ifdef DIAGNOSTIC
638 printf("ep%d: Status: %x (input buffer overflow)\n",
639 sc->unit, status);
640#else
641 ++ifp->if_ierrors;
642#endif
643
644#endif
624 ep_if_init(sc);
625 splx(x);
645 epinit_body(sc);
646 EP_UNLOCK(sc);
626 return;
627 }
628 if (status & S_TX_COMPLETE) {
629 ifp->if_timer = 0;
630 /*
631 * We need ACK. We do it at the end.
632 *
633 * We need to read TX_STATUS until we get a
634 * 0 status in order to turn off the interrupt flag.
635 */
647 return;
648 }
649 if (status & S_TX_COMPLETE) {
650 ifp->if_timer = 0;
651 /*
652 * We need ACK. We do it at the end.
653 *
654 * We need to read TX_STATUS until we get a
655 * 0 status in order to turn off the interrupt flag.
656 */
636 while ((status = EP_READ_1(sc, EP_W1_TX_STATUS)) &
657 while ((status = CSR_READ_1(sc, EP_W1_TX_STATUS)) &
637 TXS_COMPLETE) {
638 if (status & TXS_SUCCES_INTR_REQ);
639 else if (status &
640 (TXS_UNDERRUN | TXS_JABBER |
641 TXS_MAX_COLLISION)) {
658 TXS_COMPLETE) {
659 if (status & TXS_SUCCES_INTR_REQ);
660 else if (status &
661 (TXS_UNDERRUN | TXS_JABBER |
662 TXS_MAX_COLLISION)) {
642 EP_WRITE_2(sc, EP_COMMAND, TX_RESET);
663 CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
643 if (status & TXS_UNDERRUN) {
644#ifdef EP_LOCAL_STATS
645 sc->tx_underrun++;
646#endif
647 } else {
648 if (status & TXS_JABBER);
649 else
650 ++ifp->if_collisions;
651 /* TXS_MAX_COLLISION
652 * we shouldn't get
653 * here
654 */
655 }
656 ++ifp->if_oerrors;
664 if (status & TXS_UNDERRUN) {
665#ifdef EP_LOCAL_STATS
666 sc->tx_underrun++;
667#endif
668 } else {
669 if (status & TXS_JABBER);
670 else
671 ++ifp->if_collisions;
672 /* TXS_MAX_COLLISION
673 * we shouldn't get
674 * here
675 */
676 }
677 ++ifp->if_oerrors;
657 EP_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
678 CSR_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
658 /*
659 * To have a tx_avail_int but giving
660 * the chance to the Reception
661 */
662 if (ifp->if_snd.ifq_head)
679 /*
680 * To have a tx_avail_int but giving
681 * the chance to the Reception
682 */
683 if (ifp->if_snd.ifq_head)
663 EP_WRITE_2(sc, EP_COMMAND,
684 CSR_WRITE_2(sc, EP_COMMAND,
664 SET_TX_AVAIL_THRESH | 8);
665 }
666 /* pops up the next status */
685 SET_TX_AVAIL_THRESH | 8);
686 }
687 /* pops up the next status */
667 EP_WRITE_1(sc, EP_W1_TX_STATUS, 0x0);
688 CSR_WRITE_1(sc, EP_W1_TX_STATUS, 0x0);
668 } /* while */
669 ifp->if_flags &= ~IFF_OACTIVE;
670 GO_WINDOW(1);
689 } /* while */
690 ifp->if_flags &= ~IFF_OACTIVE;
691 GO_WINDOW(1);
671 EP_READ_2(sc, EP_W1_FREE_TX);
672 ep_if_start(ifp);
692 CSR_READ_2(sc, EP_W1_FREE_TX);
693 epstart_body(ifp);
673 } /* end TX_COMPLETE */
674 }
675
694 } /* end TX_COMPLETE */
695 }
696
676 EP_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH); /* ACK int Latch */
697 CSR_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH); /* ACK int Latch */
677
698
678 if ((status = EP_READ_2(sc, EP_STATUS)) & S_5_INTS)
699 if ((status = CSR_READ_2(sc, EP_STATUS)) & S_5_INTS)
679 goto rescan;
680
681 /* re-enable Ints */
700 goto rescan;
701
702 /* re-enable Ints */
682 EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
683
684 splx(x);
703 CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
704 EP_UNLOCK(sc);
685}
686
687static void
688epread(struct ep_softc *sc)
689{
690 struct mbuf *top, *mcur, *m;
691 struct ifnet *ifp;
692 int lenthisone;
705}
706
707static void
708epread(struct ep_softc *sc)
709{
710 struct mbuf *top, *mcur, *m;
711 struct ifnet *ifp;
712 int lenthisone;
693
694 short rx_fifo2, status;
695 short rx_fifo;
696
713 short rx_fifo2, status;
714 short rx_fifo;
715
716/* XXX Must be called with sc locked */
717
697 ifp = &sc->arpcom.ac_if;
718 ifp = &sc->arpcom.ac_if;
698 status = EP_READ_2(sc, EP_W1_RX_STATUS);
719 status = CSR_READ_2(sc, EP_W1_RX_STATUS);
699
700read_again:
701
702 if (status & ERR_RX) {
703 ++ifp->if_ierrors;
704 if (status & ERR_RX_OVERRUN) {
705 /*
706 * We can think the rx latency is actually

--- 17 unchanged lines hidden (view full) ---

724 if (rx_fifo >= MINCLSIZE)
725 MCLGET(m, M_DONTWAIT);
726 sc->top = sc->mcur = top = m;
727#define EROUND ((sizeof(struct ether_header) + 3) & ~3)
728#define EOFF (EROUND - sizeof(struct ether_header))
729 top->m_data += EOFF;
730
731 /* Read what should be the header. */
720
721read_again:
722
723 if (status & ERR_RX) {
724 ++ifp->if_ierrors;
725 if (status & ERR_RX_OVERRUN) {
726 /*
727 * We can think the rx latency is actually

--- 17 unchanged lines hidden (view full) ---

745 if (rx_fifo >= MINCLSIZE)
746 MCLGET(m, M_DONTWAIT);
747 sc->top = sc->mcur = top = m;
748#define EROUND ((sizeof(struct ether_header) + 3) & ~3)
749#define EOFF (EROUND - sizeof(struct ether_header))
750 top->m_data += EOFF;
751
752 /* Read what should be the header. */
732 EP_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
753 CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
733 mtod(top, uint16_t *), sizeof(struct ether_header) / 2);
734 top->m_len = sizeof(struct ether_header);
735 rx_fifo -= sizeof(struct ether_header);
736 sc->cur_len = rx_fifo2;
737 } else {
738 /* come here if we didn't have a complete packet last time */
739 top = sc->top;
740 m = sc->mcur;

--- 11 unchanged lines hidden (view full) ---

752 if (rx_fifo >= MINCLSIZE)
753 MCLGET(m, M_DONTWAIT);
754 m->m_len = 0;
755 mcur->m_next = m;
756 lenthisone = min(rx_fifo, M_TRAILINGSPACE(m));
757 }
758 if (EP_FTST(sc, F_ACCESS_32_BITS)) {
759 /* default for EISA configured cards */
754 mtod(top, uint16_t *), sizeof(struct ether_header) / 2);
755 top->m_len = sizeof(struct ether_header);
756 rx_fifo -= sizeof(struct ether_header);
757 sc->cur_len = rx_fifo2;
758 } else {
759 /* come here if we didn't have a complete packet last time */
760 top = sc->top;
761 m = sc->mcur;

--- 11 unchanged lines hidden (view full) ---

773 if (rx_fifo >= MINCLSIZE)
774 MCLGET(m, M_DONTWAIT);
775 m->m_len = 0;
776 mcur->m_next = m;
777 lenthisone = min(rx_fifo, M_TRAILINGSPACE(m));
778 }
779 if (EP_FTST(sc, F_ACCESS_32_BITS)) {
780 /* default for EISA configured cards */
760 EP_READ_MULTI_4(sc, EP_W1_RX_PIO_RD_1,
781 CSR_READ_MULTI_4(sc, EP_W1_RX_PIO_RD_1,
761 (uint32_t *)(mtod(m, caddr_t)+m->m_len),
762 lenthisone / 4);
763 m->m_len += (lenthisone & ~3);
764 if (lenthisone & 3)
782 (uint32_t *)(mtod(m, caddr_t)+m->m_len),
783 lenthisone / 4);
784 m->m_len += (lenthisone & ~3);
785 if (lenthisone & 3)
765 EP_READ_MULTI_1(sc, EP_W1_RX_PIO_RD_1,
786 CSR_READ_MULTI_1(sc, EP_W1_RX_PIO_RD_1,
766 mtod(m, caddr_t)+m->m_len, lenthisone & 3);
767 m->m_len += (lenthisone & 3);
768 } else {
787 mtod(m, caddr_t)+m->m_len, lenthisone & 3);
788 m->m_len += (lenthisone & 3);
789 } else {
769 EP_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
790 CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
770 (uint16_t *)(mtod(m, caddr_t)+m->m_len),
771 lenthisone / 2);
772 m->m_len += lenthisone;
773 if (lenthisone & 1)
774 *(mtod(m, caddr_t)+m->m_len - 1) =
791 (uint16_t *)(mtod(m, caddr_t)+m->m_len),
792 lenthisone / 2);
793 m->m_len += lenthisone;
794 if (lenthisone & 1)
795 *(mtod(m, caddr_t)+m->m_len - 1) =
775 EP_READ_1(sc, EP_W1_RX_PIO_RD_1);
796 CSR_READ_1(sc, EP_W1_RX_PIO_RD_1);
776 }
777 rx_fifo -= lenthisone;
778 }
779
780 if (status & ERR_RX_INCOMPLETE) {
781 /* we haven't received the complete packet */
782 sc->mcur = m;
783#ifdef EP_LOCAL_STATS
784 /* to know how often we come here */
785 sc->rx_no_first++;
786#endif
787 EP_FRST(sc, F_RX_FIRST);
797 }
798 rx_fifo -= lenthisone;
799 }
800
801 if (status & ERR_RX_INCOMPLETE) {
802 /* we haven't received the complete packet */
803 sc->mcur = m;
804#ifdef EP_LOCAL_STATS
805 /* to know how often we come here */
806 sc->rx_no_first++;
807#endif
808 EP_FRST(sc, F_RX_FIRST);
788 status = EP_READ_2(sc, EP_W1_RX_STATUS);
809 status = CSR_READ_2(sc, EP_W1_RX_STATUS);
789 if (!status & ERR_RX_INCOMPLETE) {
790 /*
791 * We see if by now, the packet has completly
792 * arrived
793 */
794 goto read_again;
795 }
810 if (!status & ERR_RX_INCOMPLETE) {
811 /*
812 * We see if by now, the packet has completly
813 * arrived
814 */
815 goto read_again;
816 }
796 EP_WRITE_2(sc, EP_COMMAND,
817 CSR_WRITE_2(sc, EP_COMMAND,
797 SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH);
798 return;
799 }
818 SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH);
819 return;
820 }
800 EP_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
821 CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
801 ++ifp->if_ipackets;
802 EP_FSET(sc, F_RX_FIRST);
803 top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
804 top->m_pkthdr.len = sc->cur_len;
805
822 ++ifp->if_ipackets;
823 EP_FSET(sc, F_RX_FIRST);
824 top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
825 top->m_pkthdr.len = sc->cur_len;
826
827 /*
828 * Drop locks before calling if_input() since it may re-enter
829 * ep_start() in the netisr case. This would result in a
830 * lock reversal. Better performance might be obtained by
831 * chaining all packets received, dropping the lock, and then
832 * calling if_input() on each one.
833 */
834 EP_UNLOCK(sc);
806 (*ifp->if_input) (ifp, top);
835 (*ifp->if_input) (ifp, top);
836 EP_LOCK(sc);
807 sc->top = 0;
837 sc->top = 0;
808 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
809 EP_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
838 EP_BUSY_WAIT;
839 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
810 return;
811
812out:
840 return;
841
842out:
813 EP_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
843 CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
814 if (sc->top) {
815 m_freem(sc->top);
816 sc->top = 0;
817#ifdef EP_LOCAL_STATS
818 sc->rx_no_mbuf++;
819#endif
820 }
821 EP_FSET(sc, F_RX_FIRST);
844 if (sc->top) {
845 m_freem(sc->top);
846 sc->top = 0;
847#ifdef EP_LOCAL_STATS
848 sc->rx_no_mbuf++;
849#endif
850 }
851 EP_FSET(sc, F_RX_FIRST);
822 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
823 EP_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
852 EP_BUSY_WAIT;
853 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
824}
825
826static int
827ep_ifmedia_upd(struct ifnet *ifp)
828{
829 struct ep_softc *sc = ifp->if_softc;
830 int i = 0, j;
831
832 GO_WINDOW(0);
854}
855
856static int
857ep_ifmedia_upd(struct ifnet *ifp)
858{
859 struct ep_softc *sc = ifp->if_softc;
860 int i = 0, j;
861
862 GO_WINDOW(0);
833 EP_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
863 CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
834 GO_WINDOW(4);
864 GO_WINDOW(4);
835 EP_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
865 CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
836 GO_WINDOW(0);
837
838 switch (IFM_SUBTYPE(sc->ifmedia.ifm_media)) {
839 case IFM_10_T:
840 if (sc->ep_connectors & UTP) {
841 i = ACF_CONNECTOR_UTP;
842 GO_WINDOW(4);
866 GO_WINDOW(0);
867
868 switch (IFM_SUBTYPE(sc->ifmedia.ifm_media)) {
869 case IFM_10_T:
870 if (sc->ep_connectors & UTP) {
871 i = ACF_CONNECTOR_UTP;
872 GO_WINDOW(4);
843 EP_WRITE_2(sc, EP_W4_MEDIA_TYPE, ENABLE_UTP);
873 CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, ENABLE_UTP);
844 }
845 break;
846 case IFM_10_2:
847 if (sc->ep_connectors & BNC) {
848 i = ACF_CONNECTOR_BNC;
874 }
875 break;
876 case IFM_10_2:
877 if (sc->ep_connectors & BNC) {
878 i = ACF_CONNECTOR_BNC;
849 EP_WRITE_2(sc, EP_COMMAND, START_TRANSCEIVER);
879 CSR_WRITE_2(sc, EP_COMMAND, START_TRANSCEIVER);
850 DELAY(DELAY_MULTIPLE * 1000);
851 }
852 break;
853 case IFM_10_5:
854 if (sc->ep_connectors & AUI)
855 i = ACF_CONNECTOR_AUI;
856 break;
857 default:
858 i = sc->ep_connector;
859 device_printf(sc->dev,
860 "strange connector type in EEPROM: assuming AUI\n");
861 }
862
863 GO_WINDOW(0);
880 DELAY(DELAY_MULTIPLE * 1000);
881 }
882 break;
883 case IFM_10_5:
884 if (sc->ep_connectors & AUI)
885 i = ACF_CONNECTOR_AUI;
886 break;
887 default:
888 i = sc->ep_connector;
889 device_printf(sc->dev,
890 "strange connector type in EEPROM: assuming AUI\n");
891 }
892
893 GO_WINDOW(0);
864 j = EP_READ_2(sc, EP_W0_ADDRESS_CFG) & 0x3fff;
865 EP_WRITE_2(sc, EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
894 j = CSR_READ_2(sc, EP_W0_ADDRESS_CFG) & 0x3fff;
895 CSR_WRITE_2(sc, EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
866
867 return (0);
868}
869
870static void
871ep_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
872{
873 struct ep_softc *sc = ifp->if_softc;
874
875 ifmr->ifm_active = sc->ifmedia.ifm_media;
876}
877
878static int
896
897 return (0);
898}
899
900static void
901ep_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
902{
903 struct ep_softc *sc = ifp->if_softc;
904
905 ifmr->ifm_active = sc->ifmedia.ifm_media;
906}
907
908static int
879ep_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
909epioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
880{
881 struct ep_softc *sc = ifp->if_softc;
882 struct ifreq *ifr = (struct ifreq *) data;
910{
911 struct ep_softc *sc = ifp->if_softc;
912 struct ifreq *ifr = (struct ifreq *) data;
883 int s, error = 0;
913 int error = 0;
884
914
885 s = splimp();
886
887 switch (cmd) {
888 case SIOCSIFFLAGS:
915 switch (cmd) {
916 case SIOCSIFFLAGS:
917 EP_LOCK(sc);
889 if (((ifp->if_flags & IFF_UP) == 0) &&
890 (ifp->if_flags & IFF_RUNNING)) {
891 ifp->if_flags &= ~IFF_RUNNING;
892 epstop(sc);
893 } else
894 /* reinitialize card on any parameter change */
918 if (((ifp->if_flags & IFF_UP) == 0) &&
919 (ifp->if_flags & IFF_RUNNING)) {
920 ifp->if_flags &= ~IFF_RUNNING;
921 epstop(sc);
922 } else
923 /* reinitialize card on any parameter change */
895 ep_if_init(sc);
924 epinit_body(sc);
925 EP_UNLOCK(sc);
896 break;
897#ifdef notdef
898 case SIOCGHWADDR:
899 bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data,
900 sizeof(sc->sc_addr));
901 break;
902#endif
903 case SIOCADDMULTI:

--- 13 unchanged lines hidden (view full) ---

917 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
918 else
919 error = EINVAL;
920 break;
921 default:
922 error = ether_ioctl(ifp, cmd, data);
923 break;
924 }
926 break;
927#ifdef notdef
928 case SIOCGHWADDR:
929 bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data,
930 sizeof(sc->sc_addr));
931 break;
932#endif
933 case SIOCADDMULTI:

--- 13 unchanged lines hidden (view full) ---

947 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
948 else
949 error = EINVAL;
950 break;
951 default:
952 error = ether_ioctl(ifp, cmd, data);
953 break;
954 }
925
926 (void)splx(s);
927
928 return (error);
929}
930
931static void
955 return (error);
956}
957
958static void
932ep_if_watchdog(struct ifnet *ifp)
959epwatchdog(struct ifnet *ifp)
933{
934 struct ep_softc *sc = ifp->if_softc;
935
960{
961 struct ep_softc *sc = ifp->if_softc;
962
936/*
937 printf("ep: watchdog\n");
938
939 log(LOG_ERR, "ep%d: watchdog\n", ifp->if_unit);
940 ifp->if_oerrors++;
941*/
942
943 if (sc->gone)
944 return;
945 ifp->if_flags &= ~IFF_OACTIVE;
963 if (sc->gone)
964 return;
965 ifp->if_flags &= ~IFF_OACTIVE;
946 ep_if_start(ifp);
966 epstart(ifp);
947 ep_intr(ifp->if_softc);
948}
949
950static void
951epstop(struct ep_softc *sc)
952{
953 if (sc->gone)
954 return;
967 ep_intr(ifp->if_softc);
968}
969
970static void
971epstop(struct ep_softc *sc)
972{
973 if (sc->gone)
974 return;
955 EP_WRITE_2(sc, EP_COMMAND, RX_DISABLE);
956 EP_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
957 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
975 CSR_WRITE_2(sc, EP_COMMAND, RX_DISABLE);
976 CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
977 EP_BUSY_WAIT;
958
978
959 EP_WRITE_2(sc, EP_COMMAND, TX_DISABLE);
960 EP_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
979 CSR_WRITE_2(sc, EP_COMMAND, TX_DISABLE);
980 CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
961 DELAY(800);
962
981 DELAY(800);
982
963 EP_WRITE_2(sc, EP_COMMAND, RX_RESET);
964 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
965 EP_WRITE_2(sc, EP_COMMAND, TX_RESET);
966 while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
983 CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
984 EP_BUSY_WAIT;
985 CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
986 EP_BUSY_WAIT;
967
987
968 EP_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH);
969 EP_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK);
970 EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);
971 EP_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER);
988 CSR_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH);
989 CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK);
990 CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);
991 CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER);
972}
992}