diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-07-31 15:34:10 (GMT) |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-16 19:26:38 (GMT) |
commit | a85d7cca1204f2dba86d2f61693f0fe8c48f0fa5 (patch) | |
tree | 78613f0415c0feca672b382d9c98f1c69c25b7e9 /drivers/net/wireless/iwlwifi | |
parent | 07d4f1ad2c21273f0f89a3d2202d22fcaf901439 (diff) | |
download | linux-fsl-qoriq-a85d7cca1204f2dba86d2f61693f0fe8c48f0fa5.tar.xz |
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: 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>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-commands.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 5 |
6 files changed, 25 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8684f26..43e078b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -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) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 60725a5..9435fd9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -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) */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 78882f9..ccdf3c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -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) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index cca7428..7f1aaf2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -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); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f35bcad..5996355 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -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; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index de6d592..b14eaf9 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -814,9 +814,9 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) static void iwl3945_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 iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); +#ifdef CONFIG_IWLWIFI_DEBUG u8 rate = beacon->beacon_notify_hdr.rate; IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " @@ -828,6 +828,8 @@ static void iwl3945_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); @@ -3803,6 +3805,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .hw_scan = iwl_mac_hw_scan, .sta_add = iwl3945_mac_sta_add, .sta_remove = iwl_mac_sta_remove, + .tx_last_beacon = iwl_mac_tx_last_beacon, }; static int iwl3945_init_drv(struct iwl_priv *priv) |