revert changes I made a long time ago. This should undo the changes which are causing problems on some non-x86 platforms. I'll probsably redo some of these changes, but after the next release branch.

This commit is contained in:
explorer 2002-01-05 20:10:53 +00:00
parent 73c2346377
commit a40b01901f
4 changed files with 50 additions and 272 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: wi.c,v 1.29 2001/11/13 13:14:46 lukem Exp $ */
/* $NetBSD: wi.c,v 1.30 2002/01/05 20:10:53 explorer Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.29 2001/11/13 13:14:46 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.30 2002/01/05 20:10:53 explorer Exp $");
#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
@ -104,8 +104,6 @@ __KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.29 2001/11/13 13:14:46 lukem Exp $");
#include <dev/ic/wireg.h>
#include <dev/ic/wivar.h>
#define STATS_FREQUENCY (60 * hz) /* collect stats every 60 seconds */
static void wi_reset __P((struct wi_softc *));
static int wi_ioctl __P((struct ifnet *, u_long, caddr_t));
static void wi_start __P((struct ifnet *));
@ -126,8 +124,7 @@ static int wi_write_data __P((struct wi_softc *, int,
int, caddr_t, int));
static int wi_seek __P((struct wi_softc *, int, int, int));
static int wi_alloc_nicmem __P((struct wi_softc *, int, int *));
static void wi_inquire_stats __P((void *));
static void wi_inquire_scan __P((void *));
static void wi_inquire __P((void *));
static int wi_setdef __P((struct wi_softc *, struct wi_req *));
static int wi_getdef __P((struct wi_softc *, struct wi_req *));
static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int));
@ -162,8 +159,7 @@ wi_attach(sc)
s = splnet();
callout_init(&sc->wi_stats_ch);
callout_init(&sc->wi_scan_ch);
callout_init(&sc->wi_inquire_ch);
/* Make sure interrupts are disabled. */
CSR_WRITE_2(sc, WI_INT_EN, 0);
@ -228,8 +224,6 @@ wi_attach(sc)
sc->wi_roaming = WI_DEFAULT_ROAMING;
sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
memset(&sc->wi_results, 0, sizeof (sc->wi_results));
/*
* Read the default channel from the NIC. This may vary
* depending on the country where the NIC was purchased, so
@ -293,10 +287,6 @@ static void wi_rxeof(sc)
struct wi_frame rx_frame;
struct mbuf *m;
int id;
u_int16_t msg_type;
u_int16_t status;
u_int16_t frame_ctl;
u_int16_t port;
ifp = sc->sc_ifp;
@ -308,62 +298,10 @@ static void wi_rxeof(sc)
return;
}
status = le16toh(rx_frame.wi_status);
frame_ctl = le16toh(rx_frame.wi_frame_ctl);
port = (status >> 8) & 0x07;
msg_type = status & WI_RXSTAT_MSG_TYPE;
/*
* Drop packets with CRC errors here. We may want the others,
* since we may be doing interesting things with undecryptable
* packets, like analyzing them in userland.
*/
if (status & WI_STAT_BADCRC) {
ifp->if_ierrors++;
return;
}
if (port == 7) {
if ((le16toh(rx_frame.wi_dat_len) + 60) > MCLBYTES)
return;
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL) {
ifp->if_ierrors++;
return;
}
MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
m_freem(m);
ifp->if_ierrors++;
return;
}
memcpy(mtod(m, caddr_t), &rx_frame, 60);
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len =
le16toh(rx_frame.wi_dat_len) + 60;
if (wi_read_data(sc, id, 60, mtod(m, caddr_t) + 60,
m->m_len - 60)) {
m_freem(m);
ifp->if_ierrors++;
return;
}
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
#endif
m_freem(m);
return;
}
/*
* Drop undecryptable or packets with receive errors here
*/
if (status & WI_STAT_ERRSTAT) {
if (le16toh(rx_frame.wi_status) & WI_STAT_ERRSTAT) {
ifp->if_ierrors++;
return;
}
@ -446,14 +384,6 @@ static void wi_rxeof(sc)
bpf_mtap(ifp->if_bpf, m);
#endif
/*
* Discard packets which are not data packets
*/
if (WLAN_FC_GET_TYPE(frame_ctl) != WLAN_FC_TYPE_DATA) {
m_freem(m);
return;
}
/* Receive packet. */
(*ifp->if_input)(ifp, m);
}
@ -475,7 +405,7 @@ static void wi_txeof(sc, status)
return;
}
void wi_inquire_stats(xsc)
void wi_inquire(xsc)
void *xsc;
{
struct wi_softc *sc;
@ -487,7 +417,7 @@ void wi_inquire_stats(xsc)
if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
return;
callout_reset(&sc->wi_stats_ch, STATS_FREQUENCY, wi_inquire_stats, sc);
callout_reset(&sc->wi_inquire_ch, hz * 60, wi_inquire, sc);
/* Don't do this while we're transmitting */
if (ifp->if_flags & IFF_OACTIVE)
@ -496,31 +426,6 @@ void wi_inquire_stats(xsc)
wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
}
void wi_inquire_scan(xsc)
void *xsc;
{
struct wi_softc *sc;
struct ifnet *ifp;
sc = xsc;
ifp = &sc->sc_ethercom.ec_if;
if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
return;
if (sc->wi_results.scanning > 0)
callout_reset(&sc->wi_scan_ch, sc->wi_results.scanning,
wi_inquire_scan, sc);
else
callout_stop(&sc->wi_scan_ch);
/* Don't do this while we're transmitting */
if (ifp->if_flags & IFF_OACTIVE)
return;
wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS);
}
void wi_update_stats(sc)
struct wi_softc *sc;
{
@ -537,55 +442,28 @@ void wi_update_stats(sc)
wi_read_data(sc, id, 0, (char *)&gen, 4);
switch (gen.wi_type) {
case WI_INFO_COUNTERS:
/* some card versions have a larger stats structure */
len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
ptr = (u_int32_t *)&sc->wi_stats;
if (gen.wi_type != WI_INFO_COUNTERS)
return;
for (i = 0; i < len; i++) {
t = CSR_READ_2(sc, WI_DATA1);
/* some card versions have a larger stats structure */
len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
ptr = (u_int32_t *)&sc->wi_stats;
for (i = 0; i < len; i++) {
t = CSR_READ_2(sc, WI_DATA1);
#ifdef WI_HERMES_STATS_WAR
if (t > 0xF000)
t = ~t & 0xFFFF;
if (t > 0xF000)
t = ~t & 0xFFFF;
#endif
ptr[i] += t;
}
ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
sc->wi_stats.wi_tx_multi_retries +
sc->wi_stats.wi_tx_retry_limit;
break;
case WI_INFO_SCAN_RESULTS:
microtime(&sc->wi_results.lastscan);
for (i = 0 ; i < gen.wi_len - 1 ; i++) {
t = CSR_READ_2(sc, WI_DATA1);
if (i < WI_SCAN_RESULTS_MAXLEN)
sc->wi_results.scan_results[i] = t;
}
if (gen.wi_len - 1 <= WI_SCAN_RESULTS_MAXLEN) {
sc->wi_results.len = gen.wi_len - 1;
sc->wi_results.truncated = 0;
} else {
sc->wi_results.len = WI_SCAN_RESULTS_MAXLEN;
sc->wi_results.truncated = 1;
}
break;
default:
#if 0
printf("Got info type: %04x\n", gen.wi_type);
#endif
for (i = 0; i < gen.wi_len; i++) {
t = CSR_READ_2(sc, WI_DATA1);
#if 0
printf("[0x%02x] = 0x%04x\n", i, t);
#endif
}
break;
ptr[i] += t;
}
ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
sc->wi_stats.wi_tx_multi_retries +
sc->wi_stats.wi_tx_retry_limit;
return;
}
int wi_intr(arg)
@ -1282,11 +1160,10 @@ wi_ioctl(ifp, command, data)
u_long command;
caddr_t data;
{
int i, s, error = 0;
int s, error = 0;
struct wi_softc *sc = ifp->if_softc;
struct wi_req wreq;
struct ifreq *ifr;
struct ifdrv *ifd;
struct proc *p = curproc;
struct ieee80211_nwid nwid;
@ -1355,34 +1232,28 @@ wi_ioctl(ifp, command, data)
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
if (error)
break;
switch (wreq.wi_type) {
case WI_RID_IFACE_STATS:
if (wreq.wi_type == WI_RID_IFACE_STATS) {
/* XXX native byte order */
memcpy((char *)&wreq.wi_val, (char *)&sc->wi_stats,
sizeof(sc->wi_stats));
sizeof(sc->wi_stats));
wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
break;
case WI_RID_DEFLT_CRYPT_KEYS:
} else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
/* For non-root user, return all-zeroes keys */
if (suser(p->p_ucred, &p->p_acflag))
memset((char *)&wreq, 0,
sizeof(struct wi_ltv_keys));
sizeof(struct wi_ltv_keys));
else
memcpy((char *)&wreq, (char *)&sc->wi_keys,
sizeof(struct wi_ltv_keys));
break;
default:
sizeof(struct wi_ltv_keys));
} else {
if (sc->sc_enabled == 0)
error = wi_getdef(sc, &wreq);
else if (wi_read_record(sc,
(struct wi_ltv_gen *)&wreq))
else if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq))
error = EINVAL;
break;
}
if (error == 0)
error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
break;
case SIOCSWAVELAN:
error = suser(p->p_ucred, &p->p_acflag);
if (error)
@ -1390,16 +1261,13 @@ wi_ioctl(ifp, command, data)
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
if (error)
break;
switch (wreq.wi_type) {
case WI_RID_IFACE_STATS:
if (wreq.wi_type == WI_RID_IFACE_STATS) {
error = EINVAL;
break;
case WI_RID_MGMT_XMIT:
} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
wreq.wi_len);
break;
default:
wreq.wi_len);
} else {
if (sc->sc_enabled != 0)
error = wi_write_record(sc,
(struct wi_ltv_gen *)&wreq);
@ -1408,67 +1276,8 @@ wi_ioctl(ifp, command, data)
if (error == 0 && sc->sc_enabled != 0)
/* Reinitialize WaveLAN. */
wi_init(ifp);
break;
}
break;
case SIOCSDRVSPEC:
error = suser(p->p_ucred, &p->p_acflag);
if (error)
break;
ifd = (struct ifdrv *)data;
switch (ifd->ifd_cmd) {
case WI_IOCTL_SET_SCAN:
error = copyin(ifd->ifd_data, &i, sizeof (i));
if (error)
break;
sc->wi_results.scanning = i;
if (sc->wi_results.scanning > 0)
callout_reset(&sc->wi_scan_ch,
sc->wi_results.scanning,
wi_inquire_scan, sc);
else
callout_stop(&sc->wi_scan_ch);
break;
/*
* Experimental XXXMLG
*/
case WI_IOCTL_SET_TESTMODE:
error = copyin(ifd->ifd_data, &i, sizeof (i));
if (error)
break;
if (i) {
wi_cmd(sc, WI_CMD_TEST | WI_TEST_MONITOR << 8,
0);
printf("wi test mode enabled\n");
} else {
wi_cmd(sc, WI_CMD_TEST | WI_TEST_STOP << 8, 0);
printf("wi test mode disabled\n");
}
break;
default:
error = EINVAL;
break;
}
break;
case SIOCGDRVSPEC:
ifd = (struct ifdrv *)data;
switch (ifd->ifd_cmd) {
case WI_IOCTL_GET_SCAN_RESULTS:
error = copyout(&sc->wi_results, ifd->ifd_data,
sizeof(struct wi_scan_results));
break;
default:
error = EINVAL;
break;
}
break;
case SIOCG80211NWID:
if (sc->sc_enabled == 0) {
/* Return the desired ID */
@ -1649,7 +1458,7 @@ wi_init(ifp)
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
callout_reset(&sc->wi_stats_ch, STATS_FREQUENCY, wi_inquire_stats, sc);
callout_reset(&sc->wi_inquire_ch, hz * 60, wi_inquire, sc);
out:
if (error) {
@ -1794,8 +1603,7 @@ wi_stop(ifp, disable)
CSR_WRITE_2(sc, WI_INT_EN, 0);
wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
callout_stop(&sc->wi_stats_ch);
callout_stop(&sc->wi_scan_ch);
callout_stop(&sc->wi_inquire_ch);
if (disable) {
if (sc->sc_enabled) {
@ -1947,8 +1755,7 @@ wi_detach(sc)
return (0);
s = splnet();
callout_stop(&sc->wi_stats_ch);
callout_stop(&sc->wi_scan_ch);
callout_stop(&sc->wi_inquire_ch);
/* Delete all remaining media. */
ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);

View File

@ -1,4 +1,4 @@
/* $NetBSD: wi_ieee.h,v 1.6 2001/11/11 00:34:52 christos Exp $ */
/* $NetBSD: wi_ieee.h,v 1.7 2002/01/05 20:10:53 explorer Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@ -66,7 +66,7 @@
* Technically I don't think there's a limit to a record
* length. The largest record is the one that contains the CIS
* data, which is 240 words long, so 256 should be a safe
* value. But 512 is more safe?
* value.
*/
#define WI_MAX_DATALEN 512
@ -76,13 +76,6 @@ struct wi_req {
u_int16_t wi_val[WI_MAX_DATALEN];
};
#define WI_IOCTL_SET_SCAN 1
#define WI_IOCTL_GET_SCAN 2
#define WI_IOCTL_GET_SCAN_RESULTS 3
#define WI_IOCTL_SET_TESTMODE 4
#define WI_IOCTL_MGMT_XMIT 5
#define WI_IOCTL_IFACE_STATS 6
/*
* Private LTV records (interpreted only by the driver). This is
* a minor kludge to allow reading the interface statistics from
@ -188,7 +181,9 @@ struct wi_counters {
};
/*
* results of last ap scan
* These are all the LTV record types that we can read or write
* from the WaveLAN. Not all of them are temendously useful, but I
* list as many as I know about here for completeness.
*/
#define WI_SCAN_RESULTS_MAXLEN 512
struct wi_scan_results {

View File

@ -1,4 +1,4 @@
/* $NetBSD: wireg.h,v 1.13 2001/11/11 00:16:07 christos Exp $ */
/* $NetBSD: wireg.h,v 1.14 2002/01/05 20:10:53 explorer Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@ -206,18 +206,9 @@
#define WI_CMD_INQUIRE 0x0011
#define WI_CMD_ACCESS 0x0021
#define WI_CMD_PROGRAM 0x0022
#define WI_CMD_READMIF 0x0030 /* prism2 only? */
#define WI_CMD_WRITEMIF 0x0031 /* prism2 only? */
#define WI_CMD_TEST 0x0038 /* prism2 only? */
#define WI_CMD_CODE_MASK 0x003F
/*
* prism2 test mode commands
*/
#define WI_TEST_MONITOR 0x000b
#define WI_TEST_STOP 0x000f
/*
* Reclaim qualifier bit, applicable to the
* TX and INQUIRE commands.
@ -281,7 +272,7 @@
#define WI_EV_RES 0x4000 /* controller h/w error (time out) */
#define WI_EV_INFO_DROP 0x2000 /* no RAM to build unsolicited frame */
#define WI_EV_NO_CARD 0x0800 /* card removed (hunh?) */
#define WI_EV_AWAKE 0x0100
#define WI_EV_DUIF_RX 0x0400 /* wavelan management packet received */
#define WI_EV_INFO 0x0080 /* async info frame */
#define WI_EV_CMD 0x0010 /* command completed */
#define WI_EV_ALLOC 0x0008 /* async alloc/reclaim completed */
@ -534,7 +525,6 @@ struct wi_frame {
u_int16_t wi_rsvd2; /* 0x08 */
u_int16_t wi_rsvd3; /* 0x0A */
u_int16_t wi_tx_ctl; /* 0x0C */
/* 802.11 */
u_int16_t wi_frame_ctl; /* 0x0E */
u_int16_t wi_id; /* 0x10 */
u_int8_t wi_addr1[6]; /* 0x12 */
@ -543,12 +533,10 @@ struct wi_frame {
u_int16_t wi_seq_ctl; /* 0x24 */
u_int8_t wi_addr4[6]; /* 0x26 */
u_int16_t wi_dat_len; /* 0x2C */
/* 802.3 */
u_int8_t wi_dst_addr[6]; /* 0x2E */
u_int8_t wi_src_addr[6]; /* 0x34 */
u_int16_t wi_len; /* 0x3A */
/* SNAP header */
u_int16_t wi_dat[3]; /* 0x3C */
u_int16_t wi_dat[3]; /* 0x3C */ /* SNAP header */
u_int16_t wi_type; /* 0x42 */
};
@ -565,16 +553,6 @@ struct wi_frame {
#define WI_STAT_WMP_MSG 0x6000 /* WaveLAN-II management protocol */
#define WI_RXSTAT_MSG_TYPE 0xE000
#define BIT(x) (1 << (x))
#define WLAN_FC_GET_TYPE(fc) (((fc) & (BIT(3) | BIT(2))) >> 2)
#define WLAN_FC_GET_STYPE(fc) \
(((fc) & (BIT(7) | BIT(6) | BIT(5) | BIT(4))) >> 4)
#define WLAN_FC_TYPE_MGMT 0
#define WLAN_FC_TYPE_CTRL 1
#define WLAN_FC_TYPE_DATA 2
#define WI_ENC_TX_802_3 0x00
#define WI_ENC_TX_802_11 0x11
#define WI_ENC_TX_E_II 0x0E

View File

@ -1,4 +1,4 @@
/* $NetBSD: wivar.h,v 1.6 2001/10/13 15:00:24 ichiro Exp $ */
/* $NetBSD: wivar.h,v 1.7 2002/01/05 20:10:53 explorer Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@ -55,8 +55,7 @@ struct wi_softc {
bus_space_tag_t sc_iot; /* bus cookie */
bus_space_handle_t sc_ioh; /* bus i/o handle */
struct callout wi_stats_ch;
struct callout wi_scan_ch;
struct callout wi_inquire_ch;
u_int8_t sc_macaddr[ETHER_ADDR_LEN];
@ -88,7 +87,6 @@ struct wi_softc {
int wi_tx_key;
struct wi_ltv_keys wi_keys;
struct wi_counters wi_stats;
struct wi_scan_results wi_results;
};
int wi_attach __P((struct wi_softc *));