diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/iwmc3200wifi/cfg80211.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi/cfg80211.c')
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/cfg80211.c | 83 |
1 files changed, 59 insertions, 24 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index f3c55658225b..a1d45cce0ebc 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include <linux/wireless.h> | 28 | #include <linux/wireless.h> |
29 | #include <linux/ieee80211.h> | 29 | #include <linux/ieee80211.h> |
30 | #include <linux/slab.h> | ||
30 | #include <net/cfg80211.h> | 31 | #include <net/cfg80211.h> |
31 | 32 | ||
32 | #include "iwm.h" | 33 | #include "iwm.h" |
@@ -405,39 +406,21 @@ static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
405 | { | 406 | { |
406 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 407 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
407 | struct ieee80211_channel *chan = params->channel; | 408 | struct ieee80211_channel *chan = params->channel; |
408 | struct cfg80211_bss *bss; | ||
409 | 409 | ||
410 | if (!test_bit(IWM_STATUS_READY, &iwm->status)) | 410 | if (!test_bit(IWM_STATUS_READY, &iwm->status)) |
411 | return -EIO; | 411 | return -EIO; |
412 | 412 | ||
413 | /* UMAC doesn't support creating IBSS network with specified bssid. | 413 | /* UMAC doesn't support creating or joining an IBSS network |
414 | * This should be removed after we have join only mode supported. */ | 414 | * with specified bssid. */ |
415 | if (params->bssid) | 415 | if (params->bssid) |
416 | return -EOPNOTSUPP; | 416 | return -EOPNOTSUPP; |
417 | 417 | ||
418 | bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL, | ||
419 | params->ssid, params->ssid_len); | ||
420 | if (!bss) { | ||
421 | iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len); | ||
422 | schedule_timeout_interruptible(2 * HZ); | ||
423 | bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL, | ||
424 | params->ssid, params->ssid_len); | ||
425 | } | ||
426 | /* IBSS join only mode is not supported by UMAC ATM */ | ||
427 | if (bss) { | ||
428 | cfg80211_put_bss(bss); | ||
429 | return -EOPNOTSUPP; | ||
430 | } | ||
431 | |||
432 | iwm->channel = ieee80211_frequency_to_channel(chan->center_freq); | 418 | iwm->channel = ieee80211_frequency_to_channel(chan->center_freq); |
433 | iwm->umac_profile->ibss.band = chan->band; | 419 | iwm->umac_profile->ibss.band = chan->band; |
434 | iwm->umac_profile->ibss.channel = iwm->channel; | 420 | iwm->umac_profile->ibss.channel = iwm->channel; |
435 | iwm->umac_profile->ssid.ssid_len = params->ssid_len; | 421 | iwm->umac_profile->ssid.ssid_len = params->ssid_len; |
436 | memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len); | 422 | memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len); |
437 | 423 | ||
438 | if (params->bssid) | ||
439 | memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN); | ||
440 | |||
441 | return iwm_send_mlme_profile(iwm); | 424 | return iwm_send_mlme_profile(iwm); |
442 | } | 425 | } |
443 | 426 | ||
@@ -490,12 +473,12 @@ static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version) | |||
490 | return 0; | 473 | return 0; |
491 | } | 474 | } |
492 | 475 | ||
476 | if (wpa_version & NL80211_WPA_VERSION_1) | ||
477 | iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK; | ||
478 | |||
493 | if (wpa_version & NL80211_WPA_VERSION_2) | 479 | if (wpa_version & NL80211_WPA_VERSION_2) |
494 | iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK; | 480 | iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK; |
495 | 481 | ||
496 | if (wpa_version & NL80211_WPA_VERSION_1) | ||
497 | iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK; | ||
498 | |||
499 | return 0; | 482 | return 0; |
500 | } | 483 | } |
501 | 484 | ||
@@ -646,6 +629,13 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
646 | iwm->default_key = sme->key_idx; | 629 | iwm->default_key = sme->key_idx; |
647 | } | 630 | } |
648 | 631 | ||
632 | /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */ | ||
633 | if ((iwm->umac_profile->sec.flags & | ||
634 | (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) && | ||
635 | iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) { | ||
636 | iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK; | ||
637 | } | ||
638 | |||
649 | ret = iwm_send_mlme_profile(iwm); | 639 | ret = iwm_send_mlme_profile(iwm); |
650 | 640 | ||
651 | if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK || | 641 | if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK || |
@@ -682,10 +672,24 @@ static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, | |||
682 | static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, | 672 | static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, |
683 | enum tx_power_setting type, int dbm) | 673 | enum tx_power_setting type, int dbm) |
684 | { | 674 | { |
675 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | ||
676 | int ret; | ||
677 | |||
685 | switch (type) { | 678 | switch (type) { |
686 | case TX_POWER_AUTOMATIC: | 679 | case TX_POWER_AUTOMATIC: |
687 | return 0; | 680 | return 0; |
681 | case TX_POWER_FIXED: | ||
682 | if (!test_bit(IWM_STATUS_READY, &iwm->status)) | ||
683 | return 0; | ||
684 | |||
685 | ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, | ||
686 | CFG_TX_PWR_LIMIT_USR, dbm * 2); | ||
687 | if (ret < 0) | ||
688 | return ret; | ||
689 | |||
690 | return iwm_tx_power_trigger(iwm); | ||
688 | default: | 691 | default: |
692 | IWM_ERR(iwm, "Unsupported power type: %d\n", type); | ||
689 | return -EOPNOTSUPP; | 693 | return -EOPNOTSUPP; |
690 | } | 694 | } |
691 | 695 | ||
@@ -696,7 +700,7 @@ static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) | |||
696 | { | 700 | { |
697 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 701 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
698 | 702 | ||
699 | *dbm = iwm->txpower; | 703 | *dbm = iwm->txpower >> 1; |
700 | 704 | ||
701 | return 0; | 705 | return 0; |
702 | } | 706 | } |
@@ -722,6 +726,33 @@ static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
722 | CFG_POWER_INDEX, iwm->conf.power_index); | 726 | CFG_POWER_INDEX, iwm->conf.power_index); |
723 | } | 727 | } |
724 | 728 | ||
729 | int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
730 | struct cfg80211_pmksa *pmksa) | ||
731 | { | ||
732 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | ||
733 | |||
734 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); | ||
735 | } | ||
736 | |||
737 | int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
738 | struct cfg80211_pmksa *pmksa) | ||
739 | { | ||
740 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | ||
741 | |||
742 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); | ||
743 | } | ||
744 | |||
745 | int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) | ||
746 | { | ||
747 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | ||
748 | struct cfg80211_pmksa pmksa; | ||
749 | |||
750 | memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); | ||
751 | |||
752 | return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH); | ||
753 | } | ||
754 | |||
755 | |||
725 | static struct cfg80211_ops iwm_cfg80211_ops = { | 756 | static struct cfg80211_ops iwm_cfg80211_ops = { |
726 | .change_virtual_intf = iwm_cfg80211_change_iface, | 757 | .change_virtual_intf = iwm_cfg80211_change_iface, |
727 | .add_key = iwm_cfg80211_add_key, | 758 | .add_key = iwm_cfg80211_add_key, |
@@ -738,6 +769,9 @@ static struct cfg80211_ops iwm_cfg80211_ops = { | |||
738 | .set_tx_power = iwm_cfg80211_set_txpower, | 769 | .set_tx_power = iwm_cfg80211_set_txpower, |
739 | .get_tx_power = iwm_cfg80211_get_txpower, | 770 | .get_tx_power = iwm_cfg80211_get_txpower, |
740 | .set_power_mgmt = iwm_cfg80211_set_power_mgmt, | 771 | .set_power_mgmt = iwm_cfg80211_set_power_mgmt, |
772 | .set_pmksa = iwm_cfg80211_set_pmksa, | ||
773 | .del_pmksa = iwm_cfg80211_del_pmksa, | ||
774 | .flush_pmksa = iwm_cfg80211_flush_pmksa, | ||
741 | }; | 775 | }; |
742 | 776 | ||
743 | static const u32 cipher_suites[] = { | 777 | static const u32 cipher_suites[] = { |
@@ -783,6 +817,7 @@ struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev) | |||
783 | 817 | ||
784 | set_wiphy_dev(wdev->wiphy, dev); | 818 | set_wiphy_dev(wdev->wiphy, dev); |
785 | wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX; | 819 | wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX; |
820 | wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS; | ||
786 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 821 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
787 | BIT(NL80211_IFTYPE_ADHOC); | 822 | BIT(NL80211_IFTYPE_ADHOC); |
788 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz; | 823 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz; |