From debcf734287a4e15710e6da7add0febca349d5b4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 25 Aug 2011 23:13:56 -0700 Subject: 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 Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c') 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) return 0; } +static int iwl_mac_tx_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const u8 *bssid, enum ieee80211_tx_sync_type type) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *ctx = vif_priv->ctx; + int ret; + u8 sta_id; + + mutex_lock(&priv->shrd->mutex); + + if (iwl_is_associated_ctx(ctx)) { + ret = 0; + goto out; + } + + if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { + ret = -EBUSY; + goto out; + } + + ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); + if (ret) + goto out; + + if (WARN_ON(sta_id != ctx->ap_sta_id)) { + ret = -EIO; + goto out_remove_sta; + } + + memcpy(ctx->bssid, bssid, ETH_ALEN); + ctx->preauth_bssid = true; + + ret = iwlagn_commit_rxon(priv, ctx); + + if (ret == 0) + goto out; + + out_remove_sta: + iwl_remove_station(priv, sta_id, bssid); + out: + mutex_unlock(&priv->shrd->mutex); + return ret; +} + +static void iwl_mac_finish_tx_sync(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *bssid, + enum ieee80211_tx_sync_type type) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *ctx = vif_priv->ctx; + + mutex_lock(&priv->shrd->mutex); + + if (iwl_is_associated_ctx(ctx)) + goto out; + + iwl_remove_station(priv, ctx->ap_sta_id, bssid); + ctx->preauth_bssid = false; + /* no need to commit */ + out: + mutex_unlock(&priv->shrd->mutex); +} + /***************************************************************************** * * driver setup and teardown @@ -3164,6 +3230,8 @@ struct ieee80211_ops iwlagn_hw_ops = { .rssi_callback = iwl_mac_rssi_callback, CFG80211_TESTMODE_CMD(iwl_testmode_cmd) CFG80211_TESTMODE_DUMP(iwl_testmode_dump) + .tx_sync = iwl_mac_tx_sync, + .finish_tx_sync = iwl_mac_finish_tx_sync, }; static u32 iwl_hw_detect(struct iwl_priv *priv) -- cgit v1.2.3