forked from Minki/linux
iwlwifi: introduce beacon context
Only one context can be beaconing at a time, but we need to track which one. Introduce a new variable priv->beacon_ctx to do that. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
This commit is contained in:
parent
7e6a588601
commit
76d048151c
@ -345,6 +345,13 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
|
||||
* beacon contents.
|
||||
*/
|
||||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
if (!priv->beacon_ctx) {
|
||||
IWL_ERR(priv, "trying to build beacon w/o beacon context!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Initialize memory */
|
||||
tx_beacon_cmd = &frame->u.beacon;
|
||||
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
|
||||
@ -357,9 +364,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
|
||||
|
||||
/* Set up TX command fields */
|
||||
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
|
||||
#warning "Use proper STA ID"
|
||||
tx_beacon_cmd->tx.sta_id =
|
||||
priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
|
||||
tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id;
|
||||
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
|
||||
tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
|
||||
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
|
||||
@ -369,7 +374,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
|
||||
frame_size);
|
||||
|
||||
/* Set up packet rate and flags */
|
||||
rate = iwl_rate_get_lowest_plcp(priv);
|
||||
rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx);
|
||||
priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
|
||||
priv->hw_params.valid_tx_ant);
|
||||
rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
|
||||
@ -602,25 +607,28 @@ static void iwl_bg_beacon_update(struct work_struct *work)
|
||||
container_of(work, struct iwl_priv, beacon_update);
|
||||
struct sk_buff *beacon;
|
||||
|
||||
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
|
||||
#warning "introduce and use beacon context"
|
||||
beacon = ieee80211_beacon_get(priv->hw,
|
||||
priv->contexts[IWL_RXON_CTX_BSS].vif);
|
||||
|
||||
if (!beacon) {
|
||||
IWL_ERR(priv, "update beacon failed\n");
|
||||
return;
|
||||
mutex_lock(&priv->mutex);
|
||||
if (!priv->beacon_ctx) {
|
||||
IWL_ERR(priv, "updating beacon w/o beacon context!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
|
||||
beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
|
||||
if (!beacon) {
|
||||
IWL_ERR(priv, "update beacon failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
/* new beacon skb is allocated every time; dispose previous.*/
|
||||
if (priv->ibss_beacon)
|
||||
dev_kfree_skb(priv->ibss_beacon);
|
||||
|
||||
priv->ibss_beacon = beacon;
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
iwl_send_beacon_cmd(priv);
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwl_bg_bt_runtime_config(struct work_struct *work)
|
||||
@ -3477,6 +3485,8 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
|
||||
int ret = 0;
|
||||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
|
@ -699,11 +699,9 @@ int iwl_full_rxon_required(struct iwl_priv *priv,
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_full_rxon_required);
|
||||
|
||||
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
|
||||
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
#if !TODO
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
#endif
|
||||
/*
|
||||
* Assign the lowest rate -- should really get this from
|
||||
* the beacon skb from mac80211.
|
||||
@ -1723,6 +1721,14 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
if (!priv->beacon_ctx) {
|
||||
IWL_ERR(priv, "update beacon but no beacon context!\n");
|
||||
dev_kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!iwl_is_ready_rf(priv)) {
|
||||
IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
|
||||
return -EIO;
|
||||
@ -1741,9 +1747,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
#warning "use beacon context?"
|
||||
priv->cfg->ops->lib->post_associate(
|
||||
priv, priv->contexts[IWL_RXON_CTX_BSS].vif);
|
||||
priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1773,6 +1777,18 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
if (changes & BSS_CHANGED_BEACON_ENABLED) {
|
||||
/*
|
||||
* the add_interface code must make sure we only ever
|
||||
* have a single interface that could be beaconing at
|
||||
* any time.
|
||||
*/
|
||||
if (vif->bss_conf.enable_beacon)
|
||||
priv->beacon_ctx = ctx;
|
||||
else
|
||||
priv->beacon_ctx = NULL;
|
||||
}
|
||||
|
||||
if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
|
||||
dev_kfree_skb(priv->ibss_beacon);
|
||||
priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
|
||||
|
@ -523,7 +523,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
|
||||
|
||||
int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
|
||||
|
||||
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
|
||||
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx);
|
||||
|
||||
u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
|
||||
|
||||
|
@ -1437,6 +1437,8 @@ struct iwl_priv {
|
||||
struct work_struct rx_replenish;
|
||||
struct work_struct abort_scan;
|
||||
struct work_struct beacon_update;
|
||||
struct iwl_rxon_context *beacon_ctx;
|
||||
|
||||
struct work_struct tt_work;
|
||||
struct work_struct ct_enter;
|
||||
struct work_struct ct_exit;
|
||||
|
@ -343,7 +343,8 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rate = iwl_rate_get_lowest_plcp(priv);
|
||||
rate = iwl_rate_get_lowest_plcp(priv,
|
||||
&priv->contexts[IWL_RXON_CTX_BSS]);
|
||||
|
||||
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user