diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2009-11-24 18:02:26 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-28 15:05:06 -0500 |
commit | 9bf22f2c4607dbb68beb26153d83fa52b82e2d2f (patch) | |
tree | 13336c0aa86248f4608f15b597d5a09b7dbab1d2 /drivers/net/wireless | |
parent | 2944b2c2d2dd884c550163c698577132588277d8 (diff) |
iwmc3200wifi: Implement cfg80211 PMKSA API
We need to implement the PMKSA API for proper WPA2 pre-auth and fast
re-association. Our fullmac device generates all (re-)assoc IEs, and thus it
needs the right PMKIDs. With this implementation we now get them from
wpa_supplicant.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/cfg80211.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/commands.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/commands.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/umac.h | 2 |
4 files changed, 68 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 7cfc2c0a1fbc..7c4f44a9c3e6 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c | |||
@@ -725,6 +725,33 @@ static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
725 | CFG_POWER_INDEX, iwm->conf.power_index); | 725 | CFG_POWER_INDEX, iwm->conf.power_index); |
726 | } | 726 | } |
727 | 727 | ||
728 | int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
729 | struct cfg80211_pmksa *pmksa) | ||
730 | { | ||
731 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | ||
732 | |||
733 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); | ||
734 | } | ||
735 | |||
736 | int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
737 | struct cfg80211_pmksa *pmksa) | ||
738 | { | ||
739 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | ||
740 | |||
741 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); | ||
742 | } | ||
743 | |||
744 | int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) | ||
745 | { | ||
746 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | ||
747 | struct cfg80211_pmksa pmksa; | ||
748 | |||
749 | memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); | ||
750 | |||
751 | return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH); | ||
752 | } | ||
753 | |||
754 | |||
728 | static struct cfg80211_ops iwm_cfg80211_ops = { | 755 | static struct cfg80211_ops iwm_cfg80211_ops = { |
729 | .change_virtual_intf = iwm_cfg80211_change_iface, | 756 | .change_virtual_intf = iwm_cfg80211_change_iface, |
730 | .add_key = iwm_cfg80211_add_key, | 757 | .add_key = iwm_cfg80211_add_key, |
@@ -741,6 +768,9 @@ static struct cfg80211_ops iwm_cfg80211_ops = { | |||
741 | .set_tx_power = iwm_cfg80211_set_txpower, | 768 | .set_tx_power = iwm_cfg80211_set_txpower, |
742 | .get_tx_power = iwm_cfg80211_get_txpower, | 769 | .get_tx_power = iwm_cfg80211_get_txpower, |
743 | .set_power_mgmt = iwm_cfg80211_set_power_mgmt, | 770 | .set_power_mgmt = iwm_cfg80211_set_power_mgmt, |
771 | .set_pmksa = iwm_cfg80211_set_pmksa, | ||
772 | .del_pmksa = iwm_cfg80211_del_pmksa, | ||
773 | .flush_pmksa = iwm_cfg80211_flush_pmksa, | ||
744 | }; | 774 | }; |
745 | 775 | ||
746 | static const u32 cipher_suites[] = { | 776 | static const u32 cipher_suites[] = { |
@@ -786,6 +816,7 @@ struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev) | |||
786 | 816 | ||
787 | set_wiphy_dev(wdev->wiphy, dev); | 817 | set_wiphy_dev(wdev->wiphy, dev); |
788 | wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX; | 818 | wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX; |
819 | wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS; | ||
789 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 820 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
790 | BIT(NL80211_IFTYPE_ADHOC); | 821 | BIT(NL80211_IFTYPE_ADHOC); |
791 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz; | 822 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz; |
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 46ca7c58f5ac..bd0630755b32 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c | |||
@@ -960,3 +960,25 @@ int iwm_send_umac_stop_resume_tx(struct iwm_priv *iwm, | |||
960 | sizeof(struct iwm_umac_cmd_stop_resume_tx)); | 960 | sizeof(struct iwm_umac_cmd_stop_resume_tx)); |
961 | 961 | ||
962 | } | 962 | } |
963 | |||
964 | int iwm_send_pmkid_update(struct iwm_priv *iwm, | ||
965 | struct cfg80211_pmksa *pmksa, u32 command) | ||
966 | { | ||
967 | struct iwm_umac_pmkid_update update; | ||
968 | int ret; | ||
969 | |||
970 | memset(&update, 0, sizeof(struct iwm_umac_pmkid_update)); | ||
971 | |||
972 | update.command = cpu_to_le32(command); | ||
973 | memcpy(&update.bssid, pmksa->bssid, ETH_ALEN); | ||
974 | memcpy(&update.pmkid, pmksa->pmkid, WLAN_PMKID_LEN); | ||
975 | |||
976 | ret = iwm_send_wifi_if_cmd(iwm, &update, | ||
977 | sizeof(struct iwm_umac_pmkid_update), 0); | ||
978 | if (ret) { | ||
979 | IWM_ERR(iwm, "PMKID update command failed\n"); | ||
980 | return ret; | ||
981 | } | ||
982 | |||
983 | return 0; | ||
984 | } | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h index 95cdf941b222..06af0552cd75 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.h +++ b/drivers/net/wireless/iwmc3200wifi/commands.h | |||
@@ -458,6 +458,17 @@ struct iwm_umac_cmd_stop_resume_tx { | |||
458 | u16 reserved; | 458 | u16 reserved; |
459 | } __attribute__ ((packed)); | 459 | } __attribute__ ((packed)); |
460 | 460 | ||
461 | #define IWM_CMD_PMKID_ADD 1 | ||
462 | #define IWM_CMD_PMKID_DEL 2 | ||
463 | #define IWM_CMD_PMKID_FLUSH 3 | ||
464 | |||
465 | struct iwm_umac_pmkid_update { | ||
466 | __le32 command; | ||
467 | u8 bssid[ETH_ALEN]; | ||
468 | __le16 reserved; | ||
469 | u8 pmkid[WLAN_PMKID_LEN]; | ||
470 | } __attribute__ ((packed)); | ||
471 | |||
461 | /* LMAC commands */ | 472 | /* LMAC commands */ |
462 | int iwm_read_mac(struct iwm_priv *iwm, u8 *mac); | 473 | int iwm_read_mac(struct iwm_priv *iwm, u8 *mac); |
463 | int iwm_send_prio_table(struct iwm_priv *iwm); | 474 | int iwm_send_prio_table(struct iwm_priv *iwm); |
@@ -488,6 +499,8 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids, | |||
488 | int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len); | 499 | int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len); |
489 | int iwm_send_umac_stop_resume_tx(struct iwm_priv *iwm, | 500 | int iwm_send_umac_stop_resume_tx(struct iwm_priv *iwm, |
490 | struct iwm_umac_notif_stop_resume_tx *ntf); | 501 | struct iwm_umac_notif_stop_resume_tx *ntf); |
502 | int iwm_send_pmkid_update(struct iwm_priv *iwm, | ||
503 | struct cfg80211_pmksa *pmksa, u32 command); | ||
491 | 504 | ||
492 | /* UDMA commands */ | 505 | /* UDMA commands */ |
493 | int iwm_target_reset(struct iwm_priv *iwm); | 506 | int iwm_target_reset(struct iwm_priv *iwm); |
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h index 70094bfe7c91..7f54a145ca65 100644 --- a/drivers/net/wireless/iwmc3200wifi/umac.h +++ b/drivers/net/wireless/iwmc3200wifi/umac.h | |||
@@ -298,6 +298,7 @@ struct iwm_udma_out_wifi_hdr { | |||
298 | #define UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID 0x1B | 298 | #define UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID 0x1B |
299 | #define UMAC_WIFI_IF_CMD_SET_HOST_EXTENDED_IE 0x1C | 299 | #define UMAC_WIFI_IF_CMD_SET_HOST_EXTENDED_IE 0x1C |
300 | #define UMAC_WIFI_IF_CMD_GET_SUPPORTED_CHANNELS 0x1E | 300 | #define UMAC_WIFI_IF_CMD_GET_SUPPORTED_CHANNELS 0x1E |
301 | #define UMAC_WIFI_IF_CMD_PMKID_UPDATE 0x1F | ||
301 | #define UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER 0x20 | 302 | #define UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER 0x20 |
302 | 303 | ||
303 | /* UMAC WiFi interface ports */ | 304 | /* UMAC WiFi interface ports */ |
@@ -771,6 +772,7 @@ struct iwm_umac_notif_stop_resume_tx { | |||
771 | __le16 stop_resume_tid_msk; /* tid bitmask */ | 772 | __le16 stop_resume_tid_msk; /* tid bitmask */ |
772 | } __attribute__ ((packed)); | 773 | } __attribute__ ((packed)); |
773 | 774 | ||
775 | #define UMAC_MAX_NUM_PMKIDS 4 | ||
774 | 776 | ||
775 | /* WiFi interface wrapper header */ | 777 | /* WiFi interface wrapper header */ |
776 | struct iwm_umac_wifi_if { | 778 | struct iwm_umac_wifi_if { |