misc fixes, see CHANGES.
This commit is contained in:
parent
02927f0c3b
commit
b0f068adaa
6
CHANGES
6
CHANGES
|
@ -41,6 +41,12 @@
|
|||
* Intersil Corporation as part of PRISM(R) chipset product development.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
- A series of patches from Pavel Kankovsky, somewhat tweaked. :)
|
||||
- Properly set skb->mac.raw in non-monitor mode
|
||||
- Enhancments to the p80211 frame conversion code
|
||||
- Handle A4 frames.
|
||||
- Don't issue linkstatus notifications in monitor mode
|
||||
- Supress Linkstatus messages in monitor mode
|
||||
- hfa384x.h updates for latest firmware.
|
||||
-pre9
|
||||
- ZyXEL ZyAir B200 Wireless USB widget ID added (Paul Lacatus)
|
||||
|
|
2
THANKS
2
THANKS
|
@ -97,6 +97,8 @@ Tom Prado <tprado@charter.net>
|
|||
Olivier Bornet <Olivier.Bornet@puck.ch>
|
||||
Ryan Veety <ryan@ryanspc.com>
|
||||
Michael Hackett <mhackett@kanayo.com>
|
||||
Pavel Kankovsky <kan@dcit.cz>
|
||||
|
||||
|
||||
[Many, many more. If I've overlooked you and you want to be listed here,
|
||||
send me e-mail and I'll fix it. I _know_ a bunch of linux-wlan contributors
|
||||
|
|
|
@ -282,6 +282,7 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
netdevice_t *dev = wlandev->netdev;
|
||||
UINT16 fc;
|
||||
UINT payload_length;
|
||||
UINT payload_offset;
|
||||
UINT8 daddr[WLAN_ETHADDR_LEN];
|
||||
UINT8 saddr[WLAN_ETHADDR_LEN];
|
||||
p80211_hdr_t *w_hdr;
|
||||
|
@ -292,9 +293,10 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
int foo;
|
||||
|
||||
DBFENTER;
|
||||
|
||||
payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
|
||||
|
||||
payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
|
||||
payload_offset = WLAN_HDR_A3_LEN;
|
||||
|
||||
w_hdr = (p80211_hdr_t *) skb->data;
|
||||
|
||||
/* setup some vars for convenience */
|
||||
|
@ -309,14 +311,27 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
|
||||
memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
|
||||
} else {
|
||||
WLAN_LOG_ERROR0("HDR_A4 detected! A4 currently not supported.\n");
|
||||
return 1;
|
||||
payload_offset = WLAN_HDR_A4_LEN;
|
||||
payload_length -= ( WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN );
|
||||
if (payload_length < 0 ) {
|
||||
WLAN_LOG_ERROR0("A4 frame too short!\n");
|
||||
return 1;
|
||||
}
|
||||
memcpy(daddr, w_hdr->a4.a3, WLAN_ETHADDR_LEN);
|
||||
memcpy(saddr, w_hdr->a4.a4, WLAN_ETHADDR_LEN);
|
||||
}
|
||||
|
||||
/* perform de-wep if necessary.. */
|
||||
if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
|
||||
|
||||
if ((foo = wep_decrypt(wlandev, skb->data + WLAN_HDR_A3_LEN +4, payload_length-8, -1, skb->data+WLAN_HDR_A3_LEN, skb->data + WLAN_HDR_A3_LEN + payload_length - 4))) {
|
||||
if (payload_length <= 8) {
|
||||
WLAN_LOG_ERROR1("WEP frame too short (%u).\n",
|
||||
skb->len);
|
||||
return 1;
|
||||
}
|
||||
if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
|
||||
payload_length - 8, -1,
|
||||
skb->data + payload_offset,
|
||||
skb->data + payload_offset + payload_length - 4))) {
|
||||
/* de-wep failed, drop skb. */
|
||||
WLAN_LOG_WARNING1("Host de-WEP failed, dropping frame (%d).\n", foo);
|
||||
wlandev->rx.decrypt_err++;
|
||||
|
@ -333,14 +348,16 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
wlandev->rx.decrypt++;
|
||||
}
|
||||
|
||||
e_hdr = (wlan_ethhdr_t *) (skb->data + WLAN_HDR_A3_LEN);
|
||||
e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);
|
||||
|
||||
e_llc = (wlan_llc_t *) (skb->data + WLAN_HDR_A3_LEN);
|
||||
e_snap = (wlan_snap_t *) (skb->data + WLAN_HDR_A3_LEN + sizeof(wlan_llc_t));
|
||||
e_llc = (wlan_llc_t *) (skb->data + payload_offset);
|
||||
e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
|
||||
|
||||
/* Test for the various encodings */
|
||||
if ( memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0 &&
|
||||
memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0 ) {
|
||||
if ( (payload_length >= sizeof(wlan_ethhdr_t)) &&
|
||||
( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) &&
|
||||
((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
|
||||
(memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
|
||||
WLAN_LOG_DEBUG1(3, "802.3 ENCAP len: %d\n", payload_length);
|
||||
/* 802.3 Encapsulated */
|
||||
/* Test for an overlength frame */
|
||||
|
@ -352,11 +369,12 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
}
|
||||
|
||||
/* Chop off the 802.11 header. it's already sane. */
|
||||
skb_pull(skb, WLAN_HDR_A3_LEN);
|
||||
skb_pull(skb, payload_offset);
|
||||
/* chop off the 802.11 CRC */
|
||||
skb_trim(skb, skb->len - WLAN_CRC_LEN);
|
||||
|
||||
} else if ((e_llc->dsap == 0xaa) &&
|
||||
} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
|
||||
(e_llc->dsap == 0xaa) &&
|
||||
(e_llc->ssap == 0xaa) &&
|
||||
(e_llc->ctl == 0x03) &&
|
||||
(((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) &&
|
||||
|
@ -377,7 +395,7 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
}
|
||||
|
||||
/* chop 802.11 header from skb. */
|
||||
skb_pull(skb, WLAN_HDR_A3_LEN);
|
||||
skb_pull(skb, payload_offset);
|
||||
|
||||
/* create 802.3 header at beginning of skb. */
|
||||
e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
|
||||
|
@ -388,9 +406,10 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
/* chop off the 802.11 CRC */
|
||||
skb_trim(skb, skb->len - WLAN_CRC_LEN);
|
||||
|
||||
} else if ( e_llc->dsap == 0xaa &&
|
||||
e_llc->ssap == 0xaa &&
|
||||
e_llc->ctl == 0x03 ) {
|
||||
} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
|
||||
(e_llc->dsap == 0xaa) &&
|
||||
(e_llc->ssap == 0xaa) &&
|
||||
(e_llc->ctl == 0x03) ) {
|
||||
WLAN_LOG_DEBUG1(3, "802.1h/RFC1042 len: %d\n", payload_length);
|
||||
/* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */
|
||||
/* build a DIXII + RFC894 */
|
||||
|
@ -404,7 +423,7 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
}
|
||||
|
||||
/* chop 802.11 header from skb. */
|
||||
skb_pull(skb, WLAN_HDR_A3_LEN);
|
||||
skb_pull(skb, payload_offset);
|
||||
|
||||
/* chop llc header from skb. */
|
||||
skb_pull(skb, sizeof(wlan_llc_t));
|
||||
|
@ -436,7 +455,7 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
}
|
||||
|
||||
/* Chop off the 802.11 header. */
|
||||
skb_pull(skb, WLAN_HDR_A3_LEN);
|
||||
skb_pull(skb, payload_offset);
|
||||
|
||||
/* create 802.3 header at beginning of skb. */
|
||||
e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
|
||||
|
@ -450,6 +469,7 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *
|
|||
}
|
||||
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
skb->mac.raw = (unsigned char *) e_hdr; /* new MAC header */
|
||||
|
||||
DBFEXIT;
|
||||
return 0;
|
||||
|
|
|
@ -3812,6 +3812,8 @@ void hfa384x_int_rx(wlandevice_t *wlandev)
|
|||
UINT16 rxfid;
|
||||
hfa384x_rx_frame_t rxdesc;
|
||||
int result;
|
||||
int hdrlen;
|
||||
UINT16 fc;
|
||||
struct sk_buff *skb = NULL;
|
||||
UINT8 *datap;
|
||||
|
||||
|
@ -3846,14 +3848,6 @@ void hfa384x_int_rx(wlandevice_t *wlandev)
|
|||
HFA384x_RXSTATUS_ISUNDECR(rxdesc.status)))
|
||||
goto done;
|
||||
|
||||
#if 0
|
||||
printk(KERN_DEBUG"rxf(%d): ",rxlen);
|
||||
for (i=0; i<pb->p80211frmlen; i++) {
|
||||
printk("%x ",pb->p80211buf[i]);
|
||||
}
|
||||
printk("\n");
|
||||
#endif
|
||||
|
||||
/* Now handle frame based on port# */
|
||||
switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) )
|
||||
{
|
||||
|
@ -3885,9 +3879,16 @@ printk("\n");
|
|||
}
|
||||
}
|
||||
|
||||
fc = ieee2host16(rxdesc.frame_control);
|
||||
if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) {
|
||||
hdrlen = WLAN_HDR_A4_LEN;
|
||||
} else {
|
||||
hdrlen = WLAN_HDR_A3_LEN;
|
||||
}
|
||||
|
||||
/* Allocate the buffer, note CRC (aka FCS). pballoc */
|
||||
/* assumes there needs to be space for one */
|
||||
skb = dev_alloc_skb(hfa384x2host_16(rxdesc.data_len) + WLAN_HDR_A3_LEN + WLAN_CRC_LEN + 2); /* a little extra */
|
||||
skb = dev_alloc_skb(hfa384x2host_16(rxdesc.data_len) + hdrlen + WLAN_CRC_LEN + 2); /* a little extra */
|
||||
|
||||
if ( ! skb ) {
|
||||
WLAN_LOG_ERROR0("alloc_skb failed.\n");
|
||||
|
@ -3897,12 +3898,19 @@ printk("\n");
|
|||
skb->dev = wlandev->netdev;
|
||||
|
||||
/* theoretically align the IP header on a 32-bit word. */
|
||||
skb_reserve(skb, 2);
|
||||
if ( hdrlen == WLAN_HDR_A3_LEN )
|
||||
skb_reserve(skb, 2);
|
||||
|
||||
/* Copy the 802.11 hdr to the buffer */
|
||||
datap = skb_put(skb, WLAN_HDR_A3_LEN);
|
||||
memcpy(datap, &rxdesc.frame_control, WLAN_HDR_A3_LEN);
|
||||
|
||||
/* Snag the A4 address if present */
|
||||
if (hdrlen == WLAN_HDR_A4_LEN) {
|
||||
datap = skb_put(skb, WLAN_ADDR_LEN);
|
||||
memcpy(datap, &rxdesc.address4, WLAN_HDR_A3_LEN);
|
||||
}
|
||||
|
||||
/* we can convert the data_len as we passed the original on */
|
||||
rxdesc.data_len = hfa384x2host_16(rxdesc.data_len);
|
||||
|
||||
|
@ -3925,6 +3933,7 @@ printk("\n");
|
|||
/* the prism2 cards don't return the FCS */
|
||||
datap = skb_put(skb, WLAN_CRC_LEN);
|
||||
memset (datap, 0xff, WLAN_CRC_LEN);
|
||||
skb->mac.raw = skb->data;
|
||||
|
||||
prism2sta_ev_rx(wlandev, skb);
|
||||
goto done;
|
||||
|
|
|
@ -3945,6 +3945,8 @@ void hfa384x_usbin_rx(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
|
|||
int result;
|
||||
p80211_hdr_t *w_hdr;
|
||||
struct sk_buff *skb = NULL;
|
||||
int hdrlen;
|
||||
UINT16 fc;
|
||||
UINT8 *datap;
|
||||
|
||||
DBFENTER;
|
||||
|
@ -3955,18 +3957,6 @@ void hfa384x_usbin_rx(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
|
|||
usbin->rxfrm.desc.time =
|
||||
hfa384x2host_32(usbin->rxfrm.desc.time);
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
printk(KERN_DEBUG"rxf(%d): ", usbin->rxfrm.desc.data_len);
|
||||
for (i=0; i<64; i++) {
|
||||
printk("%x ",((UINT8*)usbin)[i]);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now handle frame based on port# */
|
||||
switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status))
|
||||
{
|
||||
|
@ -4000,9 +3990,16 @@ printk("\n");
|
|||
}
|
||||
}
|
||||
|
||||
fc = ieee2host16(usbin->rxfrm.desc.frame_control);
|
||||
if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) {
|
||||
hdrlen = WLAN_HDR_A4_LEN;
|
||||
} else {
|
||||
hdrlen = WLAN_HDR_A3_LEN;
|
||||
}
|
||||
|
||||
/* Allocate the buffer, note CRC (aka FCS). pballoc */
|
||||
/* assumes there needs to be space for one */
|
||||
skb = dev_alloc_skb(hfa384x2host_16(usbin->rxfrm.desc.data_len) + WLAN_HDR_A3_LEN + WLAN_CRC_LEN + 2); /* a litlte extra */
|
||||
skb = dev_alloc_skb(hfa384x2host_16(usbin->rxfrm.desc.data_len) + hdrlen + WLAN_CRC_LEN + 2); /* a litlte extra */
|
||||
|
||||
if ( ! skb ) {
|
||||
WLAN_LOG_DEBUG0(1, "alloc_skb failed.\n");
|
||||
|
@ -4013,12 +4010,19 @@ printk("\n");
|
|||
skb->dev->last_rx = jiffies;
|
||||
|
||||
/* theoretically align the IP header on a 32-bit word. */
|
||||
skb_reserve(skb, 2);
|
||||
if ( hdrlen == WLAN_HDR_A3_LEN )
|
||||
skb_reserve(skb, 2);
|
||||
|
||||
/* Copy the 802.11 hdr to the buffer */
|
||||
datap = skb_put(skb, WLAN_HDR_A3_LEN);
|
||||
memcpy(datap, w_hdr, WLAN_HDR_A3_LEN);
|
||||
|
||||
/* Snag the A4 address if present */
|
||||
if (hdrlen == WLAN_HDR_A4_LEN) {
|
||||
datap = skb_put(skb, WLAN_ADDR_LEN);
|
||||
memcpy(datap, &usbin->rxfrm.desc.address4, WLAN_HDR_A3_LEN);
|
||||
}
|
||||
|
||||
/* we can convert the data_len as we passed the original on */
|
||||
usbin->rxfrm.desc.data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len);
|
||||
|
||||
|
@ -4032,6 +4036,7 @@ printk("\n");
|
|||
/* the prism2 series does not return the CRC */
|
||||
datap = skb_put(skb, WLAN_CRC_LEN);
|
||||
memset (datap, 0xff, WLAN_CRC_LEN);
|
||||
skb->mac.raw = skb->data;
|
||||
|
||||
prism2sta_ev_rx(wlandev, skb);
|
||||
|
||||
|
|
|
@ -2853,6 +2853,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
|
|||
|
||||
}
|
||||
|
||||
WLAN_LOG_INFO0("monitor mode disabled\n");
|
||||
msg->resultcode.data = P80211ENUM_resultcode_success;
|
||||
result = 0;
|
||||
goto exit;
|
||||
|
@ -2962,6 +2963,11 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
|
|||
result);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (wlandev->netdev->type = ARPHRD_ETHER) {
|
||||
WLAN_LOG_INFO0("monitor mode enabled\n");
|
||||
}
|
||||
|
||||
/* Set the driver state */
|
||||
/* Do we want the prism2 header? */
|
||||
if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) {
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
#include <wlan/wlan_compat.h>
|
||||
|
||||
|
@ -1979,10 +1980,13 @@ void prism2sta_linkstatus_defer(void *data)
|
|||
hw->join_ap = 2;
|
||||
hw->join_retries = 60;
|
||||
|
||||
WLAN_LOG_INFO0("linkstatus=CONNECTED\n");
|
||||
{
|
||||
/* Don't call this in monitor mode */
|
||||
if ( wlandev->netdev->type == ARPHRD_ETHER ) {
|
||||
UINT16 portstatus;
|
||||
int result;
|
||||
|
||||
WLAN_LOG_INFO0("linkstatus=CONNECTED\n");
|
||||
|
||||
/* For non-usb devices, we can use the sync versions */
|
||||
/* Collect the BSSID, and set state to allow tx */
|
||||
|
||||
|
@ -2034,7 +2038,8 @@ void prism2sta_linkstatus_defer(void *data)
|
|||
}
|
||||
else
|
||||
{
|
||||
WLAN_LOG_INFO0("linkstatus=DISCONNECTED (unhandled)\n");
|
||||
if (wlandev->netdev->type == ARPHRD_ETHER)
|
||||
WLAN_LOG_INFO0("linkstatus=DISCONNECTED (unhandled)\n");
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue