aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2009-11-24 18:02:26 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-28 15:05:06 -0500
commit9bf22f2c4607dbb68beb26153d83fa52b82e2d2f (patch)
tree13336c0aa86248f4608f15b597d5a09b7dbab1d2 /drivers/net/wireless
parent2944b2c2d2dd884c550163c698577132588277d8 (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.c31
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c22
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.h13
-rw-r--r--drivers/net/wireless/iwmc3200wifi/umac.h2
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
728int 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
736int 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
744int 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
728static struct cfg80211_ops iwm_cfg80211_ops = { 755static 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
746static const u32 cipher_suites[] = { 776static 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
964int 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
465struct 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 */
462int iwm_read_mac(struct iwm_priv *iwm, u8 *mac); 473int iwm_read_mac(struct iwm_priv *iwm, u8 *mac);
463int iwm_send_prio_table(struct iwm_priv *iwm); 474int iwm_send_prio_table(struct iwm_priv *iwm);
@@ -488,6 +499,8 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
488int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len); 499int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len);
489int iwm_send_umac_stop_resume_tx(struct iwm_priv *iwm, 500int 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);
502int iwm_send_pmkid_update(struct iwm_priv *iwm,
503 struct cfg80211_pmksa *pmksa, u32 command);
491 504
492/* UDMA commands */ 505/* UDMA commands */
493int iwm_target_reset(struct iwm_priv *iwm); 506int 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 */
776struct iwm_umac_wifi_if { 778struct iwm_umac_wifi_if {