Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Johannes Berg and committed by
John W. Linville
debcf734 8ad71bef

+76
+5
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
··· 435 435 if (!ctx->is_active) 436 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 442 /* always get timestamp with Rx frame */ 439 443 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; 440 444 ··· 901 897 if (!priv->disable_chain_noise_cal) 902 898 iwlagn_chain_noise_reset(priv); 903 899 priv->start_calib = 1; 900 + WARN_ON(ctx->preauth_bssid); 904 901 } 905 902 906 903 if (changes & BSS_CHANGED_IBSS) {
+68
drivers/net/wireless/iwlwifi/iwl-agn.c
··· 2956 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 3027 * driver setup and teardown ··· 3230 3164 .rssi_callback = iwl_mac_rssi_callback, 3231 3165 CFG80211_TESTMODE_CMD(iwl_testmode_cmd) 3232 3166 CFG80211_TESTMODE_DUMP(iwl_testmode_dump) 3167 + .tx_sync = iwl_mac_tx_sync, 3168 + .finish_tx_sync = iwl_mac_finish_tx_sync, 3233 3169 }; 3234 3170 3235 3171 static u32 iwl_hw_detect(struct iwl_priv *priv)
+3
drivers/net/wireless/iwlwifi/iwl-dev.h
··· 992 992 u8 extension_chan_offset; 993 993 } ht; 994 994 995 + u8 bssid[ETH_ALEN]; 996 + bool preauth_bssid; 997 + 995 998 bool last_tx_rejected; 996 999 }; 997 1000