diff options
author | Zhu, Yi <yi.zhu@intel.com> | 2008-11-12 16:14:09 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-25 16:41:19 -0500 |
commit | 352bc8de19a7e5e065d422825e226e8e80cd6576 (patch) | |
tree | 2f7a1d2184d8a04ee9dafdd97b24262225320192 /drivers | |
parent | c3056065400aeb437390e1a86b85f9c32fb1c1df (diff) |
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: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 65 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 62 |
4 files changed, 70 insertions, 59 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 7187925bd0d5..2a924c10ff93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -886,7 +886,6 @@ struct iwl3945_priv { | |||
886 | struct work_struct report_work; | 886 | struct work_struct report_work; |
887 | struct work_struct request_scan; | 887 | struct work_struct request_scan; |
888 | struct work_struct beacon_update; | 888 | struct work_struct beacon_update; |
889 | struct work_struct set_monitor; | ||
890 | 889 | ||
891 | struct tasklet_struct irq_tasklet; | 890 | struct tasklet_struct irq_tasklet; |
892 | 891 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e971a893eec8..c8ce84a1eef4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2224,27 +2224,6 @@ static void iwl_bg_rf_kill(struct work_struct *work) | |||
2224 | iwl_rfkill_set_hw_state(priv); | 2224 | iwl_rfkill_set_hw_state(priv); |
2225 | } | 2225 | } |
2226 | 2226 | ||
2227 | static void iwl_bg_set_monitor(struct work_struct *work) | ||
2228 | { | ||
2229 | struct iwl_priv *priv = container_of(work, | ||
2230 | struct iwl_priv, set_monitor); | ||
2231 | int ret; | ||
2232 | |||
2233 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); | ||
2234 | |||
2235 | mutex_lock(&priv->mutex); | ||
2236 | |||
2237 | ret = iwl_set_mode(priv, NL80211_IFTYPE_MONITOR); | ||
2238 | if (ret) { | ||
2239 | if (ret == -EAGAIN) | ||
2240 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | ||
2241 | else | ||
2242 | IWL_ERROR("iwl_set_mode() failed ret = %d\n", ret); | ||
2243 | } | ||
2244 | |||
2245 | mutex_unlock(&priv->mutex); | ||
2246 | } | ||
2247 | |||
2248 | static void iwl_bg_run_time_calib_work(struct work_struct *work) | 2227 | static void iwl_bg_run_time_calib_work(struct work_struct *work) |
2249 | { | 2228 | { |
2250 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 2229 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
@@ -2890,16 +2869,43 @@ static void iwl_configure_filter(struct ieee80211_hw *hw, | |||
2890 | int mc_count, struct dev_addr_list *mc_list) | 2869 | int mc_count, struct dev_addr_list *mc_list) |
2891 | { | 2870 | { |
2892 | struct iwl_priv *priv = hw->priv; | 2871 | struct iwl_priv *priv = hw->priv; |
2872 | __le32 *filter_flags = &priv->staging_rxon.filter_flags; | ||
2873 | |||
2874 | IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", | ||
2875 | changed_flags, *total_flags); | ||
2893 | 2876 | ||
2894 | if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { | 2877 | if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { |
2895 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", | 2878 | if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) |
2896 | NL80211_IFTYPE_MONITOR, | 2879 | *filter_flags |= RXON_FILTER_PROMISC_MSK; |
2897 | changed_flags, *total_flags); | 2880 | else |
2898 | /* queue work 'cuz mac80211 is holding a lock which | 2881 | *filter_flags &= ~RXON_FILTER_PROMISC_MSK; |
2899 | * prevents us from issuing (synchronous) f/w cmds */ | 2882 | } |
2900 | queue_work(priv->workqueue, &priv->set_monitor); | 2883 | if (changed_flags & FIF_ALLMULTI) { |
2884 | if (*total_flags & FIF_ALLMULTI) | ||
2885 | *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK; | ||
2886 | else | ||
2887 | *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK; | ||
2888 | } | ||
2889 | if (changed_flags & FIF_CONTROL) { | ||
2890 | if (*total_flags & FIF_CONTROL) | ||
2891 | *filter_flags |= RXON_FILTER_CTL2HOST_MSK; | ||
2892 | else | ||
2893 | *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK; | ||
2894 | } | ||
2895 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { | ||
2896 | if (*total_flags & FIF_BCN_PRBRESP_PROMISC) | ||
2897 | *filter_flags |= RXON_FILTER_BCON_AWARE_MSK; | ||
2898 | else | ||
2899 | *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK; | ||
2901 | } | 2900 | } |
2902 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | | 2901 | |
2902 | /* We avoid iwl_commit_rxon here to commit the new filter flags | ||
2903 | * since mac80211 will call ieee80211_hw_config immediately. | ||
2904 | * (mc_list is not supported at this time). Otherwise, we need to | ||
2905 | * queue a background iwl_commit_rxon work. | ||
2906 | */ | ||
2907 | |||
2908 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
2903 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 2909 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
2904 | } | 2910 | } |
2905 | 2911 | ||
@@ -3796,7 +3802,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3796 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | 3802 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); |
3797 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | 3803 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); |
3798 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 3804 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
3799 | INIT_WORK(&priv->set_monitor, iwl_bg_set_monitor); | ||
3800 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | 3805 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
3801 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 3806 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
3802 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | 3807 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0e97d6a13225..1b305d8d0cc5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -985,7 +985,6 @@ struct iwl_priv { | |||
985 | struct work_struct report_work; | 985 | struct work_struct report_work; |
986 | struct work_struct request_scan; | 986 | struct work_struct request_scan; |
987 | struct work_struct beacon_update; | 987 | struct work_struct beacon_update; |
988 | struct work_struct set_monitor; | ||
989 | 988 | ||
990 | struct tasklet_struct irq_tasklet; | 989 | struct tasklet_struct irq_tasklet; |
991 | 990 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index baa0d6c59d20..beba6e3cfbfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -5996,24 +5996,6 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) | |||
5996 | iwl3945_rfkill_set_hw_state(priv); | 5996 | iwl3945_rfkill_set_hw_state(priv); |
5997 | } | 5997 | } |
5998 | 5998 | ||
5999 | static void iwl3945_bg_set_monitor(struct work_struct *work) | ||
6000 | { | ||
6001 | struct iwl3945_priv *priv = container_of(work, | ||
6002 | struct iwl3945_priv, set_monitor); | ||
6003 | |||
6004 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); | ||
6005 | |||
6006 | mutex_lock(&priv->mutex); | ||
6007 | |||
6008 | if (!iwl3945_is_ready(priv)) | ||
6009 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | ||
6010 | else | ||
6011 | if (iwl3945_set_mode(priv, NL80211_IFTYPE_MONITOR) != 0) | ||
6012 | IWL_ERROR("iwl3945_set_mode() failed\n"); | ||
6013 | |||
6014 | mutex_unlock(&priv->mutex); | ||
6015 | } | ||
6016 | |||
6017 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 5999 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
6018 | 6000 | ||
6019 | static void iwl3945_bg_scan_check(struct work_struct *data) | 6001 | static void iwl3945_bg_scan_check(struct work_struct *data) |
@@ -6830,16 +6812,43 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, | |||
6830 | int mc_count, struct dev_addr_list *mc_list) | 6812 | int mc_count, struct dev_addr_list *mc_list) |
6831 | { | 6813 | { |
6832 | struct iwl3945_priv *priv = hw->priv; | 6814 | struct iwl3945_priv *priv = hw->priv; |
6815 | __le32 *filter_flags = &priv->staging_rxon.filter_flags; | ||
6833 | 6816 | ||
6834 | if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { | 6817 | IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", |
6835 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", | 6818 | changed_flags, *total_flags); |
6836 | NL80211_IFTYPE_MONITOR, | 6819 | |
6837 | changed_flags, *total_flags); | 6820 | if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { |
6838 | /* queue work 'cuz mac80211 is holding a lock which | 6821 | if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) |
6839 | * prevents us from issuing (synchronous) f/w cmds */ | 6822 | *filter_flags |= RXON_FILTER_PROMISC_MSK; |
6840 | queue_work(priv->workqueue, &priv->set_monitor); | 6823 | else |
6824 | *filter_flags &= ~RXON_FILTER_PROMISC_MSK; | ||
6825 | } | ||
6826 | if (changed_flags & FIF_ALLMULTI) { | ||
6827 | if (*total_flags & FIF_ALLMULTI) | ||
6828 | *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK; | ||
6829 | else | ||
6830 | *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK; | ||
6831 | } | ||
6832 | if (changed_flags & FIF_CONTROL) { | ||
6833 | if (*total_flags & FIF_CONTROL) | ||
6834 | *filter_flags |= RXON_FILTER_CTL2HOST_MSK; | ||
6835 | else | ||
6836 | *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK; | ||
6841 | } | 6837 | } |
6842 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | | 6838 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { |
6839 | if (*total_flags & FIF_BCN_PRBRESP_PROMISC) | ||
6840 | *filter_flags |= RXON_FILTER_BCON_AWARE_MSK; | ||
6841 | else | ||
6842 | *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK; | ||
6843 | } | ||
6844 | |||
6845 | /* We avoid iwl_commit_rxon here to commit the new filter flags | ||
6846 | * since mac80211 will call ieee80211_hw_config immediately. | ||
6847 | * (mc_list is not supported at this time). Otherwise, we need to | ||
6848 | * queue a background iwl_commit_rxon work. | ||
6849 | */ | ||
6850 | |||
6851 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
6843 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 6852 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
6844 | } | 6853 | } |
6845 | 6854 | ||
@@ -7715,7 +7724,6 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) | |||
7715 | INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); | 7724 | INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); |
7716 | INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); | 7725 | INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); |
7717 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 7726 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
7718 | INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor); | ||
7719 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 7727 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
7720 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 7728 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
7721 | INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); | 7729 | INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); |