diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index ab76798df0eb..261bbd55e94f 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -654,7 +654,8 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv, * @param priv pointer to wlan_private * @return 0; -1 */ -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv) +int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, + struct bss_descriptor * bss) { int ret; wlan_adapter *adapter = priv->adapter; @@ -663,8 +664,7 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv) if (priv->adapter->enable11d) { memset(&adapter->parsed_region_chan, 0, sizeof(struct parsed_region_chan_11d)); - ret = parse_domain_info_11d(&adapter->pattemptedbssdesc-> - countryinfo, 0, + ret = parse_domain_info_11d(&bss->countryinfo, 0, &adapter->parsed_region_chan); if (ret == -1) { diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h index db2ebea9f231..982d7929eed7 100644 --- a/drivers/net/wireless/libertas/11d.h +++ b/drivers/net/wireless/libertas/11d.h @@ -98,7 +98,9 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq); int libertas_ret_802_11d_domain_info(wlan_private * priv, struct cmd_ds_command *resp); -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv); +struct bss_descriptor; +int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, + struct bss_descriptor * bss); int libertas_create_dnld_countryinfo_11d(wlan_private * priv); diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 3f2dfaf879c5..b18464224b95 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -13,6 +13,56 @@ static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +/* From ieee80211_module.c */ +static const char *libertas_escape_essid(const char *essid, u8 essid_len) +{ + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; + const char *s = essid; + char *d = escaped; + + if (ieee80211_is_empty_essid(essid, essid_len)) + return ""; + + essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE); + while (essid_len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else { + *d++ = *s++; + } + } + *d = '\0'; + return escaped; +} + +static void print_assoc_req(const char * extra, struct assoc_request * assoc_req) +{ + lbs_deb_assoc( + "#### Association Request: %s\n" + " flags: 0x%08lX\n" + " SSID: '%s'\n" + " channel: %d\n" + " band: %d\n" + " mode: %d\n" + " BSSID: " MAC_FMT "\n" + " WPA: %d\n" + " WPA2: %d\n" + " WEP status: %d\n" + " auth: %d\n" + " auth_alg: %d\n" + " encmode: %d\n", + extra, assoc_req->flags, + libertas_escape_essid(assoc_req->ssid.ssid, assoc_req->ssid.ssidlength), + assoc_req->channel, assoc_req->band, assoc_req->mode, + MAC_ARG(assoc_req->bssid), assoc_req->secinfo.WPAenabled, + assoc_req->secinfo.WPA2enabled, assoc_req->secinfo.WEPstatus, + assoc_req->secinfo.authmode, assoc_req->secinfo.auth1xalg, + assoc_req->secinfo.Encryptionmode); +} + + static int assoc_helper_essid(wlan_private *priv, struct assoc_request * assoc_req) { @@ -36,10 +86,8 @@ static int assoc_helper_essid(wlan_private *priv, NULL, IW_MODE_INFRA); if (bss != NULL) { lbs_deb_assoc("SSID found in scan list, associating\n"); - ret = wlan_associate(priv, bss); - if (ret == 0) { - memcpy(&assoc_req->bssid, bss->bssid, ETH_ALEN); - } + memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); + ret = wlan_associate(priv, assoc_req); } else { lbs_deb_assoc("SSID '%s' not found; cannot associate\n", assoc_req->ssid.ssid); @@ -55,14 +103,16 @@ static int assoc_helper_essid(wlan_private *priv, IW_MODE_ADHOC); if (bss != NULL) { lbs_deb_assoc("SSID found joining\n"); - libertas_join_adhoc_network(priv, bss); + memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); + libertas_join_adhoc_network(priv, assoc_req); } else { /* else send START command */ lbs_deb_assoc("SSID not found in list, so creating adhoc" " with SSID '%s'\n", assoc_req->ssid.ssid); - libertas_start_adhoc_network(priv, &assoc_req->ssid); + memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, + sizeof(struct WLAN_802_11_SSID)); + libertas_start_adhoc_network(priv, assoc_req); } - memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN); } lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); @@ -89,13 +139,13 @@ static int assoc_helper_bssid(wlan_private *priv, goto out; } + memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); if (assoc_req->mode == IW_MODE_INFRA) { - ret = wlan_associate(priv, bss); + ret = wlan_associate(priv, assoc_req); lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret); } else if (assoc_req->mode == IW_MODE_ADHOC) { - libertas_join_adhoc_network(priv, bss); + libertas_join_adhoc_network(priv, assoc_req); } - memcpy(&assoc_req->ssid, &bss->ssid, sizeof(struct WLAN_802_11_SSID)); out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); @@ -421,15 +471,15 @@ void libertas_association_worker(struct work_struct *work) lbs_deb_enter(LBS_DEB_ASSOC); mutex_lock(&adapter->lock); - assoc_req = adapter->assoc_req; - adapter->assoc_req = NULL; + assoc_req = adapter->pending_assoc_req; + adapter->pending_assoc_req = NULL; + adapter->in_progress_assoc_req = assoc_req; mutex_unlock(&adapter->lock); if (!assoc_req) goto done; - lbs_deb_assoc("ASSOC: starting new association request: flags = 0x%lX\n", - assoc_req->flags); + print_assoc_req(__func__, assoc_req); /* If 'any' SSID was specified, find an SSID to associate with */ if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) @@ -561,7 +611,9 @@ lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); if (success) { lbs_deb_assoc("ASSOC: association attempt successful. " "Associated to '%s' (" MAC_FMT ")\n", - assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid)); + libertas_escape_essid(adapter->curbssparams.ssid.ssid, + adapter->curbssparams.ssid.ssidlength), + MAC_ARG(adapter->curbssparams.bssid)); libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0, cmd_option_waitforrsp, 0, NULL); @@ -580,6 +632,10 @@ lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", ret); } + + mutex_lock(&adapter->lock); + adapter->in_progress_assoc_req = NULL; + mutex_unlock(&adapter->lock); kfree(assoc_req); done: @@ -594,9 +650,10 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) { struct assoc_request * assoc_req; - if (!adapter->assoc_req) { - adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL); - if (!adapter->assoc_req) { + if (!adapter->pending_assoc_req) { + adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request), + GFP_KERNEL); + if (!adapter->pending_assoc_req) { lbs_pr_info("Not enough memory to allocate association" " request!\n"); return NULL; @@ -606,15 +663,18 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) /* Copy current configuration attributes to the association request, * but don't overwrite any that are already set. */ - assoc_req = adapter->assoc_req; + assoc_req = adapter->pending_assoc_req; if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid, - adapter->curbssparams.ssid.ssidlength); + memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid, + sizeof(struct WLAN_802_11_SSID)); } if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) assoc_req->channel = adapter->curbssparams.channel; + if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) + assoc_req->band = adapter->curbssparams.band; + if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) assoc_req->mode = adapter->mode; @@ -655,7 +715,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) assoc_req->wpa_ie_len = adapter->wpa_ie_len; } + print_assoc_req(__func__, assoc_req); + return assoc_req; } - - diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h index f9b2ad47ee6e..b5eddf8d3b39 100644 --- a/drivers/net/wireless/libertas/assoc.h +++ b/drivers/net/wireless/libertas/assoc.h @@ -21,9 +21,9 @@ static inline void wlan_postpone_association_work(wlan_private *priv) static inline void wlan_cancel_association_work(wlan_private *priv) { cancel_delayed_work(&priv->assoc_work); - if (priv->adapter->assoc_req) { - kfree(priv->adapter->assoc_req); - priv->adapter->assoc_req = NULL; + if (priv->adapter->pending_assoc_req) { + kfree(priv->adapter->pending_assoc_req); + priv->adapter->pending_assoc_req = NULL; } } diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 45459d4ba684..6bf50c1eeb93 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -67,25 +67,19 @@ void libertas_mac_event_disconnected(wlan_private * priv) lbs_deb_cmd("Previous SSID=%s, ssid length=%u\n", adapter->previousssid.ssid, adapter->previousssid.ssidlength); - /* reset internal flags */ - adapter->secinfo.WPAenabled = 0; - adapter->secinfo.WPA2enabled = 0; - adapter->wpa_ie_len = 0; - adapter->connect_status = libertas_disconnected; - /* - * memorize the previous SSID and BSSID - * it could be used for re-assoc - */ + /* Save previous SSID and BSSID for possible reassociation */ memcpy(&adapter->previousssid, &adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID)); memcpy(adapter->previousbssid, adapter->curbssparams.bssid, ETH_ALEN); - /* need to erase the current SSID and BSSID info */ - adapter->pattemptedbssdesc = NULL; - memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams)); + /* Clear out associated SSID and BSSID since connection is + * no longer valid. + */ + memset(&adapter->curbssparams.bssid, 0, ETH_ALEN); + memset(&adapter->curbssparams.ssid, 0, sizeof(struct WLAN_802_11_SSID)); if (adapter->psstate != PS_STATE_FULL_POWER) { /* make firmware to exit PS mode */ diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 4ca60d9323b4..797a1249bcaf 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -63,7 +63,6 @@ struct wlan_802_11_security { /** Current Basic Service Set State Structure */ struct current_bss_params { - struct bss_descriptor bssdescriptor; /** bssid */ u8 bssid[ETH_ALEN]; /** ssid */ @@ -168,18 +167,20 @@ struct _wlan_private { struct assoc_request { #define ASSOC_FLAG_SSID 1 #define ASSOC_FLAG_CHANNEL 2 -#define ASSOC_FLAG_MODE 3 -#define ASSOC_FLAG_BSSID 4 -#define ASSOC_FLAG_WEP_KEYS 5 -#define ASSOC_FLAG_WEP_TX_KEYIDX 6 -#define ASSOC_FLAG_WPA_MCAST_KEY 7 -#define ASSOC_FLAG_WPA_UCAST_KEY 8 -#define ASSOC_FLAG_SECINFO 9 -#define ASSOC_FLAG_WPA_IE 10 +#define ASSOC_FLAG_BAND 3 +#define ASSOC_FLAG_MODE 4 +#define ASSOC_FLAG_BSSID 5 +#define ASSOC_FLAG_WEP_KEYS 6 +#define ASSOC_FLAG_WEP_TX_KEYIDX 7 +#define ASSOC_FLAG_WPA_MCAST_KEY 8 +#define ASSOC_FLAG_WPA_UCAST_KEY 9 +#define ASSOC_FLAG_SECINFO 10 +#define ASSOC_FLAG_WPA_IE 11 unsigned long flags; struct WLAN_802_11_SSID ssid; u8 channel; + u8 band; u8 mode; u8 bssid[ETH_ALEN]; @@ -196,6 +197,9 @@ struct assoc_request { /** WPA Information Elements*/ u8 wpa_ie[MAX_WPA_IE_LEN]; u8 wpa_ie_len; + + /* BSS to associate with for infrastructure of Ad-Hoc join */ + struct bss_descriptor bss; }; /** Wlan adapter data structure*/ @@ -252,8 +256,6 @@ struct _wlan_adapter { /* IW_MODE_* */ u8 mode; - struct bss_descriptor *pattemptedbssdesc; - struct WLAN_802_11_SSID previousssid; u8 previousbssid[ETH_ALEN]; @@ -322,7 +324,8 @@ struct _wlan_adapter { u16 locallisteninterval; u16 nullpktinterval; - struct assoc_request * assoc_req; + struct assoc_request * pending_assoc_req; + struct assoc_request * in_progress_assoc_req; /** Encryption parameter */ struct wlan_802_11_security secinfo; diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c index 2e535ef7e803..eea18725bb90 100644 --- a/drivers/net/wireless/libertas/fw.c +++ b/drivers/net/wireless/libertas/fw.c @@ -185,7 +185,8 @@ static void wlan_init_adapter(wlan_private * priv) adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; adapter->mode = IW_MODE_INFRA; - adapter->assoc_req = NULL; + adapter->pending_assoc_req = NULL; + adapter->in_progress_assoc_req = NULL; /* Initialize scan result lists */ INIT_LIST_HEAD(&adapter->network_free_list); @@ -195,7 +196,6 @@ static void wlan_init_adapter(wlan_private * priv) &adapter->network_free_list); } - adapter->pattemptedbssdesc = NULL; mutex_init(&adapter->lock); adapter->prescan = 1; diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c index a11ce3a6f611..65777b40d57b 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -14,6 +15,7 @@ #include "decl.h" #include "join.h" #include "dev.h" +#include "assoc.h" #define AD_HOC_CAP_PRIVACY_ON 1 @@ -104,7 +106,7 @@ int libertas_send_deauth(wlan_private * priv) * * @return 0-success, otherwise fail */ -int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) +int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; int ret; @@ -113,13 +115,13 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate, 0, cmd_option_waitforrsp, - 0, pbssdesc->bssid); + 0, assoc_req->bss.bssid); if (ret) goto done; /* set preamble to firmware */ - if (adapter->capinfo.shortpreamble && pbssdesc->cap.shortpreamble) + if (adapter->capinfo.shortpreamble && assoc_req->bss.cap.shortpreamble) adapter->preamble = cmd_type_short_preamble; else adapter->preamble = cmd_type_long_preamble; @@ -127,7 +129,7 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) libertas_set_radio_control(priv); ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate, - 0, cmd_option_waitforrsp, 0, pbssdesc); + 0, cmd_option_waitforrsp, 0, assoc_req); done: lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); @@ -141,7 +143,7 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc) * @param adhocssid The ssid of the Adhoc Network * @return 0--success, -1--fail */ -int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *adhocssid) +int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; int ret = 0; @@ -158,12 +160,11 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a libertas_set_radio_control(priv); - lbs_deb_join("curbssparams.channel = %d\n", - adapter->curbssparams.channel); - lbs_deb_join("curbssparams.band = %d\n", adapter->curbssparams.band); + lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel); + lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band); ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start, - 0, cmd_option_waitforrsp, 0, adhocssid); + 0, cmd_option_waitforrsp, 0, assoc_req); return ret; } @@ -177,34 +178,34 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a * * @return 0--success, -1--fail */ -int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbssdesc) +int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req) { wlan_adapter *adapter = priv->adapter; + struct bss_descriptor * bss = &assoc_req->bss; int ret = 0; lbs_deb_join("libertas_join_adhoc_network: CurBss.ssid =%s\n", adapter->curbssparams.ssid.ssid); lbs_deb_join("libertas_join_adhoc_network: CurBss.ssid_len =%u\n", adapter->curbssparams.ssid.ssidlength); - lbs_deb_join("libertas_join_adhoc_network: ssid =%s\n", pbssdesc->ssid.ssid); - lbs_deb_join("libertas_join_adhoc_network: ssid len =%u\n", - pbssdesc->ssid.ssidlength); + lbs_deb_join("libertas_join_adhoc_network: ssid = '%s'\n", + bss->ssid.ssid); + lbs_deb_join("libertas_join_adhoc_network: ssid len = %u\n", + bss->ssid.ssidlength); /* check if the requested SSID is already joined */ if (adapter->curbssparams.ssid.ssidlength - && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid) + && !libertas_SSID_cmp(&bss->ssid, &adapter->curbssparams.ssid) && (adapter->mode == IW_MODE_ADHOC)) { - - lbs_deb_join( + lbs_deb_join( "ADHOC_J_CMD: New ad-hoc SSID is the same as current, " "not attempting to re-join"); - return -1; } /*Use shortpreamble only when both creator and card supports short preamble */ - if (!pbssdesc->cap.shortpreamble || !adapter->capinfo.shortpreamble) { + if (!bss->cap.shortpreamble || !adapter->capinfo.shortpreamble) { lbs_deb_join("AdhocJoin: Long preamble\n"); adapter->preamble = cmd_type_long_preamble; } else { @@ -214,15 +215,14 @@ int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbs libertas_set_radio_control(priv); - lbs_deb_join("curbssparams.channel = %d\n", - adapter->curbssparams.channel); - lbs_deb_join("curbssparams.band = %c\n", adapter->curbssparams.band); + lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel); + lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); adapter->adhoccreate = 0; ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join, 0, cmd_option_waitforrsp, - OID_802_11_SSID, pbssdesc); + OID_802_11_SSID, assoc_req); return ret; } @@ -325,7 +325,8 @@ int libertas_cmd_80211_associate(wlan_private * priv, wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_associate *passo = &cmd->params.associate; int ret = 0; - struct bss_descriptor *pbssdesc; + struct assoc_request * assoc_req = pdata_buf; + struct bss_descriptor * bss = &assoc_req->bss; u8 *card_rates; u8 *pos; int card_rates_size; @@ -338,7 +339,6 @@ int libertas_cmd_80211_associate(wlan_private * priv, lbs_deb_enter(LBS_DEB_JOIN); - pbssdesc = pdata_buf; pos = (u8 *) passo; if (!adapter) { @@ -348,11 +348,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, cmd->command = cpu_to_le16(cmd_802_11_associate); - /* Save so we know which BSS Desc to use in the response handler */ - adapter->pattemptedbssdesc = pbssdesc; - - memcpy(passo->peerstaaddr, - pbssdesc->bssid, sizeof(passo->peerstaaddr)); + memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr)); pos += sizeof(passo->peerstaaddr); /* set the listen interval */ @@ -365,8 +361,8 @@ int libertas_cmd_80211_associate(wlan_private * priv, ssid = (struct mrvlietypes_ssidparamset *) pos; ssid->header.type = cpu_to_le16(TLV_TYPE_SSID); - ssid->header.len = pbssdesc->ssid.ssidlength; - memcpy(ssid->ssid, pbssdesc->ssid.ssid, ssid->header.len); + ssid->header.len = bss->ssid.ssidlength; + memcpy(ssid->ssid, bss->ssid.ssid, ssid->header.len); pos += sizeof(ssid->header) + ssid->header.len; ssid->header.len = cpu_to_le16(ssid->header.len); @@ -374,7 +370,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); phy->header.len = sizeof(phy->fh_ds.dsparamset); memcpy(&phy->fh_ds.dsparamset, - &pbssdesc->phyparamset.dsparamset.currentchan, + &bss->phyparamset.dsparamset.currentchan, sizeof(phy->fh_ds.dsparamset)); pos += sizeof(phy->header) + phy->header.len; phy->header.len = cpu_to_le16(phy->header.len); @@ -388,7 +384,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, rates = (struct mrvlietypes_ratesparamset *) pos; rates->header.type = cpu_to_le16(TLV_TYPE_RATES); - memcpy(&rates->rates, &pbssdesc->libertas_supported_rates, WLAN_SUPPORTED_RATES); + memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES); card_rates = libertas_supported_rates; card_rates_size = sizeof(libertas_supported_rates); @@ -405,12 +401,12 @@ int libertas_cmd_80211_associate(wlan_private * priv, pos += sizeof(rates->header) + rates->header.len; rates->header.len = cpu_to_le16(rates->header.len); - if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) { + if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { rsn = (struct mrvlietypes_rsnparamset *) pos; - rsn->header.type = (u16) adapter->wpa_ie[0]; /* WPA_IE or WPA2_IE */ + rsn->header.type = (u16) assoc_req->wpa_ie[0]; /* WPA_IE or WPA2_IE */ rsn->header.type = cpu_to_le16(rsn->header.type); - rsn->header.len = (u16) adapter->wpa_ie[1]; - memcpy(rsn->rsnie, &adapter->wpa_ie[2], rsn->header.len); + rsn->header.len = (u16) assoc_req->wpa_ie[1]; + memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], rsn->header.len); lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn, sizeof(rsn->header) + rsn->header.len); pos += sizeof(rsn->header) + rsn->header.len; @@ -419,7 +415,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, /* update curbssparams */ adapter->curbssparams.channel = - (pbssdesc->phyparamset.dsparamset.currentchan); + (bss->phyparamset.dsparamset.currentchan); /* Copy the infra. association rates into Current BSS state structure */ memcpy(&adapter->curbssparams.datarates, &rates->rates, @@ -428,12 +424,12 @@ int libertas_cmd_80211_associate(wlan_private * priv, lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n", rates->header.len); /* set IBSS field */ - if (pbssdesc->mode == IW_MODE_INFRA) { + if (bss->mode == IW_MODE_INFRA) { #define CAPINFO_ESS_MODE 1 passo->capinfo.ess = CAPINFO_ESS_MODE; } - if (libertas_parse_dnld_countryinfo_11d(priv)) { + if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { ret = -1; goto done; } @@ -441,7 +437,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN); /* set the capability info at last */ - memcpy(&tmpcap, &pbssdesc->cap, sizeof(passo->capinfo)); + memcpy(&tmpcap, &bss->cap, sizeof(passo->capinfo)); tmpcap &= CAPINFO_MASK; lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", tmpcap, CAPINFO_MASK); @@ -454,7 +450,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, } int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, - struct cmd_ds_command *cmd, void *pssid) + struct cmd_ds_command *cmd, void *pdata_buf) { wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads; @@ -462,8 +458,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, int cmdappendsize = 0; int i; u16 tmpcap; - struct bss_descriptor *pbssdesc; - struct WLAN_802_11_SSID *ssid = pssid; + struct assoc_request * assoc_req = pdata_buf; lbs_deb_enter(LBS_DEB_JOIN); @@ -474,9 +469,6 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start); - pbssdesc = &adapter->curbssparams.bssdescriptor; - adapter->pattemptedbssdesc = pbssdesc; - /* * Fill in the parameters for 2 data structures: * 1. cmd_ds_802_11_ad_hoc_start command @@ -490,19 +482,13 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, */ memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE); - - memcpy(adhs->SSID, ssid->ssid, ssid->ssidlength); + memcpy(adhs->SSID, assoc_req->ssid.ssid, assoc_req->ssid.ssidlength); lbs_deb_join("ADHOC_S_CMD: SSID = %s\n", adhs->SSID); - memset(pbssdesc->ssid.ssid, 0, IW_ESSID_MAX_SIZE); - memcpy(pbssdesc->ssid.ssid, ssid->ssid, ssid->ssidlength); - - pbssdesc->ssid.ssidlength = ssid->ssidlength; - /* set the BSS type */ adhs->bsstype = cmd_bss_type_ibss; - pbssdesc->mode = IW_MODE_ADHOC; + adapter->mode = IW_MODE_ADHOC; adhs->beaconperiod = adapter->beaconperiod; /* set Physical param set */ @@ -512,16 +498,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID; adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN; - WARN_ON(!adapter->curbssparams.channel); + WARN_ON(!assoc_req->channel); lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n", - adapter->curbssparams.channel); + assoc_req->channel); - pbssdesc->channel = adapter->curbssparams.channel; - adhs->phyparamset.dsparamset.currentchan = adapter->curbssparams.channel; - - memcpy(&pbssdesc->phyparamset, - &adhs->phyparamset, sizeof(union ieeetypes_phyparamset)); + adhs->phyparamset.dsparamset.currentchan = assoc_req->channel; /* set IBSS param set */ #define IBSS_PARA_IE_ID 6 @@ -530,25 +512,20 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID; adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN; adhs->ssparamset.ibssparamset.atimwindow = adapter->atimwindow; - memcpy(&pbssdesc->ssparamset, - &adhs->ssparamset, sizeof(union IEEEtypes_ssparamset)); /* set capability info */ adhs->cap.ess = 0; adhs->cap.ibss = 1; - pbssdesc->cap.ibss = 1; /* probedelay */ adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time); /* set up privacy in adapter->scantable[i] */ - if (adapter->secinfo.wep_enabled) { + if (assoc_req->secinfo.wep_enabled) { lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n"); - pbssdesc->privacy = wlan802_11privfilter8021xWEP; adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON; } else { lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n"); - pbssdesc->privacy = wlan802_11privfilteracceptall; } memset(adhs->datarate, 0, sizeof(adhs->datarate)); @@ -610,7 +587,8 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, { wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj; - struct bss_descriptor *pbssdesc = pdata_buf; + struct assoc_request * assoc_req = pdata_buf; + struct bss_descriptor *bss = &assoc_req->bss; int cmdappendsize = 0; int ret = 0; u8 *card_rates; @@ -620,27 +598,22 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, lbs_deb_enter(LBS_DEB_JOIN); - adapter->pattemptedbssdesc = pbssdesc; - cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join); padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss; - padhocjoin->bssdescriptor.beaconperiod = pbssdesc->beaconperiod; + padhocjoin->bssdescriptor.beaconperiod = bss->beaconperiod; - memcpy(&padhocjoin->bssdescriptor.BSSID, - &pbssdesc->bssid, ETH_ALEN); - - memcpy(&padhocjoin->bssdescriptor.SSID, - &pbssdesc->ssid.ssid, pbssdesc->ssid.ssidlength); + memcpy(&padhocjoin->bssdescriptor.BSSID, &bss->bssid, ETH_ALEN); + memcpy(&padhocjoin->bssdescriptor.SSID, &bss->ssid.ssid, bss->ssid.ssidlength); memcpy(&padhocjoin->bssdescriptor.phyparamset, - &pbssdesc->phyparamset, sizeof(union ieeetypes_phyparamset)); + &bss->phyparamset, sizeof(union ieeetypes_phyparamset)); memcpy(&padhocjoin->bssdescriptor.ssparamset, - &pbssdesc->ssparamset, sizeof(union IEEEtypes_ssparamset)); + &bss->ssparamset, sizeof(union IEEEtypes_ssparamset)); - memcpy(&tmpcap, &pbssdesc->cap, sizeof(struct ieeetypes_capinfo)); + memcpy(&tmpcap, &bss->cap, sizeof(struct ieeetypes_capinfo)); tmpcap &= CAPINFO_MASK; lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", @@ -649,14 +622,9 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, sizeof(struct ieeetypes_capinfo)); /* information on BSSID descriptor passed to FW */ - lbs_deb_join( - "ADHOC_J_CMD: BSSID = %2x-%2x-%2x-%2x-%2x-%2x, SSID = %s\n", - padhocjoin->bssdescriptor.BSSID[0], - padhocjoin->bssdescriptor.BSSID[1], - padhocjoin->bssdescriptor.BSSID[2], - padhocjoin->bssdescriptor.BSSID[3], - padhocjoin->bssdescriptor.BSSID[4], - padhocjoin->bssdescriptor.BSSID[5], + lbs_deb_join( + "ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n", + MAC_ARG(padhocjoin->bssdescriptor.BSSID), padhocjoin->bssdescriptor.SSID); /* failtimeout */ @@ -669,14 +637,14 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, /* Copy Data rates from the rates recorded in scan response */ memset(padhocjoin->bssdescriptor.datarates, 0, sizeof(padhocjoin->bssdescriptor.datarates)); - memcpy(padhocjoin->bssdescriptor.datarates, pbssdesc->datarates, + memcpy(padhocjoin->bssdescriptor.datarates, bss->datarates, min(sizeof(padhocjoin->bssdescriptor.datarates), - sizeof(pbssdesc->datarates))); + sizeof(bss->datarates))); card_rates = libertas_supported_rates; card_rates_size = sizeof(libertas_supported_rates); - adapter->curbssparams.channel = pbssdesc->channel; + adapter->curbssparams.channel = bss->channel; if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates, sizeof(padhocjoin->bssdescriptor.datarates), @@ -700,9 +668,9 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, adapter->curbssparams.numofrates); padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow = - cpu_to_le16(pbssdesc->atimwindow); + cpu_to_le16(bss->atimwindow); - if (adapter->secinfo.wep_enabled) { + if (assoc_req->secinfo.wep_enabled) { padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON; } @@ -722,7 +690,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, } } - if (libertas_parse_dnld_countryinfo_11d(priv)) { + if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { ret = -1; goto done; } @@ -750,17 +718,23 @@ int libertas_ret_80211_associate(wlan_private * priv, int ret = 0; union iwreq_data wrqu; struct ieeetypes_assocrsp *passocrsp; - struct bss_descriptor *pbssdesc; + struct bss_descriptor * bss; lbs_deb_enter(LBS_DEB_JOIN); + if (!adapter->in_progress_assoc_req) { + lbs_deb_join("ASSOC_RESP: no in-progress association request\n"); + ret = -1; + goto done; + } + bss = &adapter->in_progress_assoc_req->bss; + passocrsp = (struct ieeetypes_assocrsp *) & resp->params; if (passocrsp->statuscode) { - libertas_mac_event_disconnected(priv); - lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n", + lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n", passocrsp->statuscode); ret = -1; @@ -773,22 +747,12 @@ int libertas_ret_80211_associate(wlan_private * priv, /* Send a Media Connected event, according to the Spec */ adapter->connect_status = libertas_connected; - /* Set the attempted BSSID Index to current */ - pbssdesc = adapter->pattemptedbssdesc; + lbs_deb_join("ASSOC_RESP: %s\n", bss->ssid.ssid); - lbs_deb_join("ASSOC_RESP: %s\n", pbssdesc->ssid.ssid); - - /* Set the new SSID to current SSID */ + /* Update current SSID and BSSID */ memcpy(&adapter->curbssparams.ssid, - &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID)); - - /* Set the new BSSID (AP's MAC address) to current BSSID */ - memcpy(adapter->curbssparams.bssid, - pbssdesc->bssid, ETH_ALEN); - - /* Make a copy of current BSSID descriptor */ - memcpy(&adapter->curbssparams.bssdescriptor, - pbssdesc, sizeof(struct bss_descriptor)); + &bss->ssid, sizeof(struct WLAN_802_11_SSID)); + memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN); lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n", adapter->currentpacketfilter); @@ -838,30 +802,31 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, u16 result = le16_to_cpu(resp->result); struct cmd_ds_802_11_ad_hoc_result *padhocresult; union iwreq_data wrqu; - struct bss_descriptor *pbssdesc; + struct bss_descriptor *bss; lbs_deb_enter(LBS_DEB_JOIN); padhocresult = &resp->params.result; - lbs_deb_join("ADHOC_S_RESP: size = %d\n", le16_to_cpu(resp->size)); - lbs_deb_join("ADHOC_S_RESP: command = %x\n", command); - lbs_deb_join("ADHOC_S_RESP: result = %x\n", result); + lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size)); + lbs_deb_join("ADHOC_RESP: command = %x\n", command); + lbs_deb_join("ADHOC_RESP: result = %x\n", result); - pbssdesc = adapter->pattemptedbssdesc; + if (!adapter->in_progress_assoc_req) { + lbs_deb_join("ADHOC_RESP: no in-progress association request\n"); + ret = -1; + goto done; + } + bss = &adapter->in_progress_assoc_req->bss; /* * Join result code 0 --> SUCCESS */ if (result) { - lbs_deb_join("ADHOC_RESP failed\n"); + lbs_deb_join("ADHOC_RESP: failed\n"); if (adapter->connect_status == libertas_connected) { libertas_mac_event_disconnected(priv); } - - memset(&adapter->curbssparams.bssdescriptor, - 0x00, sizeof(adapter->curbssparams.bssdescriptor)); - ret = -1; goto done; } @@ -870,29 +835,22 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, * Now the join cmd should be successful * If BSSID has changed use SSID to compare instead of BSSID */ - lbs_deb_join("ADHOC_J_RESP %s\n", pbssdesc->ssid.ssid); + lbs_deb_join("ADHOC_RESP: %s\n", bss->ssid.ssid); /* Send a Media Connected event, according to the Spec */ adapter->connect_status = libertas_connected; if (command == cmd_ret_802_11_ad_hoc_start) { /* Update the created network descriptor with the new BSSID */ - memcpy(pbssdesc->bssid, padhocresult->BSSID, ETH_ALEN); - } else { - - /* Make a copy of current BSSID descriptor, only needed for join since - * the current descriptor is already being used for adhoc start - */ - memmove(&adapter->curbssparams.bssdescriptor, - pbssdesc, sizeof(struct bss_descriptor)); + memcpy(bss->bssid, padhocresult->BSSID, ETH_ALEN); } /* Set the BSSID from the joined/started descriptor */ - memcpy(&adapter->curbssparams.bssid, pbssdesc->bssid, ETH_ALEN); + memcpy(&adapter->curbssparams.bssid, bss->bssid, ETH_ALEN); /* Set the new SSID to current SSID */ - memcpy(&adapter->curbssparams.ssid, - &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID)); + memcpy(&adapter->curbssparams.ssid, &bss->ssid, + sizeof(struct WLAN_802_11_SSID)); netif_carrier_on(priv->dev); netif_wake_queue(priv->dev); diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index 115f5a8ba346..c84e33cf8752 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h @@ -9,6 +9,7 @@ #define _WLAN_JOIN_H #include "defs.h" +#include "dev.h" struct cmd_ds_command; extern int libertas_cmd_80211_authenticate(wlan_private * priv, @@ -21,7 +22,7 @@ extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv, struct cmd_ds_command *cmd); extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, struct cmd_ds_command *cmd, - void *pssid); + void *pdata_buf); extern int libertas_cmd_80211_deauthenticate(wlan_private * priv, struct cmd_ds_command *cmd); extern int libertas_cmd_80211_associate(wlan_private * priv, @@ -43,8 +44,9 @@ struct WLAN_802_11_SSID; struct bss_descriptor; extern int libertas_start_adhoc_network(wlan_private * priv, - struct WLAN_802_11_SSID *adhocssid); -extern int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor *pbssdesc); + struct assoc_request * assoc_req); +extern int libertas_join_adhoc_network(wlan_private * priv, + struct assoc_request * assoc_req); extern int libertas_stop_adhoc_network(wlan_private * priv); extern int libertas_send_deauthentication(wlan_private * priv); @@ -52,6 +54,6 @@ extern int libertas_send_deauth(wlan_private * priv); extern int libertas_do_adhocstop_ioctl(wlan_private * priv); -int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc); +int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req); #endif diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 437a1e98671f..334da0c5c5a1 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -235,24 +235,10 @@ static void wlan_scan_process_results(wlan_private * priv) wlan_adapter *adapter = priv->adapter; struct bss_descriptor * iter_bss; + if (adapter->connect_status == libertas_connected) + return; + mutex_lock(&adapter->lock); - - if (adapter->connect_status != libertas_connected) - goto debug_print; - - /* try to find the current BSSID in the scan list */ - list_for_each_entry (iter_bss, &adapter->network_list, list) { - if (libertas_SSID_cmp(&iter_bss->ssid, &adapter->curbssparams.ssid)) - continue; - if (memcmp(adapter->curbssparams.bssid, iter_bss->bssid, ETH_ALEN)) - continue; - /* Make a copy of current BSSID descriptor */ - memcpy(&adapter->curbssparams.bssdescriptor, iter_bss, - sizeof(struct bss_descriptor)); - break; - } - -debug_print: list_for_each_entry (iter_bss, &adapter->network_list, list) { lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", i++, @@ -260,7 +246,6 @@ static void wlan_scan_process_results(wlan_private * priv) iter_bss->bssid[3], iter_bss->bssid[4], iter_bss->bssid[5], (s32) iter_bss->rssi, iter_bss->ssid.ssid); } - mutex_unlock(&adapter->lock); }