diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-08-26 02:13:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-29 15:33:01 -0400 |
commit | debcf734287a4e15710e6da7add0febca349d5b4 (patch) | |
tree | 941abef68830eb7f1068aa171d8b6a9c0cb90e7c | |
parent | 8ad71bef4a9d8173cbcfbb2f796b08d33d4ca01b (diff) |
iwlagn: handle GO powersave
In order to implement support for GO powersave on
the P2P client side, the ucode needs to know what
GO we're trying to authenticate/associate with,
it needs to have a station entry and the BSSID in
the RXON set.
Implement the new mac80211 callbacks to give this
data to the device.
Since this is also useful for the device when a
normal connection is established, also program it
with the information in that case.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 68 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 3 |
3 files changed, 76 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index b4d7460f05ca..1af276739d87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -435,6 +435,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
435 | if (!ctx->is_active) | 435 | if (!ctx->is_active) |
436 | return 0; | 436 | return 0; |
437 | 437 | ||
438 | /* override BSSID if necessary due to preauth */ | ||
439 | if (ctx->preauth_bssid) | ||
440 | memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN); | ||
441 | |||
438 | /* always get timestamp with Rx frame */ | 442 | /* always get timestamp with Rx frame */ |
439 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; | 443 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; |
440 | 444 | ||
@@ -897,6 +901,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
897 | if (!priv->disable_chain_noise_cal) | 901 | if (!priv->disable_chain_noise_cal) |
898 | iwlagn_chain_noise_reset(priv); | 902 | iwlagn_chain_noise_reset(priv); |
899 | priv->start_calib = 1; | 903 | priv->start_calib = 1; |
904 | WARN_ON(ctx->preauth_bssid); | ||
900 | } | 905 | } |
901 | 906 | ||
902 | if (changes & BSS_CHANGED_IBSS) { | 907 | if (changes & BSS_CHANGED_IBSS) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a0cf486f7625..8113fbe770a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2956,6 +2956,72 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
2956 | return 0; | 2956 | return 0; |
2957 | } | 2957 | } |
2958 | 2958 | ||
2959 | static int iwl_mac_tx_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
2960 | const u8 *bssid, enum ieee80211_tx_sync_type type) | ||
2961 | { | ||
2962 | struct iwl_priv *priv = hw->priv; | ||
2963 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2964 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
2965 | int ret; | ||
2966 | u8 sta_id; | ||
2967 | |||
2968 | mutex_lock(&priv->shrd->mutex); | ||
2969 | |||
2970 | if (iwl_is_associated_ctx(ctx)) { | ||
2971 | ret = 0; | ||
2972 | goto out; | ||
2973 | } | ||
2974 | |||
2975 | if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | ||
2976 | ret = -EBUSY; | ||
2977 | goto out; | ||
2978 | } | ||
2979 | |||
2980 | ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); | ||
2981 | if (ret) | ||
2982 | goto out; | ||
2983 | |||
2984 | if (WARN_ON(sta_id != ctx->ap_sta_id)) { | ||
2985 | ret = -EIO; | ||
2986 | goto out_remove_sta; | ||
2987 | } | ||
2988 | |||
2989 | memcpy(ctx->bssid, bssid, ETH_ALEN); | ||
2990 | ctx->preauth_bssid = true; | ||
2991 | |||
2992 | ret = iwlagn_commit_rxon(priv, ctx); | ||
2993 | |||
2994 | if (ret == 0) | ||
2995 | goto out; | ||
2996 | |||
2997 | out_remove_sta: | ||
2998 | iwl_remove_station(priv, sta_id, bssid); | ||
2999 | out: | ||
3000 | mutex_unlock(&priv->shrd->mutex); | ||
3001 | return ret; | ||
3002 | } | ||
3003 | |||
3004 | static void iwl_mac_finish_tx_sync(struct ieee80211_hw *hw, | ||
3005 | struct ieee80211_vif *vif, | ||
3006 | const u8 *bssid, | ||
3007 | enum ieee80211_tx_sync_type type) | ||
3008 | { | ||
3009 | struct iwl_priv *priv = hw->priv; | ||
3010 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
3011 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
3012 | |||
3013 | mutex_lock(&priv->shrd->mutex); | ||
3014 | |||
3015 | if (iwl_is_associated_ctx(ctx)) | ||
3016 | goto out; | ||
3017 | |||
3018 | iwl_remove_station(priv, ctx->ap_sta_id, bssid); | ||
3019 | ctx->preauth_bssid = false; | ||
3020 | /* no need to commit */ | ||
3021 | out: | ||
3022 | mutex_unlock(&priv->shrd->mutex); | ||
3023 | } | ||
3024 | |||
2959 | /***************************************************************************** | 3025 | /***************************************************************************** |
2960 | * | 3026 | * |
2961 | * driver setup and teardown | 3027 | * driver setup and teardown |
@@ -3164,6 +3230,8 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
3164 | .rssi_callback = iwl_mac_rssi_callback, | 3230 | .rssi_callback = iwl_mac_rssi_callback, |
3165 | CFG80211_TESTMODE_CMD(iwl_testmode_cmd) | 3231 | CFG80211_TESTMODE_CMD(iwl_testmode_cmd) |
3166 | CFG80211_TESTMODE_DUMP(iwl_testmode_dump) | 3232 | CFG80211_TESTMODE_DUMP(iwl_testmode_dump) |
3233 | .tx_sync = iwl_mac_tx_sync, | ||
3234 | .finish_tx_sync = iwl_mac_finish_tx_sync, | ||
3167 | }; | 3235 | }; |
3168 | 3236 | ||
3169 | static u32 iwl_hw_detect(struct iwl_priv *priv) | 3237 | static u32 iwl_hw_detect(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 33a829ad7e2a..1e54293532b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -992,6 +992,9 @@ struct iwl_rxon_context { | |||
992 | u8 extension_chan_offset; | 992 | u8 extension_chan_offset; |
993 | } ht; | 993 | } ht; |
994 | 994 | ||
995 | u8 bssid[ETH_ALEN]; | ||
996 | bool preauth_bssid; | ||
997 | |||
995 | bool last_tx_rejected; | 998 | bool last_tx_rejected; |
996 | }; | 999 | }; |
997 | 1000 | ||