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>
This commit is contained in:
parent
07d4f1ad2c
commit
a85d7cca12
6 changed files with 25 additions and 2 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue