summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-08-02 10:48:02 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 16:49:39 -0700
commitab6179711a5e46ed1db739bef7752d65ce836dce (patch)
treee1d026661ceb7736a516bcd4eb2eb50f917e9d5c /drivers
parent2950cd26308ced650cf7cc3199eae3eb27f9917f (diff)
downloadblackbird-op-linux-ab6179711a5e46ed1db739bef7752d65ce836dce.tar.gz
blackbird-op-linux-ab6179711a5e46ed1db739bef7752d65ce836dce.zip
[PATCH] libertas: clean up 802.11 IE post-scan handling
Remove struct IE_WPA and just use direct checking of the IE bytes like ipw. Remove WLAN_802_11_VARIABLE_IEs because it's unused. Kill ieeetypes_elementid enum and just use MFIE_* from ieee80211.h. Also use struct ieee80211_info_element for scan buffer processing to simplify pointer usage. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h13
-rw-r--r--drivers/net/wireless/libertas/scan.c199
-rw-r--r--drivers/net/wireless/libertas/types.h23
3 files changed, 84 insertions, 151 deletions
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index 01a97d0fa98a..05ea54df71bd 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -91,25 +91,12 @@ struct enc_key {
u8 key[32];
};
-struct IE_WPA {
- u8 elementid;
- u8 len;
- u8 oui[4];
- __le16 version;
-};
-
/* wlan_offset_value */
struct wlan_offset_value {
u32 offset;
u32 value;
};
-struct WLAN_802_11_VARIABLE_IEs {
- u8 elementid;
- u8 length;
- u8 data[1];
-};
-
/* Define general data structure */
/* cmd_DS_GEN */
struct cmd_ds_gen {
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 8753f9344f3e..2d6bc7811b27 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -74,8 +74,8 @@ static inline int match_bss_no_security(struct wlan_802_11_security * secinfo,
if ( !secinfo->wep_enabled
&& !secinfo->WPAenabled
&& !secinfo->WPA2enabled
- && match_bss->wpa_ie[0] != WPA_IE
- && match_bss->rsn_ie[0] != WPA2_IE
+ && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC
+ && match_bss->rsn_ie[0] != MFIE_TYPE_RSN
&& !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
return 1;
}
@@ -99,7 +99,7 @@ static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
{
if ( !secinfo->wep_enabled
&& secinfo->WPAenabled
- && (match_bss->wpa_ie[0] == WPA_IE)
+ && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
*/
@@ -114,7 +114,7 @@ static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
{
if ( !secinfo->wep_enabled
&& secinfo->WPA2enabled
- && (match_bss->rsn_ie[0] == WPA2_IE)
+ && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
*/
@@ -130,8 +130,8 @@ static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
if ( !secinfo->wep_enabled
&& !secinfo->WPAenabled
&& !secinfo->WPA2enabled
- && (match_bss->wpa_ie[0] != WPA_IE)
- && (match_bss->rsn_ie[0] != WPA2_IE)
+ && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC)
+ && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN)
&& (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
return 1;
}
@@ -900,24 +900,18 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
static int libertas_process_bss(struct bss_descriptor * bss,
u8 ** pbeaconinfo, int *bytesleft)
{
- enum ieeetypes_elementid elemID;
struct ieeetypes_fhparamset *pFH;
struct ieeetypes_dsparamset *pDS;
struct ieeetypes_cfparamset *pCF;
struct ieeetypes_ibssparamset *pibss;
- u8 *pcurrentptr;
+ u8 *pos, *end;
u8 *pRate;
- u8 elemlen;
u8 bytestocopy;
u8 ratesize;
u16 beaconsize;
u8 founddatarateie;
- int bytesleftforcurrentbeacon;
int ret;
- struct IE_WPA *pIe;
- const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
-
struct ieeetypes_countryinfoset *pcountryinfo;
lbs_deb_enter(LBS_DEB_ASSOC);
@@ -934,29 +928,24 @@ static int libertas_process_bss(struct bss_descriptor * bss,
}
if (beaconsize == 0 || beaconsize > *bytesleft) {
-
*pbeaconinfo += *bytesleft;
*bytesleft = 0;
-
return -1;
}
/* Initialize the current working beacon pointer for this BSS iteration */
- pcurrentptr = *pbeaconinfo;
+ pos = *pbeaconinfo;
+ end = pos + beaconsize;
/* Advance the return beacon pointer past the current beacon */
*pbeaconinfo += beaconsize;
*bytesleft -= beaconsize;
- bytesleftforcurrentbeacon = beaconsize;
-
- memcpy(bss->bssid, pcurrentptr, ETH_ALEN);
+ memcpy(bss->bssid, pos, ETH_ALEN);
lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid));
+ pos += ETH_ALEN;
- pcurrentptr += ETH_ALEN;
- bytesleftforcurrentbeacon -= ETH_ALEN;
-
- if (bytesleftforcurrentbeacon < 12) {
+ if ((end - pos) < 12) {
lbs_deb_scan("process_bss: Not enough bytes left\n");
return -1;
}
@@ -967,26 +956,22 @@ static int libertas_process_bss(struct bss_descriptor * bss,
*/
/* RSSI is 1 byte long */
- bss->rssi = *pcurrentptr;
- lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr);
- pcurrentptr += 1;
- bytesleftforcurrentbeacon -= 1;
+ bss->rssi = *pos;
+ lbs_deb_scan("process_bss: RSSI=%02X\n", *pos);
+ pos++;
/* time stamp is 8 bytes long */
- bss->timestamp = le64_to_cpup((void *)pcurrentptr);
- pcurrentptr += 8;
- bytesleftforcurrentbeacon -= 8;
+ bss->timestamp = le64_to_cpup((void *) pos);
+ pos += 8;
/* beacon interval is 2 bytes long */
- bss->beaconperiod = le16_to_cpup((void *)pcurrentptr);
- pcurrentptr += 2;
- bytesleftforcurrentbeacon -= 2;
+ bss->beaconperiod = le16_to_cpup((void *) pos);
+ pos += 2;
/* capability information is 2 bytes long */
- bss->capability = le16_to_cpup((void *)pcurrentptr);
+ bss->capability = le16_to_cpup((void *) pos);
lbs_deb_scan("process_bss: capabilities = 0x%4X\n", bss->capability);
- pcurrentptr += 2;
- bytesleftforcurrentbeacon -= 2;
+ pos += 2;
if (bss->capability & WLAN_CAPABILITY_PRIVACY)
lbs_deb_scan("process_bss: AP WEP enabled\n");
@@ -996,47 +981,39 @@ static int libertas_process_bss(struct bss_descriptor * bss,
bss->mode = IW_MODE_INFRA;
/* rest of the current buffer are IE's */
- lbs_deb_scan("process_bss: IE length for this AP = %d\n",
- bytesleftforcurrentbeacon);
-
- lbs_dbg_hex("process_bss: IE info", (u8 *) pcurrentptr,
- bytesleftforcurrentbeacon);
+ lbs_deb_scan("process_bss: IE length for this AP = %zd\n", end - pos);
+ lbs_dbg_hex("process_bss: IE info", pos, end - pos);
/* process variable IE */
- while (bytesleftforcurrentbeacon >= 2) {
- elemID = (enum ieeetypes_elementid) (*((u8 *) pcurrentptr));
- elemlen = *((u8 *) pcurrentptr + 1);
+ while (pos <= end - 2) {
+ struct ieee80211_info_element * elem =
+ (struct ieee80211_info_element *) pos;
- if (bytesleftforcurrentbeacon < elemlen) {
+ if (pos + elem->len > end) {
lbs_deb_scan("process_bss: error in processing IE, "
"bytes left < IE length\n");
- bytesleftforcurrentbeacon = 0;
- continue;
+ break;
}
- switch (elemID) {
- case SSID:
- bss->ssid_len = elemlen;
- memcpy(bss->ssid, (pcurrentptr + 2), elemlen);
+ switch (elem->id) {
+ case MFIE_TYPE_SSID:
+ bss->ssid_len = elem->len;
+ memcpy(bss->ssid, elem->data, elem->len);
lbs_deb_scan("ssid '%s', ssid length %u\n",
escape_essid(bss->ssid, bss->ssid_len),
bss->ssid_len);
break;
- case SUPPORTED_RATES:
- memcpy(bss->datarates, (pcurrentptr + 2), elemlen);
- memmove(bss->libertas_supported_rates, (pcurrentptr + 2),
- elemlen);
- ratesize = elemlen;
+ case MFIE_TYPE_RATES:
+ memcpy(bss->datarates, elem->data, elem->len);
+ memmove(bss->libertas_supported_rates, elem->data,
+ elem->len);
+ ratesize = elem->len;
founddatarateie = 1;
break;
- case EXTRA_IE:
- lbs_deb_scan("process_bss: EXTRA_IE Found!\n");
- break;
-
- case FH_PARAM_SET:
- pFH = (struct ieeetypes_fhparamset *) pcurrentptr;
+ case MFIE_TYPE_FH_SET:
+ pFH = (struct ieeetypes_fhparamset *) pos;
memmove(&bss->phyparamset.fhparamset, pFH,
sizeof(struct ieeetypes_fhparamset));
#if 0 /* I think we can store these LE */
@@ -1045,21 +1022,21 @@ static int libertas_process_bss(struct bss_descriptor * bss,
#endif
break;
- case DS_PARAM_SET:
- pDS = (struct ieeetypes_dsparamset *) pcurrentptr;
+ case MFIE_TYPE_DS_SET:
+ pDS = (struct ieeetypes_dsparamset *) pos;
bss->channel = pDS->currentchan;
memcpy(&bss->phyparamset.dsparamset, pDS,
sizeof(struct ieeetypes_dsparamset));
break;
- case CF_PARAM_SET:
- pCF = (struct ieeetypes_cfparamset *) pcurrentptr;
+ case MFIE_TYPE_CF_SET:
+ pCF = (struct ieeetypes_cfparamset *) pos;
memcpy(&bss->ssparamset.cfparamset, pCF,
sizeof(struct ieeetypes_cfparamset));
break;
- case IBSS_PARAM_SET:
- pibss = (struct ieeetypes_ibssparamset *) pcurrentptr;
+ case MFIE_TYPE_IBSS_SET:
+ pibss = (struct ieeetypes_ibssparamset *) pos;
bss->atimwindow = le32_to_cpu(pibss->atimwindow);
memmove(&bss->ssparamset.ibssparamset, pibss,
sizeof(struct ieeetypes_ibssparamset));
@@ -1069,9 +1046,8 @@ static int libertas_process_bss(struct bss_descriptor * bss,
#endif
break;
- /* Handle Country Info IE */
- case COUNTRY_INFO:
- pcountryinfo = (struct ieeetypes_countryinfoset *) pcurrentptr;
+ case MFIE_TYPE_COUNTRY:
+ pcountryinfo = (struct ieeetypes_countryinfoset *) pos;
if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
|| pcountryinfo->len > 254) {
lbs_deb_scan("process_bss: 11D- Err "
@@ -1089,62 +1065,55 @@ static int libertas_process_bss(struct bss_descriptor * bss,
(u32) (pcountryinfo->len + 2));
break;
- case EXTENDED_SUPPORTED_RATES:
- /*
- * only process extended supported rate
- * if data rate is already found.
- * data rate IE should come before
+ case MFIE_TYPE_RATES_EX:
+ /* only process extended supported rate if data rate is
+ * already found. Data rate IE should come before
* extended supported rate IE
*/
- if (founddatarateie) {
- if ((elemlen + ratesize) > WLAN_SUPPORTED_RATES) {
- bytestocopy =
- (WLAN_SUPPORTED_RATES - ratesize);
- } else {
- bytestocopy = elemlen;
- }
+ if (!founddatarateie)
+ break;
- pRate = (u8 *) bss->datarates;
- pRate += ratesize;
- memmove(pRate, (pcurrentptr + 2), bytestocopy);
- pRate = (u8 *) bss->libertas_supported_rates;
- pRate += ratesize;
- memmove(pRate, (pcurrentptr + 2), bytestocopy);
+ if ((elem->len + ratesize) > WLAN_SUPPORTED_RATES) {
+ bytestocopy =
+ (WLAN_SUPPORTED_RATES - ratesize);
+ } else {
+ bytestocopy = elem->len;
}
- break;
-
- case VENDOR_SPECIFIC_221:
-#define IE_ID_LEN_FIELDS_BYTES 2
- pIe = (struct IE_WPA *)pcurrentptr;
- if (memcmp(pIe->oui, oui01, sizeof(oui01)))
- break;
-
- bss->wpa_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
- MAX_WPA_IE_LEN);
- memcpy(bss->wpa_ie, pcurrentptr, bss->wpa_ie_len);
- lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie, elemlen);
+ pRate = (u8 *) bss->datarates;
+ pRate += ratesize;
+ memmove(pRate, elem->data, bytestocopy);
+ pRate = (u8 *) bss->libertas_supported_rates;
+ pRate += ratesize;
+ memmove(pRate, elem->data, bytestocopy);
break;
- case WPA2_IE:
- pIe = (struct IE_WPA *)pcurrentptr;
- bss->rsn_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
- MAX_WPA_IE_LEN);
- memcpy(bss->rsn_ie, pcurrentptr, bss->rsn_ie_len);
- lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elemlen);
+
+ case MFIE_TYPE_GENERIC:
+ if (elem->len >= 4 &&
+ elem->data[0] == 0x00 &&
+ elem->data[1] == 0x50 &&
+ elem->data[2] == 0xf2 &&
+ elem->data[3] == 0x01) {
+ bss->wpa_ie_len = min(elem->len + 2,
+ MAX_WPA_IE_LEN);
+ memcpy(bss->wpa_ie, elem, bss->wpa_ie_len);
+ lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie,
+ elem->len);
+ }
break;
- case TIM:
+
+ case MFIE_TYPE_RSN:
+ bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
+ memcpy(bss->rsn_ie, elem, bss->rsn_ie_len);
+ lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elem->len);
break;
- case CHALLENGE_TEXT:
+ default:
break;
}
- pcurrentptr += elemlen + 2;
-
- /* need to account for IE ID and IE len */
- bytesleftforcurrentbeacon -= (elemlen + 2);
-
- } /* while (bytesleftforcurrentbeacon > 2) */
+ pos += elem->len + 2;
+ }
/* Timestamp */
bss->last_scanned = jiffies;
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index f4be1293cd16..2df352db1557 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -7,29 +7,6 @@
#include <linux/if_ether.h>
#include <asm/byteorder.h>
-/** IEEE type definitions */
-enum ieeetypes_elementid {
- SSID = 0,
- SUPPORTED_RATES,
- FH_PARAM_SET,
- DS_PARAM_SET,
- CF_PARAM_SET,
- TIM,
- IBSS_PARAM_SET,
- COUNTRY_INFO = 7,
-
- CHALLENGE_TEXT = 16,
-
- EXTENDED_SUPPORTED_RATES = 50,
-
- VENDOR_SPECIFIC_221 = 221,
-
- WPA_IE = 221,
- WPA2_IE = 48,
-
- EXTRA_IE = 133,
-} __attribute__ ((packed));
-
#define CAPINFO_MASK (~(0x00da))
struct ieeetypes_cfparamset {
OpenPOWER on IntegriCloud