Commit a85d7cca authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

iwlwifi: track IBSS manager status



Only the IBSS manager, ie. the station that sent
the IBSS beacon last, should be replying to probe
responses. This requires implementing the mac80211
tx_last_beacon callback, which we can do thanks to
the ucode beacon notification.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 07d4f1ad
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -764,10 +764,10 @@ static void iwl_bg_ucode_trace(unsigned long data)
static void iwl_rx_beacon_notif(struct iwl_priv *priv,
				struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWLWIFI_DEBUG
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
	struct iwl4965_beacon_notif *beacon =
		(struct iwl4965_beacon_notif *)pkt->u.raw;
#ifdef CONFIG_IWLWIFI_DEBUG
	u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);

	IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
@@ -779,6 +779,8 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
		le32_to_cpu(beacon->low_tsf), rate);
#endif

	priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);

	if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
	    (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
		queue_work(priv->workqueue, &priv->beacon_update);
@@ -3881,6 +3883,7 @@ static struct ieee80211_ops iwl_hw_ops = {
	.sta_remove = iwl_mac_sta_remove,
	.channel_switch = iwl_mac_channel_switch,
	.flush = iwl_mac_flush,
	.tx_last_beacon = iwl_mac_tx_last_beacon,
};

static void iwl_hw_detect(struct iwl_priv *priv)
+5 −0
Original line number Diff line number Diff line
@@ -2919,6 +2919,11 @@ struct iwl_scancomplete_notification {
 *
 *****************************************************************************/

enum iwl_ibss_manager {
	IWL_NOT_IBSS_MANAGER = 0,
	IWL_IBSS_MANAGER = 1,
};

/*
 * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
 */
+8 −0
Original line number Diff line number Diff line
@@ -1666,6 +1666,14 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
}
EXPORT_SYMBOL(iwl_mac_conf_tx);

int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
{
	struct iwl_priv *priv = hw->priv;

	return priv->ibss_manager == IWL_IBSS_MANAGER;
}
EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);

static void iwl_ht_conf(struct iwl_priv *priv,
			struct ieee80211_vif *vif)
{
+1 −0
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
void iwl_activate_qos(struct iwl_priv *priv);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
		    const struct ieee80211_tx_queue_params *params);
int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
int iwl_check_rxon_cmd(struct iwl_priv *priv);
int iwl_full_rxon_required(struct iwl_priv *priv);
+3 −0
Original line number Diff line number Diff line
@@ -1109,6 +1109,9 @@ struct iwl_priv {
	u32 ucode_beacon_time;
	int missed_beacon_threshold;

	/* track IBSS manager (last beacon) status */
	u32 ibss_manager;

	/* storing the jiffies when the plcp error rate is received */
	unsigned long plcp_jiffies;

Loading