2006-10-12 05:30:41 +04:00
|
|
|
/* $NetBSD: if_xi.c,v 1.58 2006/10/12 01:31:50 christos Exp $ */
|
2000-06-06 03:14:22 +04:00
|
|
|
/* OpenBSD: if_xe.c,v 1.9 1999/09/16 11:28:42 niklas Exp */
|
|
|
|
|
2000-10-02 03:32:39 +04:00
|
|
|
/*
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
* Copyright (c) 2004 Charles M. Hannum. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by Charles M. Hannum.
|
|
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
2000-10-02 03:32:39 +04:00
|
|
|
*/
|
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1999 Niklas Hallqvist, Brandon Creighton, Job de Haas
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by Niklas Hallqvist,
|
|
|
|
* Brandon Creighton and Job de Haas.
|
|
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A driver for Xircom CreditCard PCMCIA Ethernet adapters.
|
|
|
|
*/
|
|
|
|
|
2001-11-13 10:24:43 +03:00
|
|
|
#include <sys/cdefs.h>
|
2006-10-12 05:30:41 +04:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: if_xi.c,v 1.58 2006/10/12 01:31:50 christos Exp $");
|
2001-11-13 10:24:43 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
#include "opt_inet.h"
|
2003-06-23 15:00:59 +04:00
|
|
|
#include "opt_ipx.h"
|
2000-06-06 03:14:22 +04:00
|
|
|
#include "bpfilter.h"
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/device.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/mbuf.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/socket.h>
|
2004-08-12 22:23:50 +04:00
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/proc.h>
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <net/if_dl.h>
|
|
|
|
#include <net/if_media.h>
|
|
|
|
#include <net/if_types.h>
|
|
|
|
#include <net/if_ether.h>
|
|
|
|
|
|
|
|
#ifdef INET
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_systm.h>
|
|
|
|
#include <netinet/in_var.h>
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#include <netinet/if_inarp.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef IPX
|
|
|
|
#include <netipx/ipx.h>
|
|
|
|
#include <netipx/ipx_if.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if NBPFILTER > 0
|
|
|
|
#include <net/bpf.h>
|
|
|
|
#include <net/bpfdesc.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Maximum number of bytes to read per interrupt. Linux recommends
|
|
|
|
* somewhere between 2000-22000.
|
|
|
|
* XXX This is currently a hard maximum.
|
|
|
|
*/
|
|
|
|
#define MAX_BYTES_INTR 12000
|
|
|
|
|
|
|
|
#include <dev/mii/mii.h>
|
|
|
|
#include <dev/mii/miivar.h>
|
|
|
|
|
|
|
|
#include <dev/pcmcia/pcmciareg.h>
|
|
|
|
#include <dev/pcmcia/pcmciavar.h>
|
|
|
|
#include <dev/pcmcia/pcmciadevs.h>
|
|
|
|
|
|
|
|
#include <dev/pcmcia/if_xireg.h>
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#include <dev/pcmcia/if_xivar.h>
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
#ifdef __GNUC__
|
2005-12-24 23:27:29 +03:00
|
|
|
#define INLINE inline
|
2000-06-06 03:14:22 +04:00
|
|
|
#else
|
|
|
|
#define INLINE
|
|
|
|
#endif /* __GNUC__ */
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#define XIDEBUG
|
2004-08-08 09:56:50 +04:00
|
|
|
#define XIDEBUG_VALUE 0
|
2004-08-07 00:38:09 +04:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
#ifdef XIDEBUG
|
|
|
|
#define DPRINTF(cat, x) if (xidebug & (cat)) printf x
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#define XID_CONFIG 0x01
|
|
|
|
#define XID_MII 0x02
|
|
|
|
#define XID_INTR 0x04
|
|
|
|
#define XID_FIFO 0x08
|
|
|
|
#define XID_MCAST 0x10
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
#ifdef XIDEBUG_VALUE
|
|
|
|
int xidebug = XIDEBUG_VALUE;
|
|
|
|
#else
|
|
|
|
int xidebug = 0;
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#define DPRINTF(cat, x) (void)0
|
|
|
|
#endif
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#define STATIC
|
|
|
|
|
2005-02-04 05:10:35 +03:00
|
|
|
STATIC int xi_enable(struct xi_softc *);
|
|
|
|
STATIC void xi_disable(struct xi_softc *);
|
|
|
|
STATIC void xi_cycle_power(struct xi_softc *);
|
|
|
|
STATIC int xi_ether_ioctl(struct ifnet *, u_long cmd, caddr_t);
|
|
|
|
STATIC void xi_full_reset(struct xi_softc *);
|
|
|
|
STATIC void xi_init(struct xi_softc *);
|
|
|
|
STATIC int xi_ioctl(struct ifnet *, u_long, caddr_t);
|
|
|
|
STATIC int xi_mdi_read(struct device *, int, int);
|
|
|
|
STATIC void xi_mdi_write(struct device *, int, int, int);
|
|
|
|
STATIC int xi_mediachange(struct ifnet *);
|
|
|
|
STATIC void xi_mediastatus(struct ifnet *, struct ifmediareq *);
|
|
|
|
STATIC u_int16_t xi_get(struct xi_softc *);
|
|
|
|
STATIC void xi_reset(struct xi_softc *);
|
|
|
|
STATIC void xi_set_address(struct xi_softc *);
|
|
|
|
STATIC void xi_start(struct ifnet *);
|
|
|
|
STATIC void xi_statchg(struct device *);
|
|
|
|
STATIC void xi_stop(struct xi_softc *);
|
|
|
|
STATIC void xi_watchdog(struct ifnet *);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
void
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
xi_attach(sc, myea)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
u_int8_t *myea;
|
2000-06-06 03:14:22 +04:00
|
|
|
{
|
|
|
|
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#if 0
|
2000-06-06 03:14:22 +04:00
|
|
|
/*
|
2001-07-01 05:57:29 +04:00
|
|
|
* Configuration as advised by DINGO documentation.
|
2000-06-06 03:14:22 +04:00
|
|
|
* Dingo has some extra configuration registers in the CCR space.
|
|
|
|
*/
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_DINGO) {
|
2000-06-06 03:14:22 +04:00
|
|
|
struct pcmcia_mem_handle pcmh;
|
|
|
|
int ccr_window;
|
2003-02-27 10:50:57 +03:00
|
|
|
bus_size_t ccr_offset;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2001-07-01 05:57:29 +04:00
|
|
|
/* get access to the DINGO CCR space */
|
2000-06-06 03:14:22 +04:00
|
|
|
if (pcmcia_mem_alloc(psc->sc_pf, PCMCIA_CCR_SIZE_DINGO,
|
|
|
|
&pcmh)) {
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi: bad mem alloc\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR,
|
|
|
|
psc->sc_pf->ccr_base, PCMCIA_CCR_SIZE_DINGO,
|
|
|
|
&pcmh, &ccr_offset, &ccr_window)) {
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi: bad mem map\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
pcmcia_mem_free(psc->sc_pf, &pcmh);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2001-07-01 05:57:29 +04:00
|
|
|
/* enable the second function - usually modem */
|
2000-06-06 03:14:22 +04:00
|
|
|
bus_space_write_1(pcmh.memt, pcmh.memh,
|
|
|
|
ccr_offset + PCMCIA_CCR_DCOR0, PCMCIA_CCR_DCOR0_SFINT);
|
|
|
|
bus_space_write_1(pcmh.memt, pcmh.memh,
|
|
|
|
ccr_offset + PCMCIA_CCR_DCOR1,
|
|
|
|
PCMCIA_CCR_DCOR1_FORCE_LEVIREQ | PCMCIA_CCR_DCOR1_D6);
|
|
|
|
bus_space_write_1(pcmh.memt, pcmh.memh,
|
|
|
|
ccr_offset + PCMCIA_CCR_DCOR2, 0);
|
|
|
|
bus_space_write_1(pcmh.memt, pcmh.memh,
|
|
|
|
ccr_offset + PCMCIA_CCR_DCOR3, 0);
|
|
|
|
bus_space_write_1(pcmh.memt, pcmh.memh,
|
|
|
|
ccr_offset + PCMCIA_CCR_DCOR4, 0);
|
|
|
|
|
|
|
|
/* We don't need them anymore and can free them (I think). */
|
|
|
|
pcmcia_mem_unmap(psc->sc_pf, ccr_window);
|
|
|
|
pcmcia_mem_free(psc->sc_pf, &pcmh);
|
|
|
|
}
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#endif
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
/* Reset and initialize the card. */
|
|
|
|
xi_full_reset(sc);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
printf("%s: MAC address %s\n", sc->sc_dev.dv_xname, ether_sprintf(myea));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
ifp = &sc->sc_ethercom.ec_if;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
/* Initialize the ifnet structure. */
|
|
|
|
strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
|
2000-06-06 03:14:22 +04:00
|
|
|
ifp->if_softc = sc;
|
|
|
|
ifp->if_start = xi_start;
|
|
|
|
ifp->if_ioctl = xi_ioctl;
|
|
|
|
ifp->if_watchdog = xi_watchdog;
|
|
|
|
ifp->if_flags =
|
|
|
|
IFF_BROADCAST | IFF_NOTRAILERS | IFF_SIMPLEX | IFF_MULTICAST;
|
2000-12-14 09:27:23 +03:00
|
|
|
IFQ_SET_READY(&ifp->if_snd);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
/* 802.1q capability */
|
|
|
|
sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
|
|
|
|
|
|
|
|
/* Attach the interface. */
|
|
|
|
if_attach(ifp);
|
|
|
|
ether_ifattach(ifp, myea);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize our media structures and probe the MII.
|
|
|
|
*/
|
|
|
|
sc->sc_mii.mii_ifp = ifp;
|
|
|
|
sc->sc_mii.mii_readreg = xi_mdi_read;
|
|
|
|
sc->sc_mii.mii_writereg = xi_mdi_write;
|
|
|
|
sc->sc_mii.mii_statchg = xi_statchg;
|
|
|
|
ifmedia_init(&sc->sc_mii.mii_media, 0, xi_mediachange,
|
|
|
|
xi_mediastatus);
|
|
|
|
DPRINTF(XID_MII | XID_CONFIG,
|
2000-06-09 12:22:13 +04:00
|
|
|
("xi: bmsr %x\n", xi_mdi_read(&sc->sc_dev, 0, 1)));
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
|
|
|
|
mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
|
2000-06-06 03:14:22 +04:00
|
|
|
MII_OFFSET_ANY, 0);
|
|
|
|
if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL)
|
|
|
|
ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO, 0,
|
|
|
|
NULL);
|
|
|
|
ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
|
|
|
|
|
2001-07-01 05:57:29 +04:00
|
|
|
#if NRND > 0
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
rnd_attach_source(&sc->sc_rnd_source, sc->sc_dev.dv_xname, RND_TYPE_NET, 0);
|
2001-07-01 05:57:29 +04:00
|
|
|
#endif
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2006-10-12 05:30:41 +04:00
|
|
|
xi_detach(struct device *self, int flags __unused)
|
2000-06-06 03:14:22 +04:00
|
|
|
{
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
struct xi_softc *sc = (void *)self;
|
2000-06-06 03:14:22 +04:00
|
|
|
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_detach()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2004-08-08 11:25:20 +04:00
|
|
|
xi_disable(sc);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2001-07-01 05:57:29 +04:00
|
|
|
#if NRND > 0
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
rnd_detach_source(&sc->sc_rnd_source);
|
2001-07-01 05:57:29 +04:00
|
|
|
#endif
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
|
|
|
|
ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
|
|
|
|
ether_ifdetach(ifp);
|
|
|
|
if_detach(ifp);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
xi_activate(self, act)
|
|
|
|
struct device *self;
|
|
|
|
enum devact act;
|
2000-06-06 03:14:22 +04:00
|
|
|
{
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
struct xi_softc *sc = (void *)self;
|
|
|
|
int s, rv = 0;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_activate()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
s = splnet();
|
|
|
|
switch (act) {
|
|
|
|
case DVACT_ACTIVATE:
|
|
|
|
rv = EOPNOTSUPP;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DVACT_DEACTIVATE:
|
|
|
|
if_deactivate(&sc->sc_ethercom.ec_if);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
splx(s);
|
|
|
|
return (rv);
|
|
|
|
}
|
|
|
|
|
2000-07-25 01:50:10 +04:00
|
|
|
int
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_intr(arg)
|
|
|
|
void *arg;
|
|
|
|
{
|
|
|
|
struct xi_softc *sc = arg;
|
|
|
|
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
2004-08-09 09:11:33 +04:00
|
|
|
u_int8_t esr, rsr, isr, rx_status;
|
2003-10-29 02:26:28 +03:00
|
|
|
u_int16_t tx_status, recvcount = 0, tempint;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_intr()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_enabled == 0 ||
|
2006-02-20 19:50:36 +03:00
|
|
|
!device_is_active(&sc->sc_dev))
|
2000-06-06 03:14:22 +04:00
|
|
|
return (0);
|
|
|
|
|
|
|
|
ifp->if_timer = 0; /* turn watchdog timer off */
|
|
|
|
|
2004-08-09 09:11:33 +04:00
|
|
|
PAGE(sc, 0);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Disable interrupt (Linux does it). */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, 0);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
2004-08-12 23:42:03 +04:00
|
|
|
esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, ESR);
|
|
|
|
isr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, ISR0);
|
|
|
|
rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, RSR);
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Check to see if card has been ejected. */
|
|
|
|
if (isr == 0xff) {
|
|
|
|
#ifdef DIAGNOSTIC
|
|
|
|
printf("%s: interrupt for dead card\n", sc->sc_dev.dv_xname);
|
|
|
|
#endif
|
|
|
|
goto end;
|
|
|
|
}
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
DPRINTF(XID_INTR, ("xi: isr=%02x\n", isr));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
PAGE(sc, 0x40);
|
2000-06-06 03:14:22 +04:00
|
|
|
rx_status =
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_read_1(sc->sc_bst, sc->sc_bsh, RXST0);
|
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, RXST0, ~rx_status & 0xff);
|
2000-06-06 03:14:22 +04:00
|
|
|
tx_status =
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_read_1(sc->sc_bst, sc->sc_bsh, TXST0);
|
2002-09-22 14:13:32 +04:00
|
|
|
tx_status |=
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_read_1(sc->sc_bst, sc->sc_bsh, TXST1) << 8;
|
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, TXST0, 0);
|
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, TXST1, 0);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
DPRINTF(XID_INTR, ("xi: rx_status=%02x tx_status=%04x\n", rx_status,
|
|
|
|
tx_status));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
PAGE(sc, 0);
|
|
|
|
while (esr & FULL_PKT_RCV) {
|
|
|
|
if (!(rsr & RSR_RX_OK))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Compare bytes read this interrupt to hard maximum. */
|
|
|
|
if (recvcount > MAX_BYTES_INTR) {
|
|
|
|
DPRINTF(XID_INTR,
|
2000-06-09 12:22:13 +04:00
|
|
|
("xi: too many bytes this interrupt\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
ifp->if_iqdrops++;
|
|
|
|
/* Drop packet. */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_2(sc->sc_bst, sc->sc_bsh, DO0,
|
|
|
|
DO_SKIP_RX_PKT);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
tempint = xi_get(sc); /* XXX doesn't check the error! */
|
|
|
|
recvcount += tempint;
|
|
|
|
ifp->if_ibytes += tempint;
|
2004-08-12 23:42:03 +04:00
|
|
|
esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, ESR);
|
|
|
|
rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, RSR);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Packet too long? */
|
|
|
|
if (rsr & RSR_TOO_LONG) {
|
|
|
|
ifp->if_ierrors++;
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_INTR, ("xi: packet too long\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* CRC error? */
|
|
|
|
if (rsr & RSR_CRCERR) {
|
|
|
|
ifp->if_ierrors++;
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_INTR, ("xi: CRC error detected\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Alignment error? */
|
|
|
|
if (rsr & RSR_ALIGNERR) {
|
|
|
|
ifp->if_ierrors++;
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_INTR, ("xi: alignment error detected\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for rx overrun. */
|
|
|
|
if (rx_status & RX_OVERRUN) {
|
2002-09-22 14:13:32 +04:00
|
|
|
ifp->if_ierrors++;
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, CLR_RX_OVERRUN);
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_INTR, ("xi: overrun cleared\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Try to start more packets transmitting. */
|
2000-12-14 09:27:23 +03:00
|
|
|
if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_start(ifp);
|
|
|
|
|
|
|
|
/* Detected excessive collisions? */
|
|
|
|
if ((tx_status & EXCESSIVE_COLL) && ifp->if_opackets > 0) {
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_INTR, ("xi: excessive collisions\n"));
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, RESTART_TX);
|
2000-06-06 03:14:22 +04:00
|
|
|
ifp->if_oerrors++;
|
|
|
|
}
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
if ((tx_status & TX_ABORT) && ifp->if_opackets > 0)
|
|
|
|
ifp->if_oerrors++;
|
|
|
|
|
2003-10-29 02:26:28 +03:00
|
|
|
/* have handled the interrupt */
|
2005-02-27 03:26:58 +03:00
|
|
|
#if NRND > 0
|
|
|
|
rnd_add_uint32(&sc->sc_rnd_source, tx_status);
|
2003-10-29 02:26:28 +03:00
|
|
|
#endif
|
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
end:
|
|
|
|
/* Reenable interrupts. */
|
2004-08-09 09:11:33 +04:00
|
|
|
PAGE(sc, 0);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, CR, ENABLE_INT);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pull a packet from the card into an mbuf chain.
|
|
|
|
*/
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC u_int16_t
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_get(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
|
|
|
struct mbuf *top, **mp, *m;
|
|
|
|
u_int16_t pktlen, len, recvcount = 0;
|
|
|
|
u_int8_t *data;
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_get()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
PAGE(sc, 0);
|
|
|
|
pktlen =
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_read_2(sc->sc_bst, sc->sc_bsh, RBC0) & RBC_COUNT_MASK;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
DPRINTF(XID_CONFIG, ("xi_get: pktlen=%d\n", pktlen));
|
|
|
|
|
|
|
|
if (pktlen == 0) {
|
|
|
|
/*
|
|
|
|
* XXX At least one CE2 sets RBC0 == 0 occasionally, and only
|
|
|
|
* when MPE is set. It is not known why.
|
|
|
|
*/
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX should this be incremented now ? */
|
|
|
|
recvcount += pktlen;
|
|
|
|
|
|
|
|
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
2006-04-14 21:46:29 +04:00
|
|
|
if (m == NULL)
|
2000-06-06 03:14:22 +04:00
|
|
|
return (recvcount);
|
|
|
|
m->m_pkthdr.rcvif = ifp;
|
|
|
|
m->m_pkthdr.len = pktlen;
|
|
|
|
len = MHLEN;
|
2006-04-14 21:46:29 +04:00
|
|
|
top = NULL;
|
2000-06-06 03:14:22 +04:00
|
|
|
mp = ⊤
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
while (pktlen > 0) {
|
|
|
|
if (top) {
|
|
|
|
MGET(m, M_DONTWAIT, MT_DATA);
|
2006-04-14 21:46:29 +04:00
|
|
|
if (m == NULL) {
|
2000-06-06 03:14:22 +04:00
|
|
|
m_freem(top);
|
|
|
|
return (recvcount);
|
|
|
|
}
|
|
|
|
len = MLEN;
|
|
|
|
}
|
|
|
|
if (pktlen >= MINCLSIZE) {
|
|
|
|
MCLGET(m, M_DONTWAIT);
|
|
|
|
if (!(m->m_flags & M_EXT)) {
|
|
|
|
m_freem(m);
|
|
|
|
m_freem(top);
|
|
|
|
return (recvcount);
|
|
|
|
}
|
|
|
|
len = MCLBYTES;
|
|
|
|
}
|
2006-04-14 21:46:29 +04:00
|
|
|
if (top == NULL) {
|
2000-06-06 03:14:22 +04:00
|
|
|
caddr_t newdata = (caddr_t)ALIGN(m->m_data +
|
|
|
|
sizeof(struct ether_header)) -
|
|
|
|
sizeof(struct ether_header);
|
|
|
|
len -= newdata - m->m_data;
|
|
|
|
m->m_data = newdata;
|
|
|
|
}
|
|
|
|
len = min(pktlen, len);
|
|
|
|
data = mtod(m, u_int8_t *);
|
|
|
|
if (len > 1) {
|
|
|
|
len &= ~1;
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_read_multi_2(sc->sc_bst, sc->sc_bsh, EDP,
|
|
|
|
(u_int16_t *)data, len>>1);
|
2000-06-06 03:14:22 +04:00
|
|
|
} else
|
2004-08-12 23:42:03 +04:00
|
|
|
*data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, EDP);
|
2000-06-06 03:14:22 +04:00
|
|
|
m->m_len = len;
|
|
|
|
pktlen -= len;
|
|
|
|
*mp = m;
|
|
|
|
mp = &m->m_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Skip Rx packet. */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_2(sc->sc_bst, sc->sc_bsh, DO0, DO_SKIP_RX_PKT);
|
2005-01-30 22:30:16 +03:00
|
|
|
|
2006-04-14 21:46:29 +04:00
|
|
|
if (top == NULL)
|
|
|
|
return recvcount;
|
|
|
|
|
2005-01-30 22:30:16 +03:00
|
|
|
/* Trim the CRC off the end of the packet. */
|
|
|
|
m_adj(top, -ETHER_CRC_LEN);
|
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
ifp->if_ipackets++;
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
#if NBPFILTER > 0
|
|
|
|
if (ifp->if_bpf)
|
|
|
|
bpf_mtap(ifp->if_bpf, top);
|
|
|
|
#endif
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
(*ifp->if_input)(ifp, top);
|
|
|
|
return (recvcount);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Serial management for the MII.
|
|
|
|
* The DELAY's below stem from the fact that the maximum frequency
|
|
|
|
* acceptable on the MDC pin is 2.5 MHz and fast processors can easily
|
|
|
|
* go much faster than that.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Let the MII serial management be idle for one period. */
|
2005-02-04 05:10:35 +03:00
|
|
|
static INLINE void xi_mdi_idle(struct xi_softc *);
|
2000-06-06 03:14:22 +04:00
|
|
|
static INLINE void
|
|
|
|
xi_mdi_idle(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
|
|
|
|
|
|
|
/* Drive MDC low... */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP2, MDC_LOW);
|
2000-06-06 03:14:22 +04:00
|
|
|
DELAY(1);
|
|
|
|
|
|
|
|
/* and high again. */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP2, MDC_HIGH);
|
2000-06-06 03:14:22 +04:00
|
|
|
DELAY(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Pulse out one bit of data. */
|
2005-02-04 05:10:35 +03:00
|
|
|
static INLINE void xi_mdi_pulse(struct xi_softc *, int);
|
2000-06-06 03:14:22 +04:00
|
|
|
static INLINE void
|
|
|
|
xi_mdi_pulse(sc, data)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
int data;
|
|
|
|
{
|
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
|
|
|
u_int8_t bit = data ? MDIO_HIGH : MDIO_LOW;
|
|
|
|
|
|
|
|
/* First latch the data bit MDIO with clock bit MDC low...*/
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP2, bit | MDC_LOW);
|
2000-06-06 03:14:22 +04:00
|
|
|
DELAY(1);
|
|
|
|
|
|
|
|
/* then raise the clock again, preserving the data bit. */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP2, bit | MDC_HIGH);
|
2000-06-06 03:14:22 +04:00
|
|
|
DELAY(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Probe one bit of data. */
|
2005-02-04 05:10:35 +03:00
|
|
|
static INLINE int xi_mdi_probe(struct xi_softc *sc);
|
2000-06-06 03:14:22 +04:00
|
|
|
static INLINE int
|
|
|
|
xi_mdi_probe(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
|
|
|
u_int8_t x;
|
|
|
|
|
|
|
|
/* Pull clock bit MDCK low... */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP2, MDC_LOW);
|
2000-06-06 03:14:22 +04:00
|
|
|
DELAY(1);
|
|
|
|
|
|
|
|
/* Read data and drive clock high again. */
|
2004-08-12 23:42:03 +04:00
|
|
|
x = bus_space_read_1(bst, bsh, GP2);
|
|
|
|
bus_space_write_1(bst, bsh, GP2, MDC_HIGH);
|
2000-06-06 03:14:22 +04:00
|
|
|
DELAY(1);
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
return (x & MDIO);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Pulse out a sequence of data bits. */
|
2005-02-04 05:10:35 +03:00
|
|
|
static INLINE void xi_mdi_pulse_bits(struct xi_softc *, u_int32_t, int);
|
2000-06-06 03:14:22 +04:00
|
|
|
static INLINE void
|
|
|
|
xi_mdi_pulse_bits(sc, data, len)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
u_int32_t data;
|
|
|
|
int len;
|
|
|
|
{
|
|
|
|
u_int32_t mask;
|
|
|
|
|
|
|
|
for (mask = 1 << (len - 1); mask; mask >>= 1)
|
|
|
|
xi_mdi_pulse(sc, data & mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read a PHY register. */
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC int
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_mdi_read(self, phy, reg)
|
|
|
|
struct device *self;
|
|
|
|
int phy;
|
|
|
|
int reg;
|
|
|
|
{
|
|
|
|
struct xi_softc *sc = (struct xi_softc *)self;
|
|
|
|
int i;
|
|
|
|
u_int32_t mask;
|
|
|
|
u_int32_t data = 0;
|
|
|
|
|
|
|
|
PAGE(sc, 2);
|
|
|
|
for (i = 0; i < 32; i++) /* Synchronize. */
|
|
|
|
xi_mdi_pulse(sc, 1);
|
|
|
|
xi_mdi_pulse_bits(sc, 0x06, 4); /* Start + Read opcode */
|
|
|
|
xi_mdi_pulse_bits(sc, phy, 5); /* PHY address */
|
|
|
|
xi_mdi_pulse_bits(sc, reg, 5); /* PHY register */
|
|
|
|
xi_mdi_idle(sc); /* Turn around. */
|
|
|
|
xi_mdi_probe(sc); /* Drop initial zero bit. */
|
|
|
|
|
|
|
|
for (mask = 1 << 15; mask; mask >>= 1) {
|
|
|
|
if (xi_mdi_probe(sc))
|
|
|
|
data |= mask;
|
|
|
|
}
|
|
|
|
xi_mdi_idle(sc);
|
|
|
|
|
|
|
|
DPRINTF(XID_MII,
|
|
|
|
("xi_mdi_read: phy %d reg %d -> %x\n", phy, reg, data));
|
|
|
|
|
|
|
|
return (data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write a PHY register. */
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_mdi_write(self, phy, reg, value)
|
|
|
|
struct device *self;
|
|
|
|
int phy;
|
|
|
|
int reg;
|
|
|
|
int value;
|
|
|
|
{
|
|
|
|
struct xi_softc *sc = (struct xi_softc *)self;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
PAGE(sc, 2);
|
|
|
|
for (i = 0; i < 32; i++) /* Synchronize. */
|
|
|
|
xi_mdi_pulse(sc, 1);
|
|
|
|
xi_mdi_pulse_bits(sc, 0x05, 4); /* Start + Write opcode */
|
|
|
|
xi_mdi_pulse_bits(sc, phy, 5); /* PHY address */
|
|
|
|
xi_mdi_pulse_bits(sc, reg, 5); /* PHY register */
|
|
|
|
xi_mdi_pulse_bits(sc, 0x02, 2); /* Turn around. */
|
|
|
|
xi_mdi_pulse_bits(sc, value, 16); /* Write the data */
|
|
|
|
xi_mdi_idle(sc); /* Idle away. */
|
|
|
|
|
|
|
|
DPRINTF(XID_MII,
|
|
|
|
("xi_mdi_write: phy %d reg %d val %x\n", phy, reg, value));
|
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2006-10-12 05:30:41 +04:00
|
|
|
xi_statchg(struct device *self __unused)
|
2000-06-06 03:14:22 +04:00
|
|
|
{
|
|
|
|
/* XXX Update ifp->if_baudrate */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change media according to request.
|
|
|
|
*/
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC int
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_mediachange(ifp)
|
|
|
|
struct ifnet *ifp;
|
|
|
|
{
|
2004-08-08 11:25:20 +04:00
|
|
|
int s;
|
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_mediachange()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2004-08-08 11:25:20 +04:00
|
|
|
if (ifp->if_flags & IFF_UP) {
|
|
|
|
s = splnet();
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_init(ifp->if_softc);
|
2004-08-08 11:25:20 +04:00
|
|
|
splx(s);
|
|
|
|
}
|
2000-06-06 03:14:22 +04:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Notify the world which media we're using.
|
|
|
|
*/
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_mediastatus(ifp, ifmr)
|
|
|
|
struct ifnet *ifp;
|
|
|
|
struct ifmediareq *ifmr;
|
|
|
|
{
|
|
|
|
struct xi_softc *sc = ifp->if_softc;
|
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_mediastatus()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2004-08-08 11:48:46 +04:00
|
|
|
if (LIST_FIRST(&sc->sc_mii.mii_phys)) {
|
|
|
|
mii_pollstat(&sc->sc_mii);
|
|
|
|
ifmr->ifm_status = sc->sc_mii.mii_media_status;
|
|
|
|
ifmr->ifm_active = sc->sc_mii.mii_media_active;
|
|
|
|
}
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_reset(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
int s;
|
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_reset()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
s = splnet();
|
|
|
|
xi_stop(sc);
|
|
|
|
xi_init(sc);
|
|
|
|
splx(s);
|
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_watchdog(ifp)
|
|
|
|
struct ifnet *ifp;
|
|
|
|
{
|
|
|
|
struct xi_softc *sc = ifp->if_softc;
|
|
|
|
|
|
|
|
printf("%s: device timeout\n", sc->sc_dev.dv_xname);
|
|
|
|
++ifp->if_oerrors;
|
|
|
|
|
|
|
|
xi_reset(sc);
|
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_stop(sc)
|
|
|
|
register struct xi_softc *sc;
|
|
|
|
{
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_stop()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2004-08-09 08:47:40 +04:00
|
|
|
PAGE(sc, 0x40);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, CMD0, DISABLE_RX);
|
2004-08-09 08:47:40 +04:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Disable interrupts. */
|
|
|
|
PAGE(sc, 0);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, CR, 0);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
PAGE(sc, 1);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, IMR0, 0);
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Cancel watchdog timer. */
|
|
|
|
sc->sc_ethercom.ec_if.if_timer = 0;
|
|
|
|
}
|
|
|
|
|
2004-08-08 11:25:20 +04:00
|
|
|
STATIC int
|
|
|
|
xi_enable(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
|
|
|
if (!sc->sc_enabled) {
|
|
|
|
error = (*sc->sc_enable)(sc);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
sc->sc_enabled = 1;
|
|
|
|
xi_full_reset(sc);
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC void
|
|
|
|
xi_disable(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
|
|
|
|
if (sc->sc_enabled) {
|
|
|
|
sc->sc_enabled = 0;
|
|
|
|
(*sc->sc_disable)(sc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_init(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_init()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
/* Setup the ethernet interrupt mask. */
|
|
|
|
PAGE(sc, 1);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, IMR0,
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
ISR_TX_OFLOW | ISR_PKT_TX | ISR_MAC_INT | /* ISR_RX_EARLY | */
|
|
|
|
ISR_RX_FULL | ISR_RX_PKT_REJ | ISR_FORCED_INT);
|
|
|
|
if (sc->sc_chipset < XI_CHIPSET_DINGO) {
|
|
|
|
/* XXX What is this? Not for Dingo at least. */
|
|
|
|
/* Unmask TX underrun detection */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, IMR1, 1);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Enable interrupts. */
|
|
|
|
PAGE(sc, 0);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, CR, ENABLE_INT);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
|
2004-08-09 08:47:40 +04:00
|
|
|
xi_set_address(sc);
|
|
|
|
|
|
|
|
PAGE(sc, 0x40);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, CMD0, ENABLE_RX | ONLINE);
|
2004-08-09 08:47:40 +04:00
|
|
|
|
|
|
|
PAGE(sc, 0);
|
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Set current media. */
|
|
|
|
mii_mediachg(&sc->sc_mii);
|
|
|
|
|
|
|
|
ifp->if_flags |= IFF_RUNNING;
|
|
|
|
ifp->if_flags &= ~IFF_OACTIVE;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
|
2004-08-08 11:25:20 +04:00
|
|
|
xi_start(ifp);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start outputting on the interface.
|
|
|
|
* Always called as splnet().
|
|
|
|
*/
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_start(ifp)
|
|
|
|
struct ifnet *ifp;
|
|
|
|
{
|
|
|
|
struct xi_softc *sc = ifp->if_softc;
|
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
|
|
|
unsigned int s, len, pad = 0;
|
|
|
|
struct mbuf *m0, *m;
|
|
|
|
u_int16_t space;
|
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_start()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/* Don't transmit if interface is busy or not running. */
|
|
|
|
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) {
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi: interface busy or not running\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Peek at the next packet. */
|
2000-12-14 09:27:23 +03:00
|
|
|
IFQ_POLL(&ifp->if_snd, m0);
|
2000-06-06 03:14:22 +04:00
|
|
|
if (m0 == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* We need to use m->m_pkthdr.len, so require the header. */
|
|
|
|
if (!(m0->m_flags & M_PKTHDR))
|
|
|
|
panic("xi_start: no header mbuf");
|
|
|
|
|
|
|
|
len = m0->m_pkthdr.len;
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#if 1
|
2000-06-06 03:14:22 +04:00
|
|
|
/* Pad to ETHER_MIN_LEN - ETHER_CRC_LEN. */
|
|
|
|
if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
|
|
|
|
pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
#else
|
|
|
|
pad = 0;
|
|
|
|
#endif
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
PAGE(sc, 0);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_2(bst, bsh, TRS, (u_int16_t)len + pad + 2);
|
|
|
|
space = bus_space_read_2(bst, bsh, TSO) & 0x7fff;
|
2000-06-06 03:14:22 +04:00
|
|
|
if (len + pad + 2 > space) {
|
|
|
|
DPRINTF(XID_FIFO,
|
2000-06-09 12:22:13 +04:00
|
|
|
("xi: not enough space in output FIFO (%d > %d)\n",
|
|
|
|
len + pad + 2, space));
|
2000-06-06 03:14:22 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-12-14 09:27:23 +03:00
|
|
|
IFQ_DEQUEUE(&ifp->if_snd, m0);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
#if NBPFILTER > 0
|
|
|
|
if (ifp->if_bpf)
|
|
|
|
bpf_mtap(ifp->if_bpf, m0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Do the output at splhigh() so that an interrupt from another device
|
|
|
|
* won't cause a FIFO underrun.
|
|
|
|
*/
|
|
|
|
s = splhigh();
|
|
|
|
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_2(bst, bsh, EDP, (u_int16_t)len + pad);
|
2000-06-06 03:14:22 +04:00
|
|
|
for (m = m0; m; ) {
|
|
|
|
if (m->m_len > 1)
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_multi_2(bst, bsh, EDP,
|
2002-05-05 07:19:26 +04:00
|
|
|
mtod(m, u_int16_t *), m->m_len>>1);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (m->m_len & 1) {
|
|
|
|
DPRINTF(XID_CONFIG, ("xi: XXX odd!\n"));
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, EDP,
|
2000-06-06 03:14:22 +04:00
|
|
|
*(mtod(m, u_int8_t *) + m->m_len - 1));
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
}
|
2000-06-06 03:14:22 +04:00
|
|
|
MFREE(m, m0);
|
|
|
|
m = m0;
|
|
|
|
}
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi: len=%d pad=%d total=%d\n", len, pad, len+pad+4));
|
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, CR, TX_PKT | ENABLE_INT);
|
2000-06-06 03:14:22 +04:00
|
|
|
else {
|
|
|
|
for (; pad > 1; pad -= 2)
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_2(bst, bsh, EDP, 0);
|
2000-06-06 03:14:22 +04:00
|
|
|
if (pad == 1)
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, EDP, 0);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
splx(s);
|
|
|
|
|
|
|
|
ifp->if_timer = 5;
|
|
|
|
++ifp->if_opackets;
|
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC int
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_ether_ioctl(ifp, cmd, data)
|
|
|
|
struct ifnet *ifp;
|
|
|
|
u_long cmd;
|
|
|
|
caddr_t data;
|
|
|
|
{
|
|
|
|
struct ifaddr *ifa = (struct ifaddr *)data;
|
|
|
|
struct xi_softc *sc = ifp->if_softc;
|
2004-08-08 11:25:20 +04:00
|
|
|
int error;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_ether_ioctl()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case SIOCSIFADDR:
|
2004-08-08 11:25:20 +04:00
|
|
|
if ((error = xi_enable(sc)) != 0)
|
|
|
|
break;
|
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
ifp->if_flags |= IFF_UP;
|
|
|
|
|
|
|
|
switch (ifa->ifa_addr->sa_family) {
|
|
|
|
#ifdef INET
|
|
|
|
case AF_INET:
|
|
|
|
xi_init(sc);
|
|
|
|
arp_ifinit(ifp, ifa);
|
|
|
|
break;
|
|
|
|
#endif /* INET */
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
xi_init(sc);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC int
|
|
|
|
xi_ioctl(ifp, cmd, data)
|
2000-06-06 03:14:22 +04:00
|
|
|
struct ifnet *ifp;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
u_long cmd;
|
2000-06-06 03:14:22 +04:00
|
|
|
caddr_t data;
|
|
|
|
{
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
struct xi_softc *sc = ifp->if_softc;
|
2000-06-06 03:14:22 +04:00
|
|
|
struct ifreq *ifr = (struct ifreq *)data;
|
|
|
|
int s, error = 0;
|
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_ioctl()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2001-01-14 20:37:41 +03:00
|
|
|
s = splnet();
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
switch (cmd) {
|
2000-06-06 03:14:22 +04:00
|
|
|
case SIOCSIFADDR:
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
error = xi_ether_ioctl(ifp, cmd, data);
|
2000-06-06 03:14:22 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SIOCSIFFLAGS:
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if ((ifp->if_flags & IFF_UP) == 0 &&
|
|
|
|
(ifp->if_flags & IFF_RUNNING) != 0) {
|
|
|
|
/*
|
|
|
|
* If interface is marked down and it is running,
|
|
|
|
* stop it.
|
|
|
|
*/
|
|
|
|
xi_stop(sc);
|
|
|
|
ifp->if_flags &= ~IFF_RUNNING;
|
2004-08-08 11:25:20 +04:00
|
|
|
xi_disable(sc);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
} else if ((ifp->if_flags & IFF_UP) != 0 &&
|
|
|
|
(ifp->if_flags & IFF_RUNNING) == 0) {
|
|
|
|
/*
|
|
|
|
* If interface is marked up and it is stopped,
|
|
|
|
* start it.
|
|
|
|
*/
|
2004-08-08 11:25:20 +04:00
|
|
|
if ((error = xi_enable(sc)) != 0)
|
|
|
|
break;
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_init(sc);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
} else if ((ifp->if_flags & IFF_UP) != 0) {
|
|
|
|
/*
|
|
|
|
* Reset the interface to pick up changes in any
|
|
|
|
* other flags that affect hardware registers.
|
|
|
|
*/
|
2004-08-08 11:25:20 +04:00
|
|
|
xi_set_address(sc);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIOCADDMULTI:
|
|
|
|
case SIOCDELMULTI:
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_enabled == 0) {
|
|
|
|
error = EIO;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = (cmd == SIOCADDMULTI) ?
|
2000-06-06 03:14:22 +04:00
|
|
|
ether_addmulti(ifr, &sc->sc_ethercom) :
|
|
|
|
ether_delmulti(ifr, &sc->sc_ethercom);
|
|
|
|
if (error == ENETRESET) {
|
|
|
|
/*
|
|
|
|
* Multicast list has changed; set the hardware
|
|
|
|
* filter accordingly.
|
|
|
|
*/
|
2004-10-30 22:08:34 +04:00
|
|
|
if (ifp->if_flags & IFF_RUNNING)
|
|
|
|
xi_set_address(sc);
|
2000-06-06 03:14:22 +04:00
|
|
|
error = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIOCSIFMEDIA:
|
|
|
|
case SIOCGIFMEDIA:
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
|
2000-06-06 03:14:22 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
error = EINVAL;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
break;
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
|
2000-06-06 03:14:22 +04:00
|
|
|
splx(s);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_set_address(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
|
|
|
struct ethercom *ether = &sc->sc_ethercom;
|
|
|
|
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
2001-07-01 05:57:29 +04:00
|
|
|
struct ether_multistep step;
|
|
|
|
struct ether_multi *enm;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
int page, num;
|
2001-07-01 05:57:29 +04:00
|
|
|
int i;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
u_int8_t x;
|
|
|
|
u_int8_t *enaddr;
|
|
|
|
u_int8_t indaddr[64];
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_set_address()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
enaddr = (u_int8_t *)LLADDR(ifp->if_sadl);
|
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
indaddr[i] = enaddr[5 - i];
|
|
|
|
else
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
indaddr[i] = enaddr[i];
|
|
|
|
num = 1;
|
|
|
|
|
|
|
|
if (ether->ec_multicnt > 9) {
|
|
|
|
ifp->if_flags |= IFF_ALLMULTI;
|
|
|
|
goto done;
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
2001-07-01 05:57:29 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
ETHER_FIRST_MULTI(step, ether, enm);
|
|
|
|
for (; enm; num++) {
|
|
|
|
if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
|
|
|
|
sizeof(enm->enm_addrlo)) != 0) {
|
|
|
|
/*
|
|
|
|
* The multicast address is really a range;
|
|
|
|
* it's easier just to accept all multicasts.
|
|
|
|
* XXX should we be setting IFF_ALLMULTI here?
|
|
|
|
*/
|
|
|
|
ifp->if_flags |= IFF_ALLMULTI;
|
|
|
|
goto done;
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
indaddr[num * 6 + i] = enm->enm_addrlo[5 - i];
|
|
|
|
else
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
indaddr[num * 6 + i] = enm->enm_addrlo[i];
|
|
|
|
ETHER_NEXT_MULTI(step, enm);
|
|
|
|
}
|
|
|
|
ifp->if_flags &= ~IFF_ALLMULTI;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
done:
|
|
|
|
if (num < 10)
|
|
|
|
memset(&indaddr[num * 6], 0xff, 6 * (10 - num));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
for (page = 0; page < 8; page++) {
|
|
|
|
#ifdef XIDEBUG
|
|
|
|
if (xidebug & XID_MCAST) {
|
2004-08-09 17:30:16 +04:00
|
|
|
printf("page %d before:", page);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
printf(" %02x", indaddr[page * 8 + i]);
|
2001-07-01 05:57:29 +04:00
|
|
|
printf("\n");
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
2001-07-01 05:57:29 +04:00
|
|
|
#endif
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
|
|
|
|
PAGE(sc, 0x50 + page);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_region_1(bst, bsh, IA, &indaddr[page * 8],
|
|
|
|
page == 7 ? 4 : 8);
|
2004-08-09 17:30:16 +04:00
|
|
|
/*
|
|
|
|
* XXX
|
|
|
|
* Without this delay, the address registers on my CE2 get
|
|
|
|
* trashed the first and I have to cycle it. I have no idea
|
|
|
|
* why. - mycroft, 2004/08/09
|
|
|
|
*/
|
|
|
|
DELAY(50);
|
|
|
|
|
|
|
|
#ifdef XIDEBUG
|
|
|
|
if (xidebug & XID_MCAST) {
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_read_region_1(bst, bsh, IA,
|
2004-08-09 17:30:16 +04:00
|
|
|
&indaddr[page * 8], page == 7 ? 4 : 8);
|
|
|
|
printf("page %d after: ", page);
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
printf(" %02x", indaddr[page * 8 + i]);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
#endif
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
|
|
|
|
PAGE(sc, 0x42);
|
|
|
|
x = SWC1_IND_ADDR;
|
|
|
|
if (ifp->if_flags & IFF_PROMISC)
|
|
|
|
x |= SWC1_PROMISC;
|
2004-08-09 08:47:40 +04:00
|
|
|
if (ifp->if_flags & (IFF_ALLMULTI|IFF_PROMISC))
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
x |= SWC1_MCAST_PROM;
|
|
|
|
if (!LIST_FIRST(&sc->sc_mii.mii_phys))
|
|
|
|
x |= SWC1_AUTO_MEDIA;
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(sc->sc_bst, sc->sc_bsh, SWC1, x);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_cycle_power(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_cycle_power()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
PAGE(sc, 4);
|
|
|
|
DELAY(1);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP1, 0);
|
2004-08-12 22:23:50 +04:00
|
|
|
tsleep(&xi_cycle_power, PWAIT, "xipwr1", hz * 40 / 1000);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP1, POWER_UP);
|
2000-06-06 03:14:22 +04:00
|
|
|
else
|
|
|
|
/* XXX What is bit 2 (aka AIC)? */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP1, POWER_UP | 4);
|
2004-08-12 22:23:50 +04:00
|
|
|
tsleep(&xi_cycle_power, PWAIT, "xipwr2", hz * 20 / 1000);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
STATIC void
|
2000-06-06 03:14:22 +04:00
|
|
|
xi_full_reset(sc)
|
|
|
|
struct xi_softc *sc;
|
|
|
|
{
|
|
|
|
bus_space_tag_t bst = sc->sc_bst;
|
|
|
|
bus_space_handle_t bsh = sc->sc_bsh;
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
u_int8_t x;
|
2000-06-06 03:14:22 +04:00
|
|
|
|
2000-06-09 12:22:13 +04:00
|
|
|
DPRINTF(XID_CONFIG, ("xi_full_reset()\n"));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/* Do an as extensive reset as possible on all functions. */
|
|
|
|
xi_cycle_power(sc);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, CR, SOFT_RESET);
|
2004-08-12 22:23:50 +04:00
|
|
|
tsleep(&xi_full_reset, PWAIT, "xirst1", hz * 20 / 1000);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, CR, 0);
|
2004-08-12 22:23:50 +04:00
|
|
|
tsleep(&xi_full_reset, PWAIT, "xirst2", hz * 20 / 1000);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
PAGE(sc, 4);
|
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {
|
2000-06-06 03:14:22 +04:00
|
|
|
/*
|
|
|
|
* Drive GP1 low to power up ML6692 and GP2 high to power up
|
2003-02-22 08:06:36 +03:00
|
|
|
* the 10MHz chip. XXX What chip is that? The phy?
|
2000-06-06 03:14:22 +04:00
|
|
|
*/
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP0, GP1_OUT | GP2_OUT | GP2_WR);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
2004-08-12 22:23:50 +04:00
|
|
|
tsleep(&xi_full_reset, PWAIT, "xirst3", hz * 500 / 1000);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/* Get revision information. XXX Symbolic constants. */
|
2004-08-12 23:42:03 +04:00
|
|
|
sc->sc_rev = bus_space_read_1(bst, bsh, BV) &
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
((sc->sc_chipset >= XI_CHIPSET_MOHAWK) ? 0x70 : 0x30) >> 4;
|
|
|
|
DPRINTF(XID_CONFIG, ("xi: rev=%02x\n", sc->sc_rev));
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/* Media selection. XXX Maybe manual overriding too? */
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_chipset < XI_CHIPSET_MOHAWK) {
|
2000-06-06 03:14:22 +04:00
|
|
|
/*
|
|
|
|
* XXX I have no idea what this really does, it is from the
|
|
|
|
* Linux driver.
|
|
|
|
*/
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, GP0, GP1_OUT);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
2004-08-12 22:23:50 +04:00
|
|
|
tsleep(&xi_full_reset, PWAIT, "xirst4", hz * 40 / 1000);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Disable source insertion.
|
|
|
|
* XXX Dingo does not have this bit, but Linux does it unconditionally.
|
|
|
|
*/
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_chipset < XI_CHIPSET_DINGO) {
|
2000-06-06 03:14:22 +04:00
|
|
|
PAGE(sc, 0x42);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, SWC0, 0x20);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the local memory dividing line. */
|
|
|
|
if (sc->sc_rev != 1) {
|
|
|
|
PAGE(sc, 2);
|
|
|
|
/* XXX Symbolic constant preferrable. */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_2(bst, bsh, RBS0, 0x2000);
|
2000-06-06 03:14:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Apparently the receive byte pointer can be bad after a reset, so
|
|
|
|
* we hardwire it correctly.
|
|
|
|
*/
|
|
|
|
PAGE(sc, 0);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_2(bst, bsh, DO0, DO_CHG_OFFSET);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/* Setup ethernet MAC registers. XXX Symbolic constants. */
|
|
|
|
PAGE(sc, 0x40);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, RX0MSK,
|
2000-06-06 03:14:22 +04:00
|
|
|
PKT_TOO_LONG | CRC_ERR | RX_OVERRUN | RX_ABORT | RX_OK);
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, TX0MSK,
|
2000-06-06 03:14:22 +04:00
|
|
|
CARRIER_LOST | EXCESSIVE_COLL | TX_UNDERRUN | LATE_COLLISION |
|
|
|
|
SQE | TX_ABORT | TX_OK);
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
if (sc->sc_chipset < XI_CHIPSET_DINGO)
|
2000-06-06 03:14:22 +04:00
|
|
|
/* XXX From Linux, dunno what 0xb0 means. */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, TX1MSK, 0xb0);
|
|
|
|
bus_space_write_1(bst, bsh, RXST0, 0);
|
|
|
|
bus_space_write_1(bst, bsh, TXST0, 0);
|
|
|
|
bus_space_write_1(bst, bsh, TXST1, 0);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
PAGE(sc, 2);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
Split "xi" into a "xirc" frontend (similar to mhzc; it attaches two child
devices) and a "xi" backend.
My CE2 and CEM2 cards are now probed correctly. However, there are still
some problems with one model of the CE2, and the CEM2 doesn't seem to get
any modem interrupts.
While I'm at it, fix several bugs:
* The tuple scan for the MAC address was broken in multiple ways.
* xi_intr() did not deal well with a shared interrupt.
* We were setting the wrong page number to look at the receive status. (How
did this work???)
* Remove the xi_full_reset() from xi_reset(). Move the parts of
xi_full_reset() needed to undo the effect of xi_stop() into xi_init(). This
allows a stop/init pair to DTRT, and much quicker, as used by various
ioctl()s.
* Set the TRS register before reading the TSO register, as the Linux driver
does. While I'm at it, fix the name.
* Fix numerous problems with xi_set_address(). "Where do I begin?" There's a
chance that multicast works now, but I haven't tested it.
* Explicitly clear the MSR register, and also force SELECT_MII to 0 if we
didn't find any PHYs.
* Clean up some cruft that appears to be bogus.
Probably needs more work, but it's a start.
2004-08-08 09:56:08 +04:00
|
|
|
/* Enable MII function if available. */
|
|
|
|
x = 0;
|
|
|
|
if (LIST_FIRST(&sc->sc_mii.mii_phys))
|
|
|
|
x |= SELECT_MII;
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, MSR, x);
|
2004-08-12 22:23:50 +04:00
|
|
|
tsleep(&xi_full_reset, PWAIT, "xirst5", hz * 20 / 1000);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/* Configure the LED registers. */
|
|
|
|
/* XXX This is not good for 10base2. */
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, LED,
|
2004-08-08 10:37:17 +04:00
|
|
|
(LED_TX_ACT << LED1_SHIFT) | (LED_10MB_LINK << LED0_SHIFT));
|
|
|
|
if (sc->sc_chipset >= XI_CHIPSET_DINGO)
|
2004-08-12 23:42:03 +04:00
|
|
|
bus_space_write_1(bst, bsh, LED3, LED_100MB_LINK << LED3_SHIFT);
|
2000-06-06 03:14:22 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The Linux driver says this:
|
|
|
|
* We should switch back to page 0 to avoid a bug in revision 0
|
|
|
|
* where regs with offset below 8 can't be read after an access
|
|
|
|
* to the MAC registers.
|
|
|
|
*/
|
|
|
|
PAGE(sc, 0);
|
|
|
|
}
|