aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwmc3200wifi
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2010-02-25 01:15:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-03-10 17:09:37 -0500
commit7d49c6111c27f0e68b0310aeececf7ded53f7f94 (patch)
tree24039ba43babf5ef8b2651a8097de5eefe1bd6a0 /drivers/net/wireless/iwmc3200wifi
parent6c26361e4be3cf0dad7083e38ca52001a987e3e6 (diff)
iwmc3200wifi: refuse to associate on unallowed channels
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>
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi')
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c12
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.h1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c15
3 files changed, 25 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 1e41ad0fcad5..9ef4fd045041 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -781,10 +781,9 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
781 return 0; 781 return 0;
782} 782}
783 783
784int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) 784int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
785{ 785{
786 struct iwm_umac_invalidate_profile invalid; 786 struct iwm_umac_invalidate_profile invalid;
787 int ret;
788 787
789 invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; 788 invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
790 invalid.hdr.buf_size = 789 invalid.hdr.buf_size =
@@ -793,7 +792,14 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
793 792
794 invalid.reason = WLAN_REASON_UNSPECIFIED; 793 invalid.reason = WLAN_REASON_UNSPECIFIED;
795 794
796 ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); 795 return iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
796}
797
798int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
799{
800 int ret;
801
802 ret = __iwm_invalidate_mlme_profile(iwm);
797 if (ret) 803 if (ret)
798 return ret; 804 return ret;
799 805
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index 3dfd9f0e9003..7e16bcf59978 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -488,6 +488,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
488 void *payload, u16 payload_size); 488 void *payload, u16 payload_size);
489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); 489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags);
490int iwm_send_mlme_profile(struct iwm_priv *iwm); 490int iwm_send_mlme_profile(struct iwm_priv *iwm);
491int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
491int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); 492int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
492int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); 493int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
493int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); 494int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index ad8f7eabb5aa..36b1580329cc 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -518,6 +518,8 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
518 unsigned long buf_size, 518 unsigned long buf_size,
519 struct iwm_wifi_cmd *cmd) 519 struct iwm_wifi_cmd *cmd)
520{ 520{
521 struct wiphy *wiphy = iwm_to_wiphy(iwm);
522 struct ieee80211_channel *chan;
521 struct iwm_umac_notif_assoc_complete *complete = 523 struct iwm_umac_notif_assoc_complete *complete =
522 (struct iwm_umac_notif_assoc_complete *)buf; 524 (struct iwm_umac_notif_assoc_complete *)buf;
523 525
@@ -526,6 +528,18 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
526 528
527 switch (le32_to_cpu(complete->status)) { 529 switch (le32_to_cpu(complete->status)) {
528 case UMAC_ASSOC_COMPLETE_SUCCESS: 530 case UMAC_ASSOC_COMPLETE_SUCCESS:
531 chan = ieee80211_get_channel(wiphy,
532 ieee80211_channel_to_frequency(complete->channel));
533 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
534 /* Associated to a unallowed channel, disassociate. */
535 __iwm_invalidate_mlme_profile(iwm);
536 IWM_WARN(iwm, "Couldn't associate with %pM due to "
537 "channel %d is disabled. Check your local "
538 "regulatory setting.\n",
539 complete->bssid, complete->channel);
540 goto failure;
541 }
542
529 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 543 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
530 memcpy(iwm->bssid, complete->bssid, ETH_ALEN); 544 memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
531 iwm->channel = complete->channel; 545 iwm->channel = complete->channel;
@@ -562,6 +576,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
562 GFP_KERNEL); 576 GFP_KERNEL);
563 break; 577 break;
564 case UMAC_ASSOC_COMPLETE_FAILURE: 578 case UMAC_ASSOC_COMPLETE_FAILURE:
579 failure:
565 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 580 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
566 memset(iwm->bssid, 0, ETH_ALEN); 581 memset(iwm->bssid, 0, ETH_ALEN);
567 iwm->channel = 0; 582 iwm->channel = 0;