Deleted Added
sdiff udiff text old ( 52632 ) new ( 55723 )
full compact
1/*-
2 * Copyright (c) 1998, 1999 Scott Mitchell
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

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

19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: if_xe.c,v 1.20 1999/06/13 19:17:40 scott Exp $
27 * $FreeBSD: head/sys/dev/xe/if_xe.c 52632 1999-10-29 17:28:09Z imp $
28 */
29
30/*
31 * Portions of this software were derived from Werner Koch's xirc2ps driver
32 * for Linux under the terms of the following license (from v1.30 of the
33 * xirc2ps driver):
34 *
35 * Copyright (c) 1997 by Werner Koch (dd9jn)
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions

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

98 * Author email: <scott@uk.freebsd.org>
99 */
100
101
102#ifndef XE_DEBUG
103#define XE_DEBUG 1 /* Increase for more voluminous output! */
104#endif
105
106#include "xe.h"
107#include "card.h"
108#include "apm.h"
109
110#if NXE > 0
111
112#undef NCARD
113#define NCARD 0
114#if NCARD > 0
115
116#include <sys/param.h>
117#include <sys/cdefs.h>
118#include <sys/errno.h>
119#include <sys/kernel.h>
120#include <sys/malloc.h>
121#include <sys/mbuf.h>
122#include <sys/select.h>
123#include <sys/socket.h>
124#include <sys/sockio.h>
125#include <sys/systm.h>
126#include <sys/uio.h>
127#include <sys/conf.h>
128
129#include <net/ethernet.h>
130#include <net/if.h>
131#include <net/if_arp.h>
132#include <net/if_dl.h>
133#include <net/if_media.h>
134#include <net/if_mib.h>
135#include <net/bpf.h>
136
137#include <i386/isa/isa.h>
138#include <i386/isa/isa_device.h>
139#include <dev/pccard/if_xereg.h>
140#include <machine/clock.h>
141#if NAPM > 0
142#include <machine/apm_bios.h>
143#endif /* NAPM > 0 */
144
145#include <pccard/cardinfo.h>
146#include <pccard/cis.h>
147#include <pccard/driver.h>
148#include <pccard/slot.h>
149
150
151
152/*
153 * One of these structures per allocated device
154 */
155struct xe_softc {
156 struct arpcom arpcom;
157 struct ifmedia ifmedia;
158 struct ifmib_iso_8802_3 mibdata;
159 struct callout_handle chand;
160 struct isa_device *dev;
161 struct pccard_devinfo *crd;
162 struct ifnet *ifp;
163 struct ifmedia *ifm;
164 char *card_type; /* Card model name */
165 char *vendor; /* Card manufacturer */
166 int unit; /* Unit number, from dev->id_unit */
167 int srev; /* Silicon revision */
168 int tx_queued; /* Packets currently waiting to transmit */
169 int tx_tpr; /* Last value of TPR reg on card */
170 int tx_collisions; /* Collisions since last successful send */
171 int tx_timeouts; /* Count of transmit timeouts */
172 int autoneg_status; /* Autonegotiation progress state */
173 int media; /* Private media word */
174 u_char version; /* Bonding Version register from card */
175 u_char modem; /* 1 = Card has a modem */
176 u_char ce2; /* 1 = Card has CE2 silicon */
177 u_char mohawk; /* 1 = Card has Mohawk (CE3) silicon */
178 u_char dingo; /* 1 = Card has Dingo (CEM56) silicon */
179 u_char phy_ok; /* 1 = MII-compliant PHY found and initialised */
180 u_char gone; /* 1 = Card bailed out */
181#if NAPM > 0
182 struct apmhook suspend_hook;
183 struct apmhook resume_hook;
184#endif /* NAPM > 0 */
185};
186
187static struct xe_softc *sca[MAXSLOT];
188
189
190/*
191 * MII command structure
192 */
193struct xe_mii_frame {
194 u_int8_t mii_stdelim;
195 u_int8_t mii_opcode;
196 u_int8_t mii_phyaddr;
197 u_int8_t mii_regaddr;
198 u_int8_t mii_turnaround;
199 u_int16_t mii_data;
200};
201
202/*
203 * For accessing card registers
204 */
205#define XE_INB(r) inb(scp->dev->id_iobase+(r))
206#define XE_INW(r) inw(scp->dev->id_iobase+(r))
207#define XE_OUTB(r, b) outb(scp->dev->id_iobase+(r), (b))
208#define XE_OUTW(r, w) outw(scp->dev->id_iobase+(r), (w))
209#define XE_SELECT_PAGE(p) XE_OUTB(XE_PR, (p))
210
211/*
212 * Horrid stuff for accessing CIS tuples
213 */
214#define CARD_MAJOR 50
215#define CISTPL_BUFSIZE 512
216#define CISTPL_TYPE(tpl) tpl[0]
217#define CISTPL_LEN(tpl) tpl[2]
218#define CISTPL_DATA(tpl,pos) tpl[4 + ((pos)<<1)]
219
220/*
221 * Media autonegotiation progress constants
222 */
223#define XE_AUTONEG_NONE 0 /* No autonegotiation in progress */
224#define XE_AUTONEG_WAITING 1 /* Waiting for transmitter to go idle */
225#define XE_AUTONEG_STARTED 2 /* Waiting for autonegotiation to complete */
226#define XE_AUTONEG_100TX 3 /* Trying to force 100baseTX link */
227#define XE_AUTONEG_FAIL 4 /* Autonegotiation failed */
228
229
230/*
231 * Prototypes start here
232 */
233static int xe_probe (struct isa_device *dev);
234static int xe_card_init (struct pccard_devinfo *devi);
235static int xe_attach (struct isa_device *dev);
236static void xe_init (void *xscp);
237static void xe_start (struct ifnet *ifp);
238static int xe_ioctl (struct ifnet *ifp, u_long command, caddr_t data);
239static int xe_card_intr (struct pccard_devinfo *devi);
240static void xe_watchdog (struct ifnet *ifp);
241static int xe_media_change (struct ifnet *ifp);
242static void xe_media_status (struct ifnet *ifp, struct ifmediareq *mrp);
243static timeout_t xe_setmedia;
244static void xe_hard_reset (struct xe_softc *scp);
245static void xe_soft_reset (struct xe_softc *scp);
246static void xe_stop (struct xe_softc *scp);
247static void xe_enable_intr (struct xe_softc *scp);
248static void xe_disable_intr (struct xe_softc *scp);
249static void xe_setmulti (struct xe_softc *scp);
250static void xe_setaddrs (struct xe_softc *scp);
251static int xe_pio_write_packet (struct xe_softc *scp, struct mbuf *mbp);
252static void xe_card_unload (struct pccard_devinfo *devi);
253static u_int32_t xe_compute_crc (u_int8_t *data, int len);
254static int xe_compute_hashbit (u_int32_t crc);
255
256/*
257 * MII functions
258 */
259static void xe_mii_sync (struct xe_softc *scp);
260static int xe_mii_init (struct xe_softc *scp);

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

272#define XE_MII_DUMP(scp) xe_mii_dump((scp))
273static void xe_reg_dump (struct xe_softc *scp);
274static void xe_mii_dump (struct xe_softc *scp);
275#else
276#define XE_REG_DUMP(scp)
277#define XE_MII_DUMP(scp)
278#endif
279
280#if NAPM > 0
281/*
282 * APM hook functions
283 */
284static int xe_suspend (void *xunit);
285static int xe_resume (void *xunit);
286#endif /* NAPM > 0 */
287
288
289/*
290 * PCMCIA driver hooks
291 */
292#ifdef PCCARD_MODULE
293PCCARD_MODULE(xe, xe_card_init, xe_card_unload, xe_card_intr, 0, net_imask);
294#else
295static struct pccard_device xe_info = { /* For pre 3.1-STABLE code */
296 "xe",
297 xe_card_init,
298 xe_card_unload,
299 xe_card_intr,
300 0,
301 &net_imask
302};
303DATA_SET(pccarddrv_set, xe_info);
304#endif /* PCCARD_MODULE */
305
306
307/*
308 * ISA driver hooks. I'd like to do without these but the kernel config stuff
309 * seems to require them.
310 */
311struct isa_driver xedriver = {
312 xe_probe,
313 xe_attach,
314 "xe"
315};
316
317
318
319/*
320 * ISA probe routine.
321 * All of the supported devices are PCMCIA cards. I have no idea if it's even
322 * possible to successfully probe/attach these at boot time (pccardd normally
323 * does a lot of setup work) so I don't even bother trying.
324 */
325static int
326xe_probe (struct isa_device *dev) {
327#ifdef XE_DEBUG
328 printf("xe%d: probe\n", dev->id_unit);
329#endif
330 bzero(sca, MAXSLOT * sizeof(sca[0]));
331 return 0;
332}
333
334
335/*
336 * Two routines to read from/write to the attribute memory
337 * the write portion is used only for fixing up the RealPort cards,
338 * the reader portion was needed for debugging info, and duplicated some
339 * code in xe_card_init(), so it appears here instead with suitable
340 * modifications to xe_card_init()
341 * -aDe Lovett
342 */
343static int
344xe_memwrite(struct pccard_devinfo *devi, off_t offset, u_char byte)
345{
346 struct iovec iov;
347 struct uio uios;
348
349 iov.iov_base = &byte;
350 iov.iov_len = sizeof(byte);
351
352 uios.uio_iov = &iov;
353 uios.uio_iovcnt = 1;
354 uios.uio_offset = offset;
355 uios.uio_resid = sizeof(byte);
356 uios.uio_segflg = UIO_SYSSPACE;
357 uios.uio_rw = UIO_WRITE;
358 uios.uio_procp = 0;
359
360#if 0 /* THIS IS BOGUS */
361 return cdevsw[CARD_MAJOR]->d_write(makedev(CARD_MAJOR, devi->slt->slotnum), &uios, 0);
362#else
363 return (-1);
364#endif
365}
366
367
368static int
369xe_memread(struct pccard_devinfo *devi, off_t offset, u_char *buf, int size)
370{
371 struct iovec iov;
372 struct uio uios;
373
374 iov.iov_base = buf;
375 iov.iov_len = size;
376
377 uios.uio_iov = &iov;
378 uios.uio_iovcnt = 1;
379 uios.uio_offset = offset;
380 uios.uio_resid = size;
381 uios.uio_segflg = UIO_SYSSPACE;
382 uios.uio_rw = UIO_READ;
383 uios.uio_procp = 0;
384
385#if 0 /* THIS IS BOGUS */
386 return cdevsw[CARD_MAJOR]->d_read(makedev(CARD_MAJOR, devi->slt->slotnum), &uios, 0);
387#else
388 return (-1);
389#endif
390}
391
392
393/*
394 * Hacking for RealPort cards
395 */
396static int
397xe_cem56fix(struct xe_softc *scp)
398{
399 struct pccard_devinfo *devi;
400 struct slot *slt;
401 struct slot_ctrl *ctrl;
402 int ioport, fail;
403
404 /* initialise a few variables */
405 devi = scp->crd;
406 slt = devi->slt;
407 ctrl = slt->ctrl;
408
409 /* allocate a new I/O slot for the ethernet */
410 /* XXX: ctrl->mapio() always appears to return 0 (success), so
411 * this may cause problems if another device is listening
412 * on 0x300 already. In this case, you should choose a
413 * known free I/O port address in the kernel config line
414 * for the driver. It will be picked up here and used
415 * instead of the autodetected value.
416 */
417 slt->io[1].window = 1;
418 slt->io[1].flags = IODF_WS|IODF_16BIT|IODF_ZEROWS|IODF_ACTIVE;
419 slt->io[1].size = 0x10;
420
421#ifdef XE_IOBASE
422
423 printf( "xe%d: user requested ioport 0x%x\n", scp->unit, XE_IOBASE );
424 ioport = XE_IOBASE;
425 slt->io[1].start = ioport;
426 fail = ctrl->mapio(slt, 1);
427
428#else
429
430 for (ioport = 0x300; ioport < 0x400; ioport += 0x10) {
431 slt->io[1].start = ioport;
432 if ((fail = ctrl->mapio( slt, 1 )) == 0)
433 break;
434 }
435
436#endif
437
438 /* did we find one? */
439 if (fail) {
440 printf( "xe%d: xe_cem56fix: no free address space\n", scp->unit );
441 return -1;
442 }
443
444
445 /* munge the id_iobase entry for use by the rest of the driver */
446#if XE_DEBUG > 1
447 printf( "xe%d: using 0x%x for RealPort ethernet\n", scp->unit, ioport );
448#endif
449 scp->dev->id_iobase = ioport;
450 scp->dev->id_alive = 0x10;
451
452 /* magic to set up the ethernet */
453 xe_memwrite( devi, DINGO_ECOR, DINGO_ECOR_IRQ_LEVEL|DINGO_ECOR_INT_ENABLE|
454 DINGO_ECOR_IOB_ENABLE|DINGO_ECOR_ETH_ENABLE );
455 xe_memwrite( devi, DINGO_EBAR0, ioport & 0xff );
456 xe_memwrite( devi, DINGO_EBAR1, (ioport >> 8) & 0xff );
457
458 xe_memwrite( devi, DINGO_DCOR0, DINGO_DCOR0_SF_INT );
459 xe_memwrite( devi, DINGO_DCOR1, DINGO_DCOR1_INT_LEVEL|DINGO_DCOR1_EEDIO );
460 xe_memwrite( devi, DINGO_DCOR2, 0x00 );
461 xe_memwrite( devi, DINGO_DCOR3, 0x00 );
462 xe_memwrite( devi, DINGO_DCOR4, 0x00 );
463
464 /* success! */
465 return 0;
466}
467
468
469/*
470 * PCMCIA probe routine.
471 * Probe and identify the device. Called by the slot manager when the card is
472 * inserted or the machine wakes up from suspend mode. Assmes that the slot
473 * structure has been initialised already.
474 */
475static int
476xe_card_init(struct pccard_devinfo *devi)
477{
478 struct xe_softc *scp;
479 struct isa_device *dev;
480 u_char buf[CISTPL_BUFSIZE];
481 u_char ver_str[CISTPL_BUFSIZE>>1];
482 off_t offs;
483 int unit, success, rc, i;
484
485 unit = devi->isahd.id_unit;
486 scp = sca[unit];
487 dev = &devi->isahd;
488 success = 0;
489
490#ifdef XE_DEBUG
491 printf("xe: Probing for unit %d\n", unit);
492#endif
493
494 /* Check that unit number is OK */
495 if (unit > MAXSLOT) {
496 printf("xe%d: bad unit\n", unit);
497 return (ENODEV);
498 }
499
500 /* Don't attach an active device */
501 if (scp && !scp->gone) {
502 printf("xe%d: already attached\n", unit);
503 return (EBUSY);
504 }
505
506 /* Allocate per-instance storage */
507 if (!scp) {
508 if ((scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT)) == NULL) {
509 printf("xe%d: failed to allocage driver storage\n", unit);
510 return (ENOMEM);
511 }
512 bzero(scp, sizeof(*scp));
513 }
514
515 /* Re-attach an existing device */
516 if (scp->gone) {
517 scp->gone = 0;
518 return 0;
519 }
520
521 /* Grep through CIS looking for relevant tuples */
522 offs = 0;
523 do {
524 u_int16_t vendor;
525 u_int8_t rev, media, prod;
526
527 /*
528 * Read tuples one at a time into buf. Sucks, but it only happens once.
529 * XXX - This assumes that attribute has been mapped by pccardd, which
530 * XXX - seems to be the default situation. If not, we're well and truly
531 * XXX - FUBAR. This is a general PCCARD problem, not our fault :)
532 */
533 if ((rc = xe_memread( devi, offs, buf, CISTPL_BUFSIZE )) == 0) {
534
535 switch (CISTPL_TYPE(buf)) {
536
537 case 0x15: /* Grab version string (needed to ID some weird CE2's) */
538#if XE_DEBUG > 1
539 printf("xe%d: Got version string (0x15)\n", unit);
540#endif
541 for (i = 0; i < CISTPL_LEN(buf); ver_str[i] = CISTPL_DATA(buf, i++));
542 ver_str[i] = '\0';
543 ver_str[(CISTPL_BUFSIZE>>1) - 1] = CISTPL_LEN(buf);
544 success++;
545 break;
546
547 case 0x20: /* Figure out what type of card we have */
548#if XE_DEBUG > 1
549 printf("xe%d: Got card ID (0x20)\n", unit);
550#endif
551 vendor = CISTPL_DATA(buf, 0) + (CISTPL_DATA(buf, 1) << 8);
552 rev = CISTPL_DATA(buf, 2);
553 media = CISTPL_DATA(buf, 3);
554 prod = CISTPL_DATA(buf, 4);
555
556 switch (vendor) { /* Get vendor ID */
557 case 0x0105:
558 scp->vendor = "Xircom"; break;
559 case 0x0138:
560 case 0x0183:
561 scp->vendor = "Compaq"; break;
562 case 0x0089:
563 scp->vendor = "Intel"; break;
564 default:
565 scp->vendor = "Unknown";
566 }
567
568 if (!((prod & 0x40) && (media & 0x01))) {
569#if XE_DEBUG > 1
570 printf("xe%d: Not a PCMCIA Ethernet card!\n", unit);
571#endif
572 rc = ENODEV; /* Not a PCMCIA Ethernet device */
573 }
574 else {
575 if (media & 0x10) { /* Ethernet/modem cards */
576#if XE_DEBUG > 1
577 printf("xe%d: Card is Ethernet/modem combo\n", unit);
578#endif
579 scp->modem = 1;
580 switch (prod & 0x0f) {
581 case 1:
582 scp->card_type = "CEM"; break;
583 case 2:
584 scp->ce2 = 1;
585 scp->card_type = "CEM2"; break;
586 case 3:
587 scp->ce2 = 1;
588 scp->card_type = "CEM3"; break;
589 case 4:
590 scp->ce2 = 1;
591 scp->card_type = "CEM33"; break;
592 case 5:
593 scp->mohawk = 1;
594 scp->card_type = "CEM56M"; break;
595 case 6:
596 case 7: /* Some kind of RealPort card */
597 scp->mohawk = 1;
598 scp->dingo = 1;
599 scp->card_type = "CEM56"; break;
600 default:
601 rc = ENODEV;
602 }
603 }
604 else { /* Ethernet-only cards */
605#if XE_DEBUG > 1
606 printf("xe%d: Card is Ethernet only\n", unit);
607#endif
608 switch (prod & 0x0f) {
609 case 1:
610 scp->card_type = "CE"; break;
611 case 2:
612 scp->ce2 = 1;
613 scp->card_type = "CE2"; break;
614 case 3:
615 scp->mohawk = 1;
616 scp->card_type = "CE3"; break;
617 default:
618 rc = ENODEV;
619 }
620 }
621 }
622 success++;
623 break;
624
625 case 0x22: /* Get MAC address */
626 if ((CISTPL_LEN(buf) == 8) &&
627 (CISTPL_DATA(buf, 0) == 0x04) &&
628 (CISTPL_DATA(buf, 1) == ETHER_ADDR_LEN)) {
629#if XE_DEBUG > 1
630 printf("xe%d: Got MAC address (0x22)\n", unit);
631#endif
632 for (i = 0; i < ETHER_ADDR_LEN; scp->arpcom.ac_enaddr[i] = CISTPL_DATA(buf, i+2), i++);
633 }
634 success++;
635 break;
636 default:
637 }
638 }
639
640 /* Skip to next tuple */
641 offs += ((CISTPL_LEN(buf) + 2) << 1);
642
643 } while ((CISTPL_TYPE(buf) != 0xff) && (CISTPL_LEN(buf) != 0xff) && (rc == 0));
644
645
646 /* Die now if something went wrong above */
647 if ((rc != 0) || (success < 3)) {
648 free(scp, M_DEVBUF);
649 return rc;
650 }
651
652 /* Check for certain strange CE2's that look like CE's */
653 if (strcmp(scp->card_type, "CE") == 0) {
654 u_char *str = ver_str;
655#if XE_DEBUG > 1
656 printf("xe%d: Checking for weird CE2 string\n", unit);
657#endif
658 str += strlen(str) + 1; /* Skip forward to 3rd version string */
659 str += strlen(str) + 1;
660 str += strlen(str) + 1;
661 for (i = 0; i < strlen(str) - 2; i++) {
662 if (bcmp(&str[i], "CE2", 3) ==0) { /* Look for "CE2" string */
663 scp->card_type = "CE2";
664 }
665 }
666 }
667
668 /* Reject unsupported cards */
669 if (strcmp(scp->card_type, "CE") == 0 || strcmp(scp->card_type, "CEM") == 0) {
670 printf("xe%d: Sorry, your %s card is not supported :(\n", unit, scp->card_type);
671 free(scp, M_DEVBUF);
672 return ENODEV;
673 }
674
675 /* Fill in some private data */
676 sca[unit] = scp;
677 scp->dev = &devi->isahd;
678 scp->crd = devi;
679 scp->ifp = &scp->arpcom.ac_if;
680 scp->ifm = &scp->ifmedia;
681 scp->unit = unit;
682 scp->autoneg_status = 0;
683
684 /* Hack RealPorts into submission */
685 if (scp->dingo && xe_cem56fix(scp) < 0) {
686 printf( "xe%d: Unable to fix your RealPort\n", unit );
687 sca[unit] = 0;
688 free(scp, M_DEVBUF);
689 return ENODEV;
690 }
691
692 /* Hopefully safe to read this here */
693 XE_SELECT_PAGE(4);
694 scp->version = XE_INB(XE_BOV);
695
696 /* Attempt to attach the device */
697 if (!xe_attach(scp->dev)) {
698 sca[unit] = 0;
699 free(scp, M_DEVBUF);
700 return ENXIO;
701 }
702
703#if NAPM > 0
704 /* Establish APM hooks once device attached */
705 scp->suspend_hook.ah_name = "xe_suspend";
706 scp->suspend_hook.ah_fun = xe_suspend;
707 scp->suspend_hook.ah_arg = (void *)unit;
708 scp->suspend_hook.ah_order = APM_MIN_ORDER;
709 apm_hook_establish(APM_HOOK_SUSPEND, &scp->suspend_hook);
710 scp->resume_hook.ah_name = "xe_resume";
711 scp->resume_hook.ah_fun = xe_resume;
712 scp->resume_hook.ah_arg = (void *)unit;
713 scp->resume_hook.ah_order = APM_MIN_ORDER;
714 apm_hook_establish(APM_HOOK_RESUME, &scp->resume_hook);
715#endif /* NAPM > 0 */
716
717 /* Success */
718 return 0;
719}
720
721
722/*
723 * Attach a device (called when xe_card_init succeeds). Assume that the probe
724 * routine has set up the softc structure correctly and that we can trust the
725 * unit number.
726 */
727static int
728xe_attach (struct isa_device *dev) {
729 struct xe_softc *scp = sca[dev->id_unit];
730 int i;
731
732#ifdef XE_DEBUG
733 printf("xe%d: attach\n", scp->unit);
734#endif
735
736 /* Initialise the ifnet structure */
737 if (!scp->ifp->if_name) {
738 scp->ifp->if_softc = scp;
739 scp->ifp->if_name = "xe";
740 scp->ifp->if_unit = scp->unit;
741 scp->ifp->if_timer = 0;
742 scp->ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
743 scp->ifp->if_linkmib = &scp->mibdata;
744 scp->ifp->if_linkmiblen = sizeof scp->mibdata;
745 scp->ifp->if_output = ether_output;
746 scp->ifp->if_start = xe_start;
747 scp->ifp->if_ioctl = xe_ioctl;
748 scp->ifp->if_watchdog = xe_watchdog;

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

768 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_2, 0, NULL);
769 }
770 ifmedia_add(scp->ifm, IFM_ETHER|IFM_AUTO, 0, NULL);
771
772 /* Default is to autoselect best supported media type */
773 ifmedia_set(scp->ifm, IFM_ETHER|IFM_AUTO);
774
775 /* Print some useful information */
776 printf("\n");
777 printf("xe%d: %s %s, bonding version %#x%s%s\n",
778 scp->unit,
779 scp->vendor,
780 scp->card_type,
781 scp->version,
782 scp->mohawk ? ", 100Mbps capable" : "",
783 scp->modem ? ", with modem" : "");
784 if (scp->mohawk) {
785 XE_SELECT_PAGE(0x10);
786 printf("xe%d: DingoID = %#x, RevisionID = %#x, VendorID = %#x\n",
787 scp->unit,
788 XE_INW(XE_DINGOID),
789 XE_INW(XE_RevID),
790 XE_INW(XE_VendorID));
791 }
792 if (scp->ce2) {
793 XE_SELECT_PAGE(0x45);
794 printf("xe%d: CE2 version = %#x\n",
795 scp->unit,
796 XE_INB(XE_REV));
797 }
798
799 /* Print MAC address */
800 printf("xe%d: Ethernet address %02x", scp->unit, scp->arpcom.ac_enaddr[0]);
801 for (i = 1; i < ETHER_ADDR_LEN; i++) {
802 printf(":%02x", scp->arpcom.ac_enaddr[i]);
803 }
804 printf("\n");
805
806 /* Attach the interface */
807 if_attach(scp->ifp);
808 ether_ifattach(scp->ifp);
809
810 /* If BPF is in the kernel, call the attach for it */
811#if XE_DEBUG > 1
812 printf("xe%d: BPF listener attached\n", scp->unit);
813#endif
814 bpfattach(scp->ifp, DLT_EN10MB, sizeof(struct ether_header));
815
816 /* Done */
817 return 1;
818}
819
820
821/*
822 * Initialize device. Completes the reset procedure on the card and starts
823 * output. If there's an autonegotiation in progress we DON'T do anything;
824 * the media selection code will call us again when it's done.
825 */
826static void
827xe_init(void *xscp) {
828 struct xe_softc *scp = xscp;
829 int s;
830
831#ifdef XE_DEBUG
832 printf("xe%d: init\n", scp->unit);
833#endif
834
835 if (scp->gone) return;
836
837 if (TAILQ_EMPTY(&scp->ifp->if_addrhead)) return;
838
839 /* Reset transmitter flags */
840 scp->tx_queued = 0;
841 scp->tx_tpr = 0;
842 scp->tx_collisions = 0;
843 scp->ifp->if_timer = 0;
844

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

910 * 2) that the IFF_OACTIVE flag is checked before this code is called
911 * (i.e. that the output part of the interface is idle)
912 */
913static void
914xe_start(struct ifnet *ifp) {
915 struct xe_softc *scp = ifp->if_softc;
916 struct mbuf *mbp;
917
918 if (scp->gone) return;
919
920 /*
921 * Loop while there are packets to be sent, and space to send them.
922 */
923 while (1) {
924 IF_DEQUEUE(&ifp->if_snd, mbp); /* Suck a packet off the send queue */
925
926 if (mbp == NULL) {
927 /*

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

939 IF_PREPEND(&ifp->if_snd, mbp); /* Push the packet back onto the queue */
940 ifp->if_flags |= IFF_OACTIVE;
941 return;
942 }
943
944 /* Tap off here if there is a bpf listener */
945 if (ifp->if_bpf) {
946#if XE_DEBUG > 1
947 printf("xe%d: sending output packet to BPF\n", scp->unit);
948#endif
949 bpf_mtap(ifp, mbp);
950 }
951
952 ifp->if_timer = 5; /* In case we don't hear from the card again */
953 scp->tx_queued++;
954
955 m_freem(mbp);

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

963static int
964xe_ioctl (register struct ifnet *ifp, u_long command, caddr_t data) {
965 struct xe_softc *scp;
966 int s, error;
967
968 scp = ifp->if_softc;
969 error = 0;
970
971 if (scp->gone) {
972 return ENXIO;
973 }
974
975 s = splimp();
976
977 switch (command) {
978
979 case SIOCSIFADDR:
980 case SIOCGIFADDR:
981 case SIOCSIFMTU:
982 error = ether_ioctl(ifp, command, data);

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

1024
1025 (void)splx(s);
1026
1027 return error;
1028}
1029
1030
1031/*
1032 * Card interrupt handler: should return true if the interrupt was for us, in
1033 * case we are sharing our IRQ line with other devices (this will probably be
1034 * the case for multifunction cards).
1035 *
1036 * This function is probably more complicated than it needs to be, as it
1037 * attempts to deal with the case where multiple packets get sent between
1038 * interrupts. This is especially annoying when working out the collision
1039 * stats. Not sure whether this case ever really happens or not (maybe on a
1040 * slow/heavily loaded machine?) so it's probably best to leave this like it
1041 * is.
1042 *
1043 * Note that the crappy PIO used to get packets on and off the card means that
1044 * you will spend a lot of time in this routine -- I can get my P150 to spend
1045 * 90% of its time servicing interrupts if I really hammer the network. Could
1046 * fix this, but then you'd start dropping/losing packets. The moral of this
1047 * story? If you want good network performance _and_ some cycles left over to
1048 * get your work done, don't buy a Xircom card. Or convince them to tell me
1049 * how to do memory-mapped I/O :)
1050 */
1051static int
1052xe_card_intr(struct pccard_devinfo *devi) {
1053 struct xe_softc *scp;
1054 struct ifnet *ifp;
1055 int unit, result;
1056 u_int16_t rx_bytes, rxs, txs;
1057 u_int8_t psr, isr, esr, rsr;
1058
1059 unit = devi->isahd.id_unit;
1060 scp = sca[unit];
1061 ifp = &scp->arpcom.ac_if;
1062 rx_bytes = 0; /* Bytes received on this interrupt */
1063 result = 0; /* Set true if the interrupt is for us */
1064
1065 if (scp->gone)
1066 return 0;
1067
1068 if (scp->mohawk) {
1069 XE_OUTB(XE_CR, 0); /* Disable interrupts */
1070 }
1071
1072 psr = XE_INB(XE_PR); /* Stash the current register page */
1073
1074 /*
1075 * Read ISR to see what caused this interrupt. Note that this clears the

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

1251 ((char *)ehp)[i] = XE_INB(XE_EDP);
1252 if (rhs == 0x8000) {
1253 rhs = 0;
1254 i--;
1255 }
1256 }
1257 }
1258 else
1259 insw(scp->dev->id_iobase+XE_EDP, ehp, len >> 1);
1260 }
1261 else
1262 insw(scp->dev->id_iobase+XE_EDP, ehp, len >> 1);
1263
1264 /*
1265 * Check if there's a BPF listener on this interface. If so, hand
1266 * off the raw packet to bpf.
1267 */
1268 if (ifp->if_bpf) {
1269#if XE_DEBUG > 1
1270 printf("xe%d: passing input packet to BPF\n", scp->unit);
1271#endif
1272 bpf_mtap(ifp, mbp);
1273
1274 /*
1275 * Note that the interface cannot be in promiscuous mode if there
1276 * are no BPF listeners. And if we are in promiscuous mode, we
1277 * have to check if this packet is really ours.
1278 */

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

1314 }
1315
1316 XE_SELECT_PAGE(psr); /* Restore saved page */
1317 XE_OUTB(XE_CR, XE_CR_ENABLE_INTR); /* Re-enable interrupts */
1318
1319 /* Could force an int here, instead of dropping packets? */
1320 /* XE_OUTB(XE_CR, XE_CR_ENABLE_INTR|XE_CE_FORCE_INTR); */
1321
1322 return result;
1323}
1324
1325
1326/*
1327 * Device timeout/watchdog routine. Called automatically if we queue a packet
1328 * for transmission but don't get an interrupt within a specified timeout
1329 * (usually 5 seconds). When this happens we assume the worst and reset the
1330 * card.
1331 */
1332static void
1333xe_watchdog(struct ifnet *ifp) {
1334 struct xe_softc *scp = ifp->if_softc;
1335
1336 if (scp->gone) return;
1337
1338 printf("xe%d: watchdog timeout; resetting card\n", scp->unit);
1339 scp->tx_timeouts++;
1340 ifp->if_oerrors += scp->tx_queued;
1341 xe_stop(scp);
1342 xe_hard_reset(scp);
1343 xe_setmedia(scp);
1344 xe_init(scp);
1345}
1346

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

1391/*
1392 * Select active media.
1393 */
1394static void xe_setmedia(void *xscp) {
1395 struct xe_softc *scp = xscp;
1396 u_int16_t bmcr, bmsr, anar, lpar;
1397
1398#ifdef XE_DEBUG
1399 printf("xe%d: setmedia\n", scp->unit);
1400#endif
1401
1402 /* Cancel any pending timeout */
1403 untimeout(xe_setmedia, scp, scp->chand);
1404 xe_disable_intr(scp);
1405
1406 /* Select media */
1407 scp->media = IFM_ETHER;

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

1438 * Select 10baseT or 10base2, whichever is connected
1439 * ENDIF
1440 * ENDIF
1441 */
1442 switch (scp->autoneg_status) {
1443
1444 case XE_AUTONEG_NONE:
1445#if XE_DEBUG > 1
1446 printf("xe%d: Waiting for idle transmitter\n", scp->unit);
1447#endif
1448 scp->arpcom.ac_if.if_flags |= IFF_OACTIVE;
1449 scp->autoneg_status = XE_AUTONEG_WAITING;
1450 scp->chand = timeout(xe_setmedia, scp, hz * 2);
1451 return;
1452
1453 case XE_AUTONEG_WAITING:
1454 xe_soft_reset(scp);
1455 if (scp->phy_ok) {
1456#if XE_DEBUG > 1
1457 printf("xe%d: Starting autonegotiation\n", scp->unit);
1458#endif
1459 bmcr = xe_phy_readreg(scp, PHY_BMCR);
1460 bmcr &= ~(PHY_BMCR_AUTONEGENBL);
1461 xe_phy_writereg(scp, PHY_BMCR, bmcr);
1462 anar = xe_phy_readreg(scp, PHY_ANAR);
1463 anar &= ~(PHY_ANAR_100BT4|PHY_ANAR_100BTXFULL|PHY_ANAR_10BTFULL);
1464 anar |= PHY_ANAR_100BTXHALF|PHY_ANAR_10BTHALF;
1465 xe_phy_writereg(scp, PHY_ANAR, anar);

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

1474 }
1475 break;
1476
1477 case XE_AUTONEG_STARTED:
1478 bmsr = xe_phy_readreg(scp, PHY_BMSR);
1479 lpar = xe_phy_readreg(scp, PHY_LPAR);
1480 if (bmsr & (PHY_BMSR_AUTONEGCOMP|PHY_BMSR_LINKSTAT)) {
1481#if XE_DEBUG > 1
1482 printf("xe%d: Autonegotiation complete!\n", scp->unit);
1483#endif
1484 /*
1485 * XXX - Shouldn't have to do this, but (on my hub at least) the
1486 * XXX - transmitter won't work after a successful autoneg. So we see
1487 * XXX - what the negotiation result was and force that mode. I'm
1488 * XXX - sure there is an easy fix for this.
1489 */
1490 if (lpar & PHY_LPAR_100BTXHALF) {

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

1513 scp->autoneg_status = XE_AUTONEG_NONE;
1514 /* END HACK */
1515 /*XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08);*/ /* Disable PHY? */
1516 /*scp->autoneg_status = XE_AUTONEG_FAIL;*/
1517 }
1518 }
1519 else {
1520#if XE_DEBUG > 1
1521 printf("xe%d: Autonegotiation failed; trying 100baseTX\n", scp->unit);
1522#endif
1523 XE_MII_DUMP(scp);
1524 xe_soft_reset(scp);
1525 if (scp->phy_ok) {
1526 xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_SPEEDSEL);
1527 scp->autoneg_status = XE_AUTONEG_100TX;
1528 scp->chand = timeout(xe_setmedia, scp, hz * 3);
1529 return;

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

1534 }
1535 break;
1536
1537 case XE_AUTONEG_100TX:
1538 (void)xe_phy_readreg(scp, PHY_BMSR);
1539 bmsr = xe_phy_readreg(scp, PHY_BMSR);
1540 if (bmsr & PHY_BMSR_LINKSTAT) {
1541#if XE_DEBUG > 1
1542 printf("xe%d: Got 100baseTX link!\n", scp->unit);
1543#endif
1544 XE_MII_DUMP(scp);
1545 XE_SELECT_PAGE(2);
1546 XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08);
1547 scp->media = IFM_ETHER|IFM_100_TX;
1548 scp->autoneg_status = XE_AUTONEG_NONE;
1549 }
1550 else {
1551#if XE_DEBUG > 1
1552 printf("xe%d: Autonegotiation failed; disabling PHY\n", scp->unit);
1553#endif
1554 XE_MII_DUMP(scp);
1555 xe_phy_writereg(scp, PHY_BMCR, 0x0000);
1556 XE_SELECT_PAGE(2);
1557 XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08); /* Disable PHY? */
1558 scp->autoneg_status = XE_AUTONEG_FAIL;
1559 }
1560 break;
1561 }
1562
1563 /*
1564 * If we got down here _and_ autoneg_status is XE_AUTONEG_FAIL, then
1565 * either autonegotiation failed, or never got started to begin with. In
1566 * either case, select a suitable 10Mbit media and hope it works. We
1567 * don't need to reset the card again, since it will have been done
1568 * already by the big switch above.
1569 */
1570 if (scp->autoneg_status == XE_AUTONEG_FAIL) {
1571#if XE_DEBUG > 1
1572 printf("xe%d: Selecting 10baseX\n", scp->unit);
1573#endif
1574 if (scp->mohawk) {
1575 XE_SELECT_PAGE(0x42);
1576 XE_OUTB(XE_SWC1, 0x80);
1577 scp->media = IFM_ETHER|IFM_10_T;
1578 scp->autoneg_status = XE_AUTONEG_NONE;
1579 }
1580 else {

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

1594 * If a specific media has been requested, we just reset the card and
1595 * select it (one small exception -- if 100baseTX is requested by there is
1596 * no PHY, we fall back to 10baseT operation).
1597 */
1598 case IFM_100_TX: /* Force 100baseTX */
1599 xe_soft_reset(scp);
1600 if (scp->phy_ok) {
1601#if XE_DEBUG > 1
1602 printf("xe%d: Selecting 100baseTX\n", scp->unit);
1603#endif
1604 XE_SELECT_PAGE(0x42);
1605 XE_OUTB(XE_SWC1, 0);
1606 xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_SPEEDSEL);
1607 XE_SELECT_PAGE(2);
1608 XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08);
1609 scp->media |= IFM_100_TX;
1610 break;
1611 }
1612 /* FALLTHROUGH */
1613
1614 case IFM_10_T: /* Force 10baseT */
1615 xe_soft_reset(scp);
1616#if XE_DEBUG > 1
1617 printf("xe%d: Selecting 10baseT\n", scp->unit);
1618#endif
1619 if (scp->phy_ok) {
1620 xe_phy_writereg(scp, PHY_BMCR, 0x0000);
1621 XE_SELECT_PAGE(2);
1622 XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08); /* Disable PHY */
1623 }
1624 XE_SELECT_PAGE(0x42);
1625 XE_OUTB(XE_SWC1, 0x80);
1626 scp->media |= IFM_10_T;
1627 break;
1628
1629 case IFM_10_2:
1630 xe_soft_reset(scp);
1631#if XE_DEBUG > 1
1632 printf("xe%d: Selecting 10base2\n", scp->unit);
1633#endif
1634 XE_SELECT_PAGE(0x42);
1635 XE_OUTB(XE_SWC1, 0xc0);
1636 scp->media |= IFM_10_2;
1637 break;
1638 }
1639
1640
1641 /*
1642 * Finally, the LEDs are set to match whatever media was chosen and the
1643 * transmitter is unblocked.
1644 */
1645#if XE_DEBUG > 1
1646 printf("xe%d: Setting LEDs\n", scp->unit);
1647#endif
1648 XE_SELECT_PAGE(2);
1649 switch (IFM_SUBTYPE(scp->media)) {
1650 case IFM_100_TX:
1651 case IFM_10_T:
1652 XE_OUTB(XE_LED, 0x3b);
1653 if (scp->dingo)
1654 XE_OUTB(0x0b, 0x04); /* 100Mbit LED */

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

1668/*
1669 * Hard reset (power cycle) the card.
1670 */
1671static void
1672xe_hard_reset(struct xe_softc *scp) {
1673 int s;
1674
1675#ifdef XE_DEBUG
1676 printf("xe%d: hard_reset\n", scp->unit);
1677#endif
1678
1679 if (scp->gone) return;
1680
1681 s = splimp();
1682
1683 /*
1684 * Power cycle the card.
1685 */
1686 XE_SELECT_PAGE(4);
1687 XE_OUTB(XE_GPR1, 0); /* Power off */
1688 DELAY(40000);

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

1705 * leave us in a position where we can access the PHY and do media
1706 * selection. The function imposes a 0.5s delay while the hardware powers up.
1707 */
1708static void
1709xe_soft_reset(struct xe_softc *scp) {
1710 int s;
1711
1712#ifdef XE_DEBUG
1713 printf("xe%d: soft_reset\n", scp->unit);
1714#endif
1715
1716 if (scp->gone) return;
1717
1718 s = splimp();
1719
1720 /*
1721 * Reset the card, (again).
1722 */
1723 XE_SELECT_PAGE(0);
1724 XE_OUTB(XE_CR, XE_CR_SOFT_RESET);
1725 DELAY(40000);

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

1745 * Get silicon revision number.
1746 */
1747 XE_SELECT_PAGE(4);
1748 if (scp->mohawk)
1749 scp->srev = (XE_INB(XE_BOV) & 0x70) >> 4;
1750 else
1751 scp->srev = (XE_INB(XE_BOV) & 0x30) >> 4;
1752#ifdef XE_DEBUG
1753 printf("xe%d: silicon revision = %d\n", scp->unit, scp->srev);
1754#endif
1755
1756 /*
1757 * Shut off interrupts.
1758 */
1759 xe_disable_intr(scp);
1760
1761 /*

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

1776 * assume means just shutting down the transceiver and Ethernet logic. This
1777 * requires a _hard_ reset to recover from, as we need to power up again.
1778 */
1779static void
1780xe_stop(struct xe_softc *scp) {
1781 int s;
1782
1783#ifdef XE_DEBUG
1784 printf("xe%d: stop\n", scp->unit);
1785#endif
1786
1787 if (scp->gone) return;
1788
1789 s = splimp();
1790
1791 /*
1792 * Shut off interrupts.
1793 */
1794 xe_disable_intr(scp);
1795
1796 /*

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

1812
1813
1814/*
1815 * Enable Ethernet interrupts from the card.
1816 */
1817static void
1818xe_enable_intr(struct xe_softc *scp) {
1819#ifdef XE_DEBUG
1820 printf("xe%d: enable_intr\n", scp->unit);
1821#endif
1822
1823 XE_SELECT_PAGE(1);
1824 XE_OUTB(XE_IMR0, 0xff); /* Unmask everything */
1825 XE_OUTB(XE_IMR1, 0x01); /* Unmask TX underrun detection */
1826 DELAY(1);
1827
1828 XE_SELECT_PAGE(0);

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

1836
1837
1838/*
1839 * Disable all Ethernet interrupts from the card.
1840 */
1841static void
1842xe_disable_intr(struct xe_softc *scp) {
1843#ifdef XE_DEBUG
1844 printf("xe%d: disable_intr\n", scp->unit);
1845#endif
1846
1847 XE_SELECT_PAGE(0);
1848 XE_OUTB(XE_CR, 0); /* Disable interrupts */
1849 if (scp->modem && !scp->dingo) { /* More magic (does this work?) */
1850 XE_OUTB(0x10, 0x10); /* Mask the master int enable bit */
1851 }
1852

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

1937 addr = (u_int8_t *)(&scp->arpcom.ac_enaddr);
1938 }
1939
1940 for (i = 0; i < 6; i++, byte++) {
1941#if XE_DEBUG > 2
1942 if (i)
1943 printf(":%x", addr[i]);
1944 else
1945 printf("xe%d: individual addresses %d: %x", scp->unit, slot, addr[0]);
1946#endif
1947
1948 if (byte > 15) {
1949 page++;
1950 byte = 8;
1951 XE_SELECT_PAGE(page);
1952 }
1953

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

2008 if (wantbyte) { /* Finish the last word */
2009 savebyte[1] = *data;
2010 XE_OUTW(XE_EDP, *(u_short *)savebyte);
2011 data++;
2012 len--;
2013 wantbyte = 0;
2014 }
2015 if (len > 1) { /* Output contiguous words */
2016 outsw(scp->dev->id_iobase+XE_EDP, data, len >> 1);
2017 data += len & ~1;
2018 len &= 1;
2019 }
2020 if (len == 1) { /* Save last byte, if necessary */
2021 savebyte[0] = *data;
2022 wantbyte = 1;
2023 }
2024 }

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

2038 while (pad > 0) {
2039 XE_OUTW(XE_EDP, 0xdead);
2040 pad--;
2041 }
2042
2043 return 0;
2044}
2045
2046
2047/*
2048 * The device entry is being removed, probably because someone ejected the
2049 * card. The interface should have been brought down manually before calling
2050 * this function; if not you may well lose packets. In any case, I shut down
2051 * the card and the interface, and hope for the best. The 'gone' flag is set,
2052 * so hopefully no-one else will try to access the missing card.
2053 */
2054static void
2055xe_card_unload(struct pccard_devinfo *devi) {
2056 struct xe_softc *scp;
2057 struct ifnet *ifp;
2058 int unit;
2059
2060 unit = devi->isahd.id_unit;
2061 scp = sca[unit];
2062 ifp = &scp->arpcom.ac_if;
2063
2064 if (scp->gone) {
2065 printf("xe%d: already unloaded\n", unit);
2066 return;
2067 }
2068
2069 if_down(ifp);
2070 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
2071 xe_stop(scp);
2072 scp->gone = 1;
2073}
2074
2075
2076/*
2077 * Compute the 32-bit Ethernet CRC for the given buffer.
2078 */
2079static u_int32_t
2080xe_compute_crc(u_int8_t *data, int len) {
2081 u_int32_t crc = 0xffffffff;
2082 u_int32_t poly = 0x04c11db6;
2083 u_int8_t current, crc31, bit;
2084 int i, k;

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

2169 */
2170static int
2171xe_mii_init(struct xe_softc *scp) {
2172 u_int16_t status;
2173
2174 status = xe_phy_readreg(scp, PHY_BMSR);
2175 if ((status & 0xff00) != 0x7800) {
2176#if XE_DEBUG > 1
2177 printf("xe%d: no PHY found, %0x\n", scp->unit, status);
2178#endif
2179 return 0;
2180 }
2181 else {
2182#if XE_DEBUG > 1
2183 printf("xe%d: PHY OK!\n", scp->unit);
2184#endif
2185
2186 /* Reset the PHY */
2187 xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_RESET);
2188 DELAY(500);
2189 while(xe_phy_readreg(scp, PHY_BMCR) & PHY_BMCR_RESET);
2190 XE_MII_DUMP(scp);
2191 return 1;

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

2398 * A bit of debugging code.
2399 */
2400static void
2401xe_mii_dump(struct xe_softc *scp) {
2402 int i, s;
2403
2404 s = splimp();
2405
2406 printf("xe%d: MII registers: ", scp->unit);
2407 for (i = 0; i < 2; i++) {
2408 printf(" %d:%04x", i, xe_phy_readreg(scp, i));
2409 }
2410 for (i = 4; i < 7; i++) {
2411 printf(" %d:%04x", i, xe_phy_readreg(scp, i));
2412 }
2413 printf("\n");
2414
2415 (void)splx(s);
2416}
2417
2418static void
2419xe_reg_dump(struct xe_softc *scp) {
2420 int page, i, s;
2421
2422 s = splimp();
2423
2424 printf("xe%d: Common registers: ", scp->unit);
2425 for (i = 0; i < 8; i++) {
2426 printf(" %2.2x", XE_INB(i));
2427 }
2428 printf("\n");
2429
2430 for (page = 0; page <= 8; page++) {
2431 printf("xe%d: Register page %2.2x: ", scp->unit, page);
2432 XE_SELECT_PAGE(page);
2433 for (i = 8; i < 16; i++) {
2434 printf(" %2.2x", XE_INB(i));
2435 }
2436 printf("\n");
2437 }
2438
2439 for (page = 0x10; page < 0x5f; page++) {
2440 if ((page >= 0x11 && page <= 0x3f) ||
2441 (page == 0x41) ||
2442 (page >= 0x43 && page <= 0x4f) ||
2443 (page >= 0x59))
2444 continue;
2445 printf("xe%d: Register page %2.2x: ", scp->unit, page);
2446 XE_SELECT_PAGE(page);
2447 for (i = 8; i < 16; i++) {
2448 printf(" %2.2x", XE_INB(i));
2449 }
2450 printf("\n");
2451 }
2452
2453 (void)splx(s);
2454}
2455#endif
2456
2457
2458
2459#if NAPM > 0
2460/**************************************************************
2461 * *
2462 * A P M F U N C T I O N S *
2463 * *
2464 **************************************************************/
2465
2466/*
2467 * This is called when we go into suspend/standby mode
2468 */
2469static int
2470xe_suspend(void *xunit) {
2471
2472#ifdef XE_DEBUG
2473 struct xe_softc *scp = sca[(int)xunit];
2474
2475 printf("xe%d: APM suspend\n", scp->unit);
2476#endif
2477
2478 return 0;
2479}
2480
2481/*
2482 * This is called when we wake up again
2483 */
2484static int
2485xe_resume(void *xunit) {
2486
2487#ifdef XE_DEBUG
2488 struct xe_softc *scp = sca[(int)xunit];
2489
2490 printf("xe%d: APM resume\n", scp->unit);
2491#endif
2492
2493 return 0;
2494}
2495
2496#endif /* NAPM > 0 */
2497
2498#endif /* NCARD > 0 */
2499
2500#endif /* NXE > 0 */