Skip to content

Commit

Permalink
iwlwifi: track IBSS manager status
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Aug 16, 2010
1 parent 07d4f1a commit a85d7cc
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 2 deletions.
5 changes: 4 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
*/
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
5 changes: 4 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a85d7cc

Please sign in to comment.