Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-2]: src/sys/dev/ic Pull up following revision(s) (requested by jn...
details: https://anonhg.NetBSD.org/src/rev/a565696560b3
branches: netbsd-2
changeset: 564346:a565696560b3
user: riz <riz%NetBSD.org@localhost>
date: Thu Dec 01 19:39:26 2005 +0000
description:
Pull up following revision(s) (requested by jnemeth in ticket #10159):
sys/dev/ic/an.c: revision 1.33 via patch
sys/dev/ic/anvar.h: revision 1.9 via patch
Fix two bugs: frames were bogusly discarded with the complaint
"oversize frame." Also, some an(4) instances (esp. w/ firmware
version 5+) would not reliably interoperate with some Cisco APs.
Add a sysctl for enabling/disabling debugging.
The problem with Aironet AP interoperability was that the rx frame
'gap' will sometimes be loaded with the 802.2 SNAP header, and
sometimes omitted, when connected to a Cisco AP; an(4) was *always*
discarding the gap. The problem with "oversize frames" was an
off-by-2 error in the frame-length arithmetic.
While we're here, pad some RIDs to the length that new firmware
really expects.
Thanks to Jim Miller for his valuable bug reports and testing, and
to Dheeraj Reddy for RID-length patches. Some clues from various
Linux drivers for Cisco/Aironet cards led to the gap fix.
diffstat:
sys/dev/ic/an.c | 52 +++++++++++++++++++++++++++++++++++-----------------
sys/dev/ic/anvar.h | 4 +++-
2 files changed, 38 insertions(+), 18 deletions(-)
diffs (123 lines):
diff -r acb67485bb22 -r a565696560b3 sys/dev/ic/an.c
--- a/sys/dev/ic/an.c Thu Dec 01 16:29:20 2005 +0000
+++ b/sys/dev/ic/an.c Thu Dec 01 19:39:26 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: an.c,v 1.29 2004/01/28 15:07:52 onoe Exp $ */
+/* $NetBSD: an.c,v 1.29.4.1 2005/12/01 19:39:26 riz Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul%ctr.columbia.edu@localhost>. All rights reserved.
@@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: an.c,v 1.29 2004/01/28 15:07:52 onoe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: an.c,v 1.29.4.1 2005/12/01 19:39:26 riz Exp $");
#include "bpfilter.h"
@@ -1225,7 +1225,8 @@
struct an_rxframe frmhdr;
struct mbuf *m;
u_int16_t status;
- int fid, off, len;
+ int fid, gaplen, off, len;
+ uint8_t *gap;
fid = CSR_READ_2(sc, AN_RX_FID);
@@ -1261,7 +1262,8 @@
return;
}
- len = le16toh(frmhdr.an_rx_payload_len);
+ /* the payload length field includes a 16-bit "mystery field" */
+ len = le16toh(frmhdr.an_rx_payload_len) - sizeof(uint16_t);
off = ALIGN(sizeof(struct ieee80211_frame));
if (off + len > MCLBYTES) {
@@ -1281,7 +1283,7 @@
DPRINTF(("an_rx_intr: MGET failed\n"));
return;
}
- if (off + len > MHLEN) {
+ if (off + len + AN_GAPLEN_MAX > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
@@ -1294,29 +1296,45 @@
m->m_data += off - sizeof(struct ieee80211_frame);
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+ gaplen = le16toh(frmhdr.an_gaplen);
+ if (gaplen > AN_GAPLEN_MAX) {
+ CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
+ m_freem(m);
+ ifp->if_ierrors++;
+ DPRINTF(("%s: gap too long\n", __func__));
+ return;
+ }
/*
- * The gap and the payload length should be skipped.
- * Make dummy read to avoid seek.
+ * We don't need the 16-bit mystery field (payload length?),
+ * so read it into the region reserved for the 802.11 header.
+ *
+ * When Cisco Aironet 350 cards w/ firmware version 5 or
+ * greater operate with certain Cisco 350 APs,
+ * the "gap" is filled with the SNAP header. Read
+ * it in after the 802.11 header.
*/
- an_read_bap(sc, fid, -1, m->m_data,
- le16toh(frmhdr.an_gaplen) + sizeof(u_int16_t));
+ gap = m->m_data + sizeof(struct ieee80211_frame) -
+ sizeof(uint16_t);
+ an_read_bap(sc, fid, -1, gap, gaplen + sizeof(uint16_t));
#ifdef AN_DEBUG
if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
(IFF_DEBUG|IFF_LINK2)) {
int i;
printf(" gap&len");
- for (i = 0;
- i < le16toh(frmhdr.an_gaplen) + sizeof(u_int16_t);
- i++)
- printf(" %02x", mtod(m, u_int8_t *)[i]);
+ for (i = 0; i < gaplen + sizeof(uint16_t); i++)
+ printf(" %02x", gap[i]);
printf("\n");
}
#endif
- }
+ } else
+ gaplen = 0;
+
+ an_read_bap(sc, fid, -1,
+ m->m_data + sizeof(struct ieee80211_frame) + gaplen, len);
+ m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + gaplen +
+ len;
+
memcpy(m->m_data, &frmhdr.an_whdr, sizeof(struct ieee80211_frame));
- an_read_bap(sc, fid, -1, m->m_data + sizeof(struct ieee80211_frame),
- len);
- m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
m->m_pkthdr.rcvif = ifp;
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
diff -r acb67485bb22 -r a565696560b3 sys/dev/ic/anvar.h
--- a/sys/dev/ic/anvar.h Thu Dec 01 16:29:20 2005 +0000
+++ b/sys/dev/ic/anvar.h Thu Dec 01 19:39:26 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: anvar.h,v 1.8 2004/01/28 15:07:52 onoe Exp $ */
+/* $NetBSD: anvar.h,v 1.8.6.1 2005/12/01 19:39:27 riz Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul%ctr.columbia.edu@localhost>. All rights reserved.
@@ -71,6 +71,8 @@
int an_wep_keylen;
};
+#define AN_GAPLEN_MAX 8
+
struct an_softc {
struct device sc_dev;
struct ieee80211com sc_ic;
Home |
Main Index |
Thread Index |
Old Index