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>
This commit is contained in:
committed by
John W. Linville
parent
8ad71bef4a
commit
debcf73428
@@ -435,6 +435,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
|||||||
if (!ctx->is_active)
|
if (!ctx->is_active)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* override BSSID if necessary due to preauth */
|
||||||
|
if (ctx->preauth_bssid)
|
||||||
|
memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN);
|
||||||
|
|
||||||
/* always get timestamp with Rx frame */
|
/* always get timestamp with Rx frame */
|
||||||
ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
|
ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
|
||||||
|
|
||||||
@@ -897,6 +901,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
|
|||||||
if (!priv->disable_chain_noise_cal)
|
if (!priv->disable_chain_noise_cal)
|
||||||
iwlagn_chain_noise_reset(priv);
|
iwlagn_chain_noise_reset(priv);
|
||||||
priv->start_calib = 1;
|
priv->start_calib = 1;
|
||||||
|
WARN_ON(ctx->preauth_bssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changes & BSS_CHANGED_IBSS) {
|
if (changes & BSS_CHANGED_IBSS) {
|
||||||
|
@@ -2956,6 +2956,72 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
|
|||||||
return 0;
|
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
|
* driver setup and teardown
|
||||||
@@ -3164,6 +3230,8 @@ struct ieee80211_ops iwlagn_hw_ops = {
|
|||||||
.rssi_callback = iwl_mac_rssi_callback,
|
.rssi_callback = iwl_mac_rssi_callback,
|
||||||
CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
|
CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
|
||||||
CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
|
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)
|
static u32 iwl_hw_detect(struct iwl_priv *priv)
|
||||||
|
@@ -992,6 +992,9 @@ struct iwl_rxon_context {
|
|||||||
u8 extension_chan_offset;
|
u8 extension_chan_offset;
|
||||||
} ht;
|
} ht;
|
||||||
|
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
bool preauth_bssid;
|
||||||
|
|
||||||
bool last_tx_rejected;
|
bool last_tx_rejected;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user