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

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
...@@ -764,10 +764,10 @@ static void iwl_bg_ucode_trace(unsigned long data) ...@@ -764,10 +764,10 @@ static void iwl_bg_ucode_trace(unsigned long data)
static void iwl_rx_beacon_notif(struct iwl_priv *priv, static void iwl_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb) struct iwl_rx_mem_buffer *rxb)
{ {
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl4965_beacon_notif *beacon = struct iwl4965_beacon_notif *beacon =
(struct iwl4965_beacon_notif *)pkt->u.raw; (struct iwl4965_beacon_notif *)pkt->u.raw;
#ifdef CONFIG_IWLWIFI_DEBUG
u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " 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, ...@@ -779,6 +779,8 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
le32_to_cpu(beacon->low_tsf), rate); le32_to_cpu(beacon->low_tsf), rate);
#endif #endif
priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
if ((priv->iw_mode == NL80211_IFTYPE_AP) && if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
(!test_bit(STATUS_EXIT_PENDING, &priv->status))) (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
queue_work(priv->workqueue, &priv->beacon_update); queue_work(priv->workqueue, &priv->beacon_update);
...@@ -3881,6 +3883,7 @@ static struct ieee80211_ops iwl_hw_ops = { ...@@ -3881,6 +3883,7 @@ static struct ieee80211_ops iwl_hw_ops = {
.sta_remove = iwl_mac_sta_remove, .sta_remove = iwl_mac_sta_remove,
.channel_switch = iwl_mac_channel_switch, .channel_switch = iwl_mac_channel_switch,
.flush = iwl_mac_flush, .flush = iwl_mac_flush,
.tx_last_beacon = iwl_mac_tx_last_beacon,
}; };
static void iwl_hw_detect(struct iwl_priv *priv) static void iwl_hw_detect(struct iwl_priv *priv)
......
...@@ -2919,6 +2919,11 @@ struct iwl_scancomplete_notification { ...@@ -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) * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
*/ */
......
...@@ -1666,6 +1666,14 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, ...@@ -1666,6 +1666,14 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
} }
EXPORT_SYMBOL(iwl_mac_conf_tx); 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, static void iwl_ht_conf(struct iwl_priv *priv,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
......
...@@ -350,6 +350,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, ...@@ -350,6 +350,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
void iwl_activate_qos(struct iwl_priv *priv); void iwl_activate_qos(struct iwl_priv *priv);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params); 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); void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
int iwl_check_rxon_cmd(struct iwl_priv *priv); int iwl_check_rxon_cmd(struct iwl_priv *priv);
int iwl_full_rxon_required(struct iwl_priv *priv); int iwl_full_rxon_required(struct iwl_priv *priv);
......
...@@ -1109,6 +1109,9 @@ struct iwl_priv { ...@@ -1109,6 +1109,9 @@ struct iwl_priv {
u32 ucode_beacon_time; u32 ucode_beacon_time;
int missed_beacon_threshold; int missed_beacon_threshold;
/* track IBSS manager (last beacon) status */
u32 ibss_manager;
/* storing the jiffies when the plcp error rate is received */ /* storing the jiffies when the plcp error rate is received */
unsigned long plcp_jiffies; unsigned long plcp_jiffies;
......
...@@ -814,9 +814,9 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) ...@@ -814,9 +814,9 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb) struct iwl_rx_mem_buffer *rxb)
{ {
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
#ifdef CONFIG_IWLWIFI_DEBUG
u8 rate = beacon->beacon_notify_hdr.rate; u8 rate = beacon->beacon_notify_hdr.rate;
IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " 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, ...@@ -828,6 +828,8 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
le32_to_cpu(beacon->low_tsf), rate); le32_to_cpu(beacon->low_tsf), rate);
#endif #endif
priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
if ((priv->iw_mode == NL80211_IFTYPE_AP) && if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
(!test_bit(STATUS_EXIT_PENDING, &priv->status))) (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
queue_work(priv->workqueue, &priv->beacon_update); queue_work(priv->workqueue, &priv->beacon_update);
...@@ -3803,6 +3805,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { ...@@ -3803,6 +3805,7 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.hw_scan = iwl_mac_hw_scan, .hw_scan = iwl_mac_hw_scan,
.sta_add = iwl3945_mac_sta_add, .sta_add = iwl3945_mac_sta_add,
.sta_remove = iwl_mac_sta_remove, .sta_remove = iwl_mac_sta_remove,
.tx_last_beacon = iwl_mac_tx_last_beacon,
}; };
static int iwl3945_init_drv(struct iwl_priv *priv) static int iwl3945_init_drv(struct iwl_priv *priv)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment