Integrate the air-tools 0.2 from dachb0den labs.
o This moves the common.h file into if_wavelan_ieee.h Submitted by: h1kari@dachb0den.com
This commit is contained in:
parent
fd503e698c
commit
8cf3aa5fce
@ -319,5 +319,363 @@ struct wi_ltv_keys {
|
||||
#define WI_RID_MAC_PROC_DELAY 0xFDC5 /* MAC processing delay time */
|
||||
#define WI_RID_DATA_RATES 0xFDC6 /* supported data rates */
|
||||
|
||||
/*
|
||||
* bsd-airtools v0.2 - source-mods v0.2 [common.h]
|
||||
* by h1kari - (c) Dachb0den Labs 2001
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Dachb0den Labs.
|
||||
* David Hulton <h1kari@dachb0den.com>. 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 David Hulton.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY David Hulton AND CONTRIBUTORS ``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 David Hulton OR THE VOICES IN HIS HEAD
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* standard hermes recieve frame used by wavelan/prism2 cards
|
||||
*/
|
||||
struct wi_rx_frame {
|
||||
/*
|
||||
* hermes prefix header. supplies information on the current status of
|
||||
* the network and various other statistics gathered from the
|
||||
* management/control frames as used internally.
|
||||
*/
|
||||
u_int16_t wi_status;
|
||||
u_int16_t wi_ts0;
|
||||
u_int16_t wi_ts1;
|
||||
u_int8_t wi_silence;
|
||||
u_int8_t wi_signal;
|
||||
u_int8_t wi_rate;
|
||||
u_int8_t wi_rx_flow;
|
||||
u_int16_t wi_rsvd0;
|
||||
u_int16_t wi_rsvd1;
|
||||
/*
|
||||
* standard 80211 frame header. all packets have to use this header as
|
||||
* per the AN9900 from intersil, even management/control. for
|
||||
* management packets, they just threw the header into the data field,
|
||||
* but for control packets the headers are lost in translation and
|
||||
* therefore not all control packet info can be displayed.
|
||||
*/
|
||||
u_int16_t wi_frame_ctl;
|
||||
u_int16_t wi_id;
|
||||
u_int8_t wi_addr1[6];
|
||||
u_int8_t wi_addr2[6];
|
||||
u_int8_t wi_addr3[6];
|
||||
u_int16_t wi_seq_ctl;
|
||||
u_int8_t wi_addr4[6];
|
||||
u_int16_t wi_dat_len;
|
||||
/*
|
||||
* another wierdity with the drivers. they append a 802.3 header which
|
||||
* is somewhat redundant, since all the same data is provided in the
|
||||
* 802.11 header.
|
||||
*/
|
||||
u_int8_t wi_dst_addr[6];
|
||||
u_int8_t wi_src_addr[6];
|
||||
u_int16_t wi_len;
|
||||
};
|
||||
#define WI_DATA_HDRLEN WI_802_11_OFFSET
|
||||
#define WI_MGMT_HDRLEN WI_802_11_OFFSET_RAW
|
||||
#define WI_CTL_HDRLEN WI_802_11_OFFSET_RAW
|
||||
|
||||
|
||||
/*
|
||||
* all data packets have a snap (sub-network access protocol) header that
|
||||
* isn't entirely definied, but added for ethernet compatibility.
|
||||
*/
|
||||
struct wi_snap_frame {
|
||||
u_int16_t wi_dat[3];
|
||||
u_int16_t wi_type;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* management frame headers
|
||||
* note: all management frames consist of a static header and variable length
|
||||
* fields.
|
||||
*/
|
||||
|
||||
/*
|
||||
* variable length field structure
|
||||
*/
|
||||
struct wi_mgmt_var_hdr {
|
||||
u_int8_t wi_code;
|
||||
u_int8_t wi_len;
|
||||
u_int8_t wi_data[256];
|
||||
};
|
||||
|
||||
/*
|
||||
* management beacon frame prefix
|
||||
*/
|
||||
struct wi_mgmt_beacon_hdr {
|
||||
u_int32_t wi_ts0;
|
||||
u_int32_t wi_ts1;
|
||||
u_int16_t wi_interval;
|
||||
u_int16_t wi_capinfo;
|
||||
};
|
||||
|
||||
/*
|
||||
* ibss announcement traffic indication message (atim) frame
|
||||
* note: no parameters
|
||||
*/
|
||||
|
||||
/*
|
||||
* management disassociation frame
|
||||
*/
|
||||
struct wi_mgmt_disas_hdr {
|
||||
u_int16_t wi_reason;
|
||||
};
|
||||
|
||||
/*
|
||||
* management association request frame prefix
|
||||
*/
|
||||
struct wi_mgmt_asreq_hdr {
|
||||
u_int16_t wi_capinfo;
|
||||
u_int16_t wi_interval;
|
||||
};
|
||||
|
||||
/*
|
||||
* management association response frame prefix
|
||||
*/
|
||||
struct wi_mgmt_asresp_hdr {
|
||||
u_int16_t wi_capinfo;
|
||||
u_int16_t wi_status;
|
||||
u_int16_t wi_aid;
|
||||
};
|
||||
|
||||
/*
|
||||
* management reassociation request frame prefix
|
||||
*/
|
||||
struct wi_mgmt_reasreq_hdr {
|
||||
u_int16_t wi_capinfo;
|
||||
u_int16_t wi_interval;
|
||||
u_int8_t wi_currap[6];
|
||||
};
|
||||
|
||||
/*
|
||||
* management reassociation response frame prefix
|
||||
*/
|
||||
struct wi_mgmt_reasresp_hdr {
|
||||
u_int16_t wi_capinfo;
|
||||
u_int16_t wi_status;
|
||||
u_int16_t wi_aid;
|
||||
};
|
||||
|
||||
/*
|
||||
* management probe request frame prefix
|
||||
* note: no static parameters, only variable length
|
||||
*/
|
||||
|
||||
/*
|
||||
* management probe response frame prefix
|
||||
*/
|
||||
struct wi_mgmt_proberesp_hdr {
|
||||
u_int32_t wi_ts0;
|
||||
u_int32_t wi_ts1;
|
||||
u_int16_t wi_interval;
|
||||
u_int16_t wi_capinfo;
|
||||
};
|
||||
|
||||
/*
|
||||
* management authentication frame prefix
|
||||
*/
|
||||
struct wi_mgmt_auth_hdr {
|
||||
u_int16_t wi_algo;
|
||||
u_int16_t wi_seq;
|
||||
u_int16_t wi_status;
|
||||
};
|
||||
|
||||
/*
|
||||
* management deauthentication frame
|
||||
*/
|
||||
struct wi_mgmt_deauth_hdr {
|
||||
u_int16_t wi_reason;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* rid configuration register definitions
|
||||
*/
|
||||
#define WI_RID_SCAN_REQ 0xFCE1 /* scan request information */
|
||||
#define WI_RID_SCAN_RES 0xFD88 /* scan result information */
|
||||
|
||||
#define WI_RID_PROCFRAME 0x3137 /* Return full frame information */
|
||||
#define WI_RID_PRISM2 0x3138 /* tell if we're a prism2 card or not */
|
||||
|
||||
|
||||
/*
|
||||
* 802.11 definitions
|
||||
*/
|
||||
#define WI_STAT_BADCRC 0x0001
|
||||
#define WI_STAT_UNDECRYPTABLE 0x0002
|
||||
#define WI_STAT_ERRSTAT 0x0003
|
||||
#define WI_STAT_MAC_PORT 0x0700
|
||||
#define WI_STAT_1042 0x2000
|
||||
#define WI_STAT_TUNNEL 0x4000
|
||||
#define WI_STAT_WMP_MSG 0x6000
|
||||
#define WI_RXSTAT_MSG_TYPE 0xE000
|
||||
|
||||
#define WI_FCTL_OPT_MASK 0xFF00
|
||||
#define WI_AID_SET 0xC000
|
||||
#define WI_AID_MASK 0x3FFF
|
||||
#define WI_SCTL_FRAGNUM_MASK 0x000F
|
||||
#define WI_SCTL_SEQNUM_MASK 0xFFF0
|
||||
|
||||
#define WI_STAT_UNSPEC_FAIL 1
|
||||
#define WI_STAT_CAPINFO_FAIL 10
|
||||
#define WI_STAT_REAS_DENY 11
|
||||
#define WI_STAT_ASSOC_DENY 12
|
||||
#define WI_STAT_ALGO_FAIL 13
|
||||
#define WI_STAT_SEQ_FAIL 14
|
||||
#define WI_STAT_CHAL_FAIL 15
|
||||
#define WI_STAT_TOUT_FAIL 16
|
||||
#define WI_STAT_OVERL_DENY 17
|
||||
#define WI_STAT_RATE_DENY 18
|
||||
|
||||
#define WI_FTYPE_MGMT 0x0000
|
||||
#define WI_FTYPE_CTL 0x0004
|
||||
#define WI_FTYPE_DATA 0x0008
|
||||
|
||||
#define WI_FCTL_VERS 0x0002
|
||||
#define WI_FCTL_FTYPE 0x000C
|
||||
#define WI_FCTL_STYPE 0x00F0
|
||||
#define WI_FCTL_TODS 0x0100
|
||||
#define WI_FCTL_FROMDS 0x0200
|
||||
#define WI_FCTL_MOREFRAGS 0x0400
|
||||
#define WI_FCTL_RETRY 0x0800
|
||||
#define WI_FCTL_PM 0x1000
|
||||
#define WI_FCTL_MOREDATA 0x2000
|
||||
#define WI_FCTL_WEP 0x4000
|
||||
#define WI_FCTL_ORDER 0x8000
|
||||
|
||||
#define WI_FCS_LEN 0x4 /* checksum length */
|
||||
|
||||
|
||||
/*
|
||||
* management definitions
|
||||
*/
|
||||
#define WI_STYPE_MGMT_ASREQ 0x0000
|
||||
#define WI_STYPE_MGMT_ASRESP 0x0010
|
||||
#define WI_STYPE_MGMT_REASREQ 0x0020
|
||||
#define WI_STYPE_MGMT_REASRESP 0x0030
|
||||
#define WI_STYPE_MGMT_PROBEREQ 0x0040
|
||||
#define WI_STYPE_MGMT_PROBERESP 0x0050
|
||||
#define WI_STYPE_MGMT_BEACON 0x0080
|
||||
#define WI_STYPE_MGMT_ATIM 0x0090
|
||||
#define WI_STYPE_MGMT_DISAS 0x00A0
|
||||
#define WI_STYPE_MGMT_AUTH 0x00B0
|
||||
#define WI_STYPE_MGMT_DEAUTH 0x00C0
|
||||
|
||||
#define WI_CAPINFO_ESS 0x01
|
||||
#define WI_CAPINFO_IBSS 0x02
|
||||
#define WI_CAPINFO_CFPOLL 0x04
|
||||
#define WI_CAPINFO_CFPOLLREQ 0x08
|
||||
#define WI_CAPINFO_PRIV 0x10
|
||||
|
||||
#define WI_REASON_UNSPEC 1
|
||||
#define WI_REASON_AUTH_INVALID 2
|
||||
#define WI_REASON_DEAUTH_LEAVE 3
|
||||
#define WI_REASON_DISAS_INACT 4
|
||||
#define WI_REASON_DISAS_OVERL 5
|
||||
#define WI_REASON_CLASS2 6
|
||||
#define WI_REASON_CLASS3 7
|
||||
#define WI_REASON_DISAS_LEAVE 8
|
||||
#define WI_REASON_NOAUTH 9
|
||||
|
||||
#define WI_VAR_SSID 0
|
||||
#define WI_VAR_SRATES 1
|
||||
#define WI_VAR_FH 2
|
||||
#define WI_VAR_DS 3
|
||||
#define WI_VAR_CF 4
|
||||
#define WI_VAR_TIM 5
|
||||
#define WI_VAR_IBSS 6
|
||||
#define WI_VAR_CHAL 16
|
||||
|
||||
#define WI_VAR_SRATES_MASK 0x7F
|
||||
|
||||
|
||||
/*
|
||||
* control definitions
|
||||
*/
|
||||
#define WI_STYPE_CTL_PSPOLL 0x00A0
|
||||
#define WI_STYPE_CTL_RTS 0x00B0
|
||||
#define WI_STYPE_CTL_CTS 0x00C0
|
||||
#define WI_STYPE_CTL_ACK 0x00D0
|
||||
#define WI_STYPE_CTL_CFEND 0x00E0
|
||||
#define WI_STYPE_CTL_CFENDCFACK 0x00F0
|
||||
|
||||
|
||||
/*
|
||||
* ap scanning structures
|
||||
*/
|
||||
struct wi_scan_res {
|
||||
u_int16_t wi_chan;
|
||||
u_int16_t wi_noise;
|
||||
u_int16_t wi_signal;
|
||||
u_int8_t wi_bssid[6];
|
||||
u_int16_t wi_interval;
|
||||
u_int16_t wi_capinfo;
|
||||
u_int16_t wi_ssid_len;
|
||||
u_int8_t wi_ssid[32];
|
||||
u_int8_t wi_srates[10];
|
||||
u_int8_t wi_rate;
|
||||
u_int8_t wi_rsvd;
|
||||
};
|
||||
#define WI_WAVELAN_RES_SIZE 50
|
||||
|
||||
struct wi_scan_p2_hdr {
|
||||
u_int16_t wi_rsvd;
|
||||
u_int16_t wi_reason;
|
||||
};
|
||||
#define WI_PRISM2_RES_SIZE 62
|
||||
|
||||
|
||||
/*
|
||||
* prism2 debug mode definitions
|
||||
*/
|
||||
#define SIOCSPRISM2DEBUG _IOW('i', 137, struct ifreq)
|
||||
#define SIOCGPRISM2DEBUG _IOWR('i', 138, struct ifreq)
|
||||
|
||||
#define WI_CMD_DEBUG 0x0038 /* prism2 debug */
|
||||
|
||||
#define WI_DEBUG_RESET 0x00
|
||||
#define WI_DEBUG_INIT 0x01
|
||||
#define WI_DEBUG_SLEEP 0x02
|
||||
#define WI_DEBUG_WAKE 0x03
|
||||
#define WI_DEBUG_CHAN 0x08
|
||||
#define WI_DEBUG_DELAYSUPP 0x09
|
||||
#define WI_DEBUG_TXSUPP 0x0A
|
||||
#define WI_DEBUG_MONITOR 0x0B
|
||||
#define WI_DEBUG_LEDTEST 0x0C
|
||||
#define WI_DEBUG_CONTTX 0x0E
|
||||
#define WI_DEBUG_STOPTEST 0x0F
|
||||
#define WI_DEBUG_CONTRX 0x10
|
||||
#define WI_DEBUG_SIGSTATE 0x11
|
||||
#define WI_DEBUG_CALENABLE 0x13
|
||||
#define WI_DEBUG_CONFBITS 0x15
|
||||
|
||||
#endif
|
||||
|
@ -172,6 +172,9 @@ static void wi_get_id(struct wi_softc *, device_t);
|
||||
static int wi_media_change(struct ifnet *);
|
||||
static void wi_media_status(struct ifnet *, struct ifmediareq *);
|
||||
|
||||
static int wi_get_debug(struct wi_softc *, struct wi_req *);
|
||||
static int wi_set_debug(struct wi_softc *, struct wi_req *);
|
||||
|
||||
static device_method_t wi_pccard_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, pccard_compat_probe),
|
||||
@ -248,6 +251,7 @@ static const struct pccard_product wi_pccard_products[] = {
|
||||
PCMCIA_CARD(EMTAC, WLAN, 0),
|
||||
PCMCIA_CARD(ERICSSON, WIRELESSLAN, 0),
|
||||
PCMCIA_CARD(GEMTEK, WLAN, 0),
|
||||
PCMCIA_CARD(HWN, AIRWAY80211, 0),
|
||||
PCMCIA_CARD(INTEL, PRO_WLAN_2011, 0),
|
||||
PCMCIA_CARD(INTERSIL, PRISM2, 0),
|
||||
PCMCIA_CARD(IODATA2, WNB11PCM, 0),
|
||||
@ -712,7 +716,6 @@ wi_rxeof(sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ether_header *eh;
|
||||
struct wi_frame rx_frame;
|
||||
struct mbuf *m;
|
||||
int id;
|
||||
|
||||
@ -720,102 +723,207 @@ wi_rxeof(sc)
|
||||
|
||||
id = CSR_READ_2(sc, WI_RX_FID);
|
||||
|
||||
/* First read in the frame header */
|
||||
if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* if we have the procframe flag set, disregard all this and just
|
||||
* read the data from the device.
|
||||
*/
|
||||
if (sc->wi_procframe || sc->wi_debug.wi_monitor) {
|
||||
struct wi_frame *rx_frame;
|
||||
int datlen, hdrlen;
|
||||
|
||||
if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
|
||||
ifp->if_ierrors++;
|
||||
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;
|
||||
}
|
||||
|
||||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
if (rx_frame.wi_status == WI_STAT_1042 ||
|
||||
rx_frame.wi_status == WI_STAT_TUNNEL ||
|
||||
rx_frame.wi_status == WI_STAT_WMP_MSG) {
|
||||
if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
|
||||
device_printf(sc->dev, "oversized packet received "
|
||||
"(wi_dat_len=%d, wi_status=0x%x)\n",
|
||||
rx_frame.wi_dat_len, rx_frame.wi_status);
|
||||
/* first allocate mbuf for packet storage */
|
||||
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;
|
||||
}
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
|
||||
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
/* now read wi_frame first so we know how much data to read */
|
||||
if (wi_read_data(sc, id, 0, mtod(m, caddr_t),
|
||||
sizeof(struct wi_frame))) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
rx_frame = mtod(m, struct wi_frame *);
|
||||
|
||||
switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) {
|
||||
case 7:
|
||||
switch (rx_frame->wi_frame_ctl & WI_FCTL_FTYPE) {
|
||||
case WI_FTYPE_DATA:
|
||||
hdrlen = WI_DATA_HDRLEN;
|
||||
datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
|
||||
break;
|
||||
case WI_FTYPE_MGMT:
|
||||
hdrlen = WI_MGMT_HDRLEN;
|
||||
datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
|
||||
break;
|
||||
case WI_FTYPE_CTL:
|
||||
/*
|
||||
* prism2 cards don't pass control packets
|
||||
* down properly or consistently, so we'll only
|
||||
* pass down the header.
|
||||
*/
|
||||
hdrlen = WI_CTL_HDRLEN;
|
||||
datlen = 0;
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->dev, "received packet of "
|
||||
"unknown type on port 7\n");
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
hdrlen = WI_DATA_HDRLEN;
|
||||
datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->dev, "received packet on invalid "
|
||||
"port (wi_status=0x%x)\n", rx_frame->wi_status);
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((hdrlen + datlen + 2) > MCLBYTES) {
|
||||
device_printf(sc->dev, "oversized packet received "
|
||||
"(wi_dat_len=%d, wi_status=0x%x)\n",
|
||||
datlen, rx_frame->wi_status);
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (wi_read_data(sc, id, hdrlen, mtod(m, caddr_t) + hdrlen,
|
||||
datlen + 2)) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
m->m_pkthdr.len = m->m_len = hdrlen + datlen;
|
||||
|
||||
ifp->if_ipackets++;
|
||||
|
||||
/* Handle BPF listeners. */
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, m);
|
||||
|
||||
m_freem(m);
|
||||
} else {
|
||||
struct wi_frame rx_frame;
|
||||
|
||||
/* First read in the frame header */
|
||||
if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame,
|
||||
sizeof(rx_frame))) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
|
||||
ifp->if_ierrors++;
|
||||
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;
|
||||
}
|
||||
|
||||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
if (rx_frame.wi_status == WI_STAT_1042 ||
|
||||
rx_frame.wi_status == WI_STAT_TUNNEL ||
|
||||
rx_frame.wi_status == WI_STAT_WMP_MSG) {
|
||||
if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
|
||||
device_printf(sc->dev,
|
||||
"oversized packet received "
|
||||
"(wi_dat_len=%d, wi_status=0x%x)\n",
|
||||
rx_frame.wi_dat_len, rx_frame.wi_status);
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
|
||||
|
||||
#if 0
|
||||
bcopy((char *)&rx_frame.wi_addr1,
|
||||
(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
|
||||
if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
|
||||
bcopy((char *)&rx_frame.wi_addr2,
|
||||
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
||||
} else {
|
||||
bcopy((char *)&rx_frame.wi_addr3,
|
||||
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
||||
}
|
||||
bcopy((char *)&rx_frame.wi_addr1,
|
||||
(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
|
||||
if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
|
||||
bcopy((char *)&rx_frame.wi_addr2,
|
||||
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
||||
} else {
|
||||
bcopy((char *)&rx_frame.wi_addr3,
|
||||
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
||||
}
|
||||
#else
|
||||
bcopy((char *)&rx_frame.wi_dst_addr,
|
||||
(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
|
||||
bcopy((char *)&rx_frame.wi_src_addr,
|
||||
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
||||
bcopy((char *)&rx_frame.wi_dst_addr,
|
||||
(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
|
||||
bcopy((char *)&rx_frame.wi_src_addr,
|
||||
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
||||
#endif
|
||||
|
||||
bcopy((char *)&rx_frame.wi_type,
|
||||
(char *)&eh->ether_type, ETHER_TYPE_LEN);
|
||||
bcopy((char *)&rx_frame.wi_type,
|
||||
(char *)&eh->ether_type, ETHER_TYPE_LEN);
|
||||
|
||||
if (wi_read_data(sc, id, WI_802_11_OFFSET,
|
||||
mtod(m, caddr_t) + sizeof(struct ether_header),
|
||||
m->m_len + 2)) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
if (wi_read_data(sc, id, WI_802_11_OFFSET,
|
||||
mtod(m, caddr_t) + sizeof(struct ether_header),
|
||||
m->m_len + 2)) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if((rx_frame.wi_dat_len +
|
||||
sizeof(struct ether_header)) > MCLBYTES) {
|
||||
device_printf(sc->dev,
|
||||
"oversized packet received "
|
||||
"(wi_dat_len=%d, wi_status=0x%x)\n",
|
||||
rx_frame.wi_dat_len, rx_frame.wi_status);
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
rx_frame.wi_dat_len + sizeof(struct ether_header);
|
||||
|
||||
if (wi_read_data(sc, id, WI_802_3_OFFSET,
|
||||
mtod(m, caddr_t), m->m_len + 2)) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if((rx_frame.wi_dat_len +
|
||||
sizeof(struct ether_header)) > MCLBYTES) {
|
||||
device_printf(sc->dev, "oversized packet received "
|
||||
"(wi_dat_len=%d, wi_status=0x%x)\n",
|
||||
rx_frame.wi_dat_len, rx_frame.wi_status);
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
rx_frame.wi_dat_len + sizeof(struct ether_header);
|
||||
|
||||
if (wi_read_data(sc, id, WI_802_3_OFFSET,
|
||||
mtod(m, caddr_t), m->m_len + 2)) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ifp->if_ipackets++;
|
||||
|
||||
ifp->if_ipackets++;
|
||||
|
||||
/* Receive packet. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
/* Receive packet. */
|
||||
m_adj(m, sizeof(struct ether_header));
|
||||
#ifdef WICACHE
|
||||
wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
|
||||
wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
|
||||
#endif
|
||||
ether_input(ifp, eh, m);
|
||||
ether_input(ifp, eh, m);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -876,7 +984,20 @@ wi_update_stats(sc)
|
||||
|
||||
wi_read_data(sc, id, 0, (char *)&gen, 4);
|
||||
|
||||
if (gen.wi_type != WI_INFO_COUNTERS)
|
||||
/*
|
||||
* if we just got our scan results, copy it over into the scan buffer
|
||||
* so we can return it to anyone that asks for it. (add a little
|
||||
* compatibility with the prism2 scanning mechanism)
|
||||
*/
|
||||
if (gen.wi_type == WI_INFO_SCAN_RESULTS)
|
||||
{
|
||||
sc->wi_scanbuf_len = gen.wi_len;
|
||||
wi_read_data(sc, id, 4, (char *)sc->wi_scanbuf,
|
||||
sc->wi_scanbuf_len * 2);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (gen.wi_type != WI_INFO_COUNTERS)
|
||||
return;
|
||||
|
||||
len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
|
||||
@ -1617,7 +1738,17 @@ wi_ioctl(ifp, command, data)
|
||||
sc->wi_sigitems) / 2) + 1;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
else if (wreq.wi_type == WI_RID_PROCFRAME) {
|
||||
wreq.wi_len = 2;
|
||||
wreq.wi_val[0] = sc->wi_procframe;
|
||||
} else if (wreq.wi_type == WI_RID_PRISM2) {
|
||||
wreq.wi_len = 2;
|
||||
wreq.wi_val[0] = sc->wi_prism2;
|
||||
} else if (wreq.wi_type == WI_RID_SCAN_RES && !sc->wi_prism2) {
|
||||
memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf,
|
||||
sc->wi_scanbuf_len * 2);
|
||||
wreq.wi_len = sc->wi_scanbuf_len;
|
||||
} else {
|
||||
if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
@ -1637,12 +1768,43 @@ wi_ioctl(ifp, command, data)
|
||||
} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
|
||||
error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
|
||||
wreq.wi_len);
|
||||
} else if (wreq.wi_type == WI_RID_PROCFRAME) {
|
||||
sc->wi_procframe = wreq.wi_val[0];
|
||||
/*
|
||||
* if we're getting a scan request from a wavelan card
|
||||
* (non-prism2), send out a cmd_inquire to the card to scan
|
||||
* results for the scan will be received through the info
|
||||
* interrupt handler. otherwise the scan request can be
|
||||
* directly handled by a prism2 card's rid interface.
|
||||
*/
|
||||
} else if (wreq.wi_type == WI_RID_SCAN_REQ && !sc->wi_prism2) {
|
||||
wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
|
||||
} else {
|
||||
error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
|
||||
if (!error)
|
||||
wi_setdef(sc, &wreq);
|
||||
}
|
||||
break;
|
||||
case SIOCGPRISM2DEBUG:
|
||||
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
|
||||
if (error)
|
||||
break;
|
||||
if (!(ifp->if_flags & IFF_RUNNING) || !sc->wi_prism2) {
|
||||
error = EIO;
|
||||
break;
|
||||
}
|
||||
error = wi_get_debug(sc, &wreq);
|
||||
if (error == 0)
|
||||
error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
|
||||
break;
|
||||
case SIOCSPRISM2DEBUG:
|
||||
if ((error = suser(p)))
|
||||
goto out;
|
||||
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
|
||||
if (error)
|
||||
break;
|
||||
error = wi_set_debug(sc, &wreq);
|
||||
break;
|
||||
case SIOCG80211:
|
||||
switch(ireq->i_type) {
|
||||
case IEEE80211_IOC_SSID:
|
||||
@ -2051,9 +2213,10 @@ wi_start(ifp)
|
||||
|
||||
/*
|
||||
* If there's a BPF listner, bounce a copy of
|
||||
* this frame to him.
|
||||
* this frame to him. Also, don't send this to the bpf sniffer
|
||||
* if we're in procframe or monitor sniffing mode.
|
||||
*/
|
||||
if (ifp->if_bpf)
|
||||
if (!(sc->wi_procframe || sc->wi_debug.wi_monitor) && ifp->if_bpf)
|
||||
bpf_mtap(ifp, m0);
|
||||
|
||||
m_freem(m0);
|
||||
@ -2594,3 +2757,146 @@ wi_media_status(ifp, imr)
|
||||
imr->ifm_status |= IFM_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
wi_get_debug(sc, wreq)
|
||||
struct wi_softc *sc;
|
||||
struct wi_req *wreq;
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
wreq->wi_len = 1;
|
||||
|
||||
switch (wreq->wi_type) {
|
||||
case WI_DEBUG_SLEEP:
|
||||
wreq->wi_len++;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_sleep;
|
||||
break;
|
||||
case WI_DEBUG_DELAYSUPP:
|
||||
wreq->wi_len++;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_delaysupp;
|
||||
break;
|
||||
case WI_DEBUG_TXSUPP:
|
||||
wreq->wi_len++;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_txsupp;
|
||||
break;
|
||||
case WI_DEBUG_MONITOR:
|
||||
wreq->wi_len++;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_monitor;
|
||||
break;
|
||||
case WI_DEBUG_LEDTEST:
|
||||
wreq->wi_len += 3;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_ledtest;
|
||||
wreq->wi_val[1] = sc->wi_debug.wi_ledtest_param0;
|
||||
wreq->wi_val[2] = sc->wi_debug.wi_ledtest_param1;
|
||||
break;
|
||||
case WI_DEBUG_CONTTX:
|
||||
wreq->wi_len += 2;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_conttx;
|
||||
wreq->wi_val[1] = sc->wi_debug.wi_conttx_param0;
|
||||
break;
|
||||
case WI_DEBUG_CONTRX:
|
||||
wreq->wi_len++;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_contrx;
|
||||
break;
|
||||
case WI_DEBUG_SIGSTATE:
|
||||
wreq->wi_len += 2;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_sigstate;
|
||||
wreq->wi_val[1] = sc->wi_debug.wi_sigstate_param0;
|
||||
break;
|
||||
case WI_DEBUG_CONFBITS:
|
||||
wreq->wi_len += 2;
|
||||
wreq->wi_val[0] = sc->wi_debug.wi_confbits;
|
||||
wreq->wi_val[1] = sc->wi_debug.wi_confbits_param0;
|
||||
break;
|
||||
default:
|
||||
error = EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
wi_set_debug(sc, wreq)
|
||||
struct wi_softc *sc;
|
||||
struct wi_req *wreq;
|
||||
{
|
||||
int error = 0;
|
||||
u_int16_t cmd, param0 = 0, param1 = 0;
|
||||
|
||||
switch (wreq->wi_type) {
|
||||
case WI_DEBUG_RESET:
|
||||
case WI_DEBUG_INIT:
|
||||
case WI_DEBUG_CALENABLE:
|
||||
break;
|
||||
case WI_DEBUG_SLEEP:
|
||||
sc->wi_debug.wi_sleep = 1;
|
||||
break;
|
||||
case WI_DEBUG_WAKE:
|
||||
sc->wi_debug.wi_sleep = 0;
|
||||
break;
|
||||
case WI_DEBUG_CHAN:
|
||||
param0 = wreq->wi_val[0];
|
||||
break;
|
||||
case WI_DEBUG_DELAYSUPP:
|
||||
sc->wi_debug.wi_delaysupp = 1;
|
||||
break;
|
||||
case WI_DEBUG_TXSUPP:
|
||||
sc->wi_debug.wi_txsupp = 1;
|
||||
break;
|
||||
case WI_DEBUG_MONITOR:
|
||||
sc->wi_debug.wi_monitor = 1;
|
||||
break;
|
||||
case WI_DEBUG_LEDTEST:
|
||||
param0 = wreq->wi_val[0];
|
||||
param1 = wreq->wi_val[1];
|
||||
sc->wi_debug.wi_ledtest = 1;
|
||||
sc->wi_debug.wi_ledtest_param0 = param0;
|
||||
sc->wi_debug.wi_ledtest_param1 = param1;
|
||||
break;
|
||||
case WI_DEBUG_CONTTX:
|
||||
param0 = wreq->wi_val[0];
|
||||
sc->wi_debug.wi_conttx = 1;
|
||||
sc->wi_debug.wi_conttx_param0 = param0;
|
||||
break;
|
||||
case WI_DEBUG_STOPTEST:
|
||||
sc->wi_debug.wi_delaysupp = 0;
|
||||
sc->wi_debug.wi_txsupp = 0;
|
||||
sc->wi_debug.wi_monitor = 0;
|
||||
sc->wi_debug.wi_ledtest = 0;
|
||||
sc->wi_debug.wi_ledtest_param0 = 0;
|
||||
sc->wi_debug.wi_ledtest_param1 = 0;
|
||||
sc->wi_debug.wi_conttx = 0;
|
||||
sc->wi_debug.wi_conttx_param0 = 0;
|
||||
sc->wi_debug.wi_contrx = 0;
|
||||
sc->wi_debug.wi_sigstate = 0;
|
||||
sc->wi_debug.wi_sigstate_param0 = 0;
|
||||
break;
|
||||
case WI_DEBUG_CONTRX:
|
||||
sc->wi_debug.wi_contrx = 1;
|
||||
break;
|
||||
case WI_DEBUG_SIGSTATE:
|
||||
param0 = wreq->wi_val[0];
|
||||
sc->wi_debug.wi_sigstate = 1;
|
||||
sc->wi_debug.wi_sigstate_param0 = param0;
|
||||
break;
|
||||
case WI_DEBUG_CONFBITS:
|
||||
param0 = wreq->wi_val[0];
|
||||
param1 = wreq->wi_val[1];
|
||||
sc->wi_debug.wi_confbits = param0;
|
||||
sc->wi_debug.wi_confbits_param0 = param1;
|
||||
break;
|
||||
default:
|
||||
error = EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
cmd = WI_CMD_DEBUG | (wreq->wi_type << 8);
|
||||
error = wi_cmd(sc, cmd, param0, param1, 0);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -32,6 +32,10 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <netinet/if_ether.h>
|
||||
#include <dev/wi/if_wavelan_ieee.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
struct wi_counters {
|
||||
u_int32_t wi_tx_unicast_frames;
|
||||
u_int32_t wi_tx_multicast_frames;
|
||||
@ -111,6 +115,7 @@ struct wi_softc {
|
||||
int wi_tx_mgmt_id;
|
||||
int wi_gone;
|
||||
int wi_if_flags;
|
||||
u_int16_t wi_procframe;
|
||||
u_int16_t wi_ptype;
|
||||
u_int16_t wi_portnum;
|
||||
u_int16_t wi_max_data_len;
|
||||
@ -129,6 +134,8 @@ struct wi_softc {
|
||||
char wi_net_name[32];
|
||||
char wi_ibss_name[32];
|
||||
u_int8_t wi_txbuf[1596];
|
||||
u_int8_t wi_scanbuf[1596];
|
||||
int wi_scanbuf_len;
|
||||
struct wi_counters wi_stats;
|
||||
int wi_has_wep;
|
||||
int wi_use_wep;
|
||||
@ -145,6 +152,23 @@ struct wi_softc {
|
||||
int wi_firmware_ver;
|
||||
int wi_nic_type;
|
||||
int wi_bus_type; /* Bus attachment type */
|
||||
struct {
|
||||
u_int16_t wi_sleep;
|
||||
u_int16_t wi_delaysupp;
|
||||
u_int16_t wi_txsupp;
|
||||
u_int16_t wi_monitor;
|
||||
u_int16_t wi_ledtest;
|
||||
u_int16_t wi_ledtest_param0;
|
||||
u_int16_t wi_ledtest_param1;
|
||||
u_int16_t wi_conttx;
|
||||
u_int16_t wi_conttx_param0;
|
||||
u_int16_t wi_contrx;
|
||||
u_int16_t wi_sigstate;
|
||||
u_int16_t wi_sigstate_param0;
|
||||
u_int16_t wi_confbits;
|
||||
u_int16_t wi_confbits_param0;
|
||||
} wi_debug;
|
||||
|
||||
};
|
||||
|
||||
#define WI_LOCK(_sc)
|
||||
|
Loading…
Reference in New Issue
Block a user