Skip to content

Commit

Permalink
iwmc3200wifi: refuse to associate on unallowed channels
Browse files Browse the repository at this point in the history
We need to make sure we don't associate with APs on unallowed
channels (according to regulatory setting). This could happen
when the channel is not specified (auto-select) within the
connection request. In this case we get the AP's channel until
the firmware indicates the association succeeded later. We need
to verify the associated channel. If the channel is disabled by
regulatory, we have to disassociate with the AP.

Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Zhu Yi authored and John W. Linville committed Mar 10, 2010
1 parent 6c26361 commit 7d49c61
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
12 changes: 9 additions & 3 deletions drivers/net/wireless/iwmc3200wifi/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,10 +781,9 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
return 0;
}

int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
{
struct iwm_umac_invalidate_profile invalid;
int ret;

invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
invalid.hdr.buf_size =
Expand All @@ -793,7 +792,14 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)

invalid.reason = WLAN_REASON_UNSPECIFIED;

ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
return iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
}

int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
{
int ret;

ret = __iwm_invalidate_mlme_profile(iwm);
if (ret)
return ret;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwmc3200wifi/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
void *payload, u16 payload_size);
int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags);
int iwm_send_mlme_profile(struct iwm_priv *iwm);
int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
Expand Down
15 changes: 15 additions & 0 deletions drivers/net/wireless/iwmc3200wifi/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,8 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
unsigned long buf_size,
struct iwm_wifi_cmd *cmd)
{
struct wiphy *wiphy = iwm_to_wiphy(iwm);
struct ieee80211_channel *chan;
struct iwm_umac_notif_assoc_complete *complete =
(struct iwm_umac_notif_assoc_complete *)buf;

Expand All @@ -526,6 +528,18 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,

switch (le32_to_cpu(complete->status)) {
case UMAC_ASSOC_COMPLETE_SUCCESS:
chan = ieee80211_get_channel(wiphy,
ieee80211_channel_to_frequency(complete->channel));
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
/* Associated to a unallowed channel, disassociate. */
__iwm_invalidate_mlme_profile(iwm);
IWM_WARN(iwm, "Couldn't associate with %pM due to "
"channel %d is disabled. Check your local "
"regulatory setting.\n",
complete->bssid, complete->channel);
goto failure;
}

set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
iwm->channel = complete->channel;
Expand Down Expand Up @@ -562,6 +576,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
GFP_KERNEL);
break;
case UMAC_ASSOC_COMPLETE_FAILURE:
failure:
clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
memset(iwm->bssid, 0, ETH_ALEN);
iwm->channel = 0;
Expand Down

0 comments on commit 7d49c61

Please sign in to comment.