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