Commit 352bc8de authored by Zhu, Yi's avatar Zhu, Yi Committed by John W. Linville

iwlwifi: configure_filter rewrite

The patch rewrites the mac80211 configure_filter handler to better mapping
mac80211 filter flags to iwlwifi hardware filter flags. We now can support
5 mac80211 filter flags: FIF_OTHER_BSS, FIF_ALLMULTI, FIF_PROMISC_IN_BSS,
FIF_BCN_PRBRESP_PROMISC and FIF_CONTROL. This patch also avoids reconnecting
if the filter flags are changed when the STA is associated. Because rx_assoc
is used when full rxon is not necessary.
Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c3056065
...@@ -886,7 +886,6 @@ struct iwl3945_priv { ...@@ -886,7 +886,6 @@ struct iwl3945_priv {
struct work_struct report_work; struct work_struct report_work;
struct work_struct request_scan; struct work_struct request_scan;
struct work_struct beacon_update; struct work_struct beacon_update;
struct work_struct set_monitor;
struct tasklet_struct irq_tasklet; struct tasklet_struct irq_tasklet;
......
...@@ -2224,27 +2224,6 @@ static void iwl_bg_rf_kill(struct work_struct *work) ...@@ -2224,27 +2224,6 @@ static void iwl_bg_rf_kill(struct work_struct *work)
iwl_rfkill_set_hw_state(priv); iwl_rfkill_set_hw_state(priv);
} }
static void iwl_bg_set_monitor(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work,
struct iwl_priv, set_monitor);
int ret;
IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");
mutex_lock(&priv->mutex);
ret = iwl_set_mode(priv, NL80211_IFTYPE_MONITOR);
if (ret) {
if (ret == -EAGAIN)
IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
else
IWL_ERROR("iwl_set_mode() failed ret = %d\n", ret);
}
mutex_unlock(&priv->mutex);
}
static void iwl_bg_run_time_calib_work(struct work_struct *work) static void iwl_bg_run_time_calib_work(struct work_struct *work)
{ {
struct iwl_priv *priv = container_of(work, struct iwl_priv, struct iwl_priv *priv = container_of(work, struct iwl_priv,
...@@ -2890,16 +2869,43 @@ static void iwl_configure_filter(struct ieee80211_hw *hw, ...@@ -2890,16 +2869,43 @@ static void iwl_configure_filter(struct ieee80211_hw *hw,
int mc_count, struct dev_addr_list *mc_list) int mc_count, struct dev_addr_list *mc_list)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = hw->priv;
__le32 *filter_flags = &priv->staging_rxon.filter_flags;
IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
changed_flags, *total_flags);
if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
NL80211_IFTYPE_MONITOR, *filter_flags |= RXON_FILTER_PROMISC_MSK;
changed_flags, *total_flags); else
/* queue work 'cuz mac80211 is holding a lock which *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
* prevents us from issuing (synchronous) f/w cmds */ }
queue_work(priv->workqueue, &priv->set_monitor); if (changed_flags & FIF_ALLMULTI) {
if (*total_flags & FIF_ALLMULTI)
*filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
else
*filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
}
if (changed_flags & FIF_CONTROL) {
if (*total_flags & FIF_CONTROL)
*filter_flags |= RXON_FILTER_CTL2HOST_MSK;
else
*filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
}
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
*filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
else
*filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
} }
*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI |
/* We avoid iwl_commit_rxon here to commit the new filter flags
* since mac80211 will call ieee80211_hw_config immediately.
* (mc_list is not supported at this time). Otherwise, we need to
* queue a background iwl_commit_rxon work.
*/
*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
} }
...@@ -3796,7 +3802,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) ...@@ -3796,7 +3802,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
INIT_WORK(&priv->set_monitor, iwl_bg_set_monitor);
INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
......
...@@ -985,7 +985,6 @@ struct iwl_priv { ...@@ -985,7 +985,6 @@ struct iwl_priv {
struct work_struct report_work; struct work_struct report_work;
struct work_struct request_scan; struct work_struct request_scan;
struct work_struct beacon_update; struct work_struct beacon_update;
struct work_struct set_monitor;
struct tasklet_struct irq_tasklet; struct tasklet_struct irq_tasklet;
......
...@@ -5996,24 +5996,6 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) ...@@ -5996,24 +5996,6 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
iwl3945_rfkill_set_hw_state(priv); iwl3945_rfkill_set_hw_state(priv);
} }
static void iwl3945_bg_set_monitor(struct work_struct *work)
{
struct iwl3945_priv *priv = container_of(work,
struct iwl3945_priv, set_monitor);
IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");
mutex_lock(&priv->mutex);
if (!iwl3945_is_ready(priv))
IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
else
if (iwl3945_set_mode(priv, NL80211_IFTYPE_MONITOR) != 0)
IWL_ERROR("iwl3945_set_mode() failed\n");
mutex_unlock(&priv->mutex);
}
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
static void iwl3945_bg_scan_check(struct work_struct *data) static void iwl3945_bg_scan_check(struct work_struct *data)
...@@ -6830,16 +6812,43 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, ...@@ -6830,16 +6812,43 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
int mc_count, struct dev_addr_list *mc_list) int mc_count, struct dev_addr_list *mc_list)
{ {
struct iwl3945_priv *priv = hw->priv; struct iwl3945_priv *priv = hw->priv;
__le32 *filter_flags = &priv->staging_rxon.filter_flags;
if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", changed_flags, *total_flags);
NL80211_IFTYPE_MONITOR,
changed_flags, *total_flags); if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
/* queue work 'cuz mac80211 is holding a lock which if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
* prevents us from issuing (synchronous) f/w cmds */ *filter_flags |= RXON_FILTER_PROMISC_MSK;
queue_work(priv->workqueue, &priv->set_monitor); else
*filter_flags &= ~RXON_FILTER_PROMISC_MSK;
}
if (changed_flags & FIF_ALLMULTI) {
if (*total_flags & FIF_ALLMULTI)
*filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
else
*filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
}
if (changed_flags & FIF_CONTROL) {
if (*total_flags & FIF_CONTROL)
*filter_flags |= RXON_FILTER_CTL2HOST_MSK;
else
*filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
} }
*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
*filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
else
*filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
}
/* We avoid iwl_commit_rxon here to commit the new filter flags
* since mac80211 will call ieee80211_hw_config immediately.
* (mc_list is not supported at this time). Otherwise, we need to
* queue a background iwl_commit_rxon work.
*/
*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
} }
...@@ -7715,7 +7724,6 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) ...@@ -7715,7 +7724,6 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
......
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