diff options
author | Christian Lamparter <chunkeey@web.de> | 2009-08-19 06:43:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-20 11:36:06 -0400 |
commit | eeef41854deae30ea304544f18684df70ae3f87b (patch) | |
tree | c6824c4c75d0d8c50ac43df17d29ca3a33fcd737 | |
parent | 5791ce18aa660df7d1dafebf6bd89d5aa05bd742 (diff) |
ar9170: refactor configure_filter
Thanks to "mac80211: allow configure_filter callback to sleep",
we no longer have to defer the work to the workqueue.
Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ar9170/ar9170.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/mac.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 75 |
3 files changed, 27 insertions, 84 deletions
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 95f8256c2026..ce407248d7d8 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -185,10 +185,8 @@ struct ar9170 { | |||
185 | bool disable_offload; | 185 | bool disable_offload; |
186 | 186 | ||
187 | /* filter settings */ | 187 | /* filter settings */ |
188 | struct work_struct filter_config_work; | 188 | u64 cur_mc_hash; |
189 | u64 cur_mc_hash, want_mc_hash; | 189 | u32 cur_filter; |
190 | u32 cur_filter, want_filter; | ||
191 | unsigned long filter_changed; | ||
192 | unsigned int filter_state; | 190 | unsigned int filter_state; |
193 | bool sniffer_enabled; | 191 | bool sniffer_enabled; |
194 | 192 | ||
@@ -261,10 +259,6 @@ struct ar9170_tx_info { | |||
261 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) | 259 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) |
262 | #define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) | 260 | #define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) |
263 | 261 | ||
264 | #define AR9170_FILTER_CHANGED_MODE BIT(0) | ||
265 | #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) | ||
266 | #define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2) | ||
267 | |||
268 | /* exported interface */ | 262 | /* exported interface */ |
269 | void *ar9170_alloc(size_t priv_size); | 263 | void *ar9170_alloc(size_t priv_size); |
270 | int ar9170_register(struct ar9170 *ar, struct device *pdev); | 264 | int ar9170_register(struct ar9170 *ar, struct device *pdev); |
@@ -278,8 +272,8 @@ int ar9170_nag_limiter(struct ar9170 *ar); | |||
278 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 272 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
279 | int ar9170_init_mac(struct ar9170 *ar); | 273 | int ar9170_init_mac(struct ar9170 *ar); |
280 | int ar9170_set_qos(struct ar9170 *ar); | 274 | int ar9170_set_qos(struct ar9170 *ar); |
281 | int ar9170_update_multicast(struct ar9170 *ar); | 275 | int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); |
282 | int ar9170_update_frame_filter(struct ar9170 *ar); | 276 | int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter); |
283 | int ar9170_set_operating_mode(struct ar9170 *ar); | 277 | int ar9170_set_operating_mode(struct ar9170 *ar); |
284 | int ar9170_set_beacon_timers(struct ar9170 *ar); | 278 | int ar9170_set_beacon_timers(struct ar9170 *ar); |
285 | int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); | 279 | int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); |
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c index d9f1f46de183..60049366e863 100644 --- a/drivers/net/wireless/ath/ar9170/mac.c +++ b/drivers/net/wireless/ath/ar9170/mac.c | |||
@@ -238,39 +238,31 @@ static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac) | |||
238 | return ar9170_regwrite_result(); | 238 | return ar9170_regwrite_result(); |
239 | } | 239 | } |
240 | 240 | ||
241 | int ar9170_update_multicast(struct ar9170 *ar) | 241 | int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash) |
242 | { | 242 | { |
243 | int err; | 243 | int err; |
244 | 244 | ||
245 | ar9170_regwrite_begin(ar); | 245 | ar9170_regwrite_begin(ar); |
246 | ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, | 246 | ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32); |
247 | ar->want_mc_hash >> 32); | 247 | ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash); |
248 | ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, | ||
249 | ar->want_mc_hash); | ||
250 | |||
251 | ar9170_regwrite_finish(); | 248 | ar9170_regwrite_finish(); |
252 | err = ar9170_regwrite_result(); | 249 | err = ar9170_regwrite_result(); |
253 | |||
254 | if (err) | 250 | if (err) |
255 | return err; | 251 | return err; |
256 | 252 | ||
257 | ar->cur_mc_hash = ar->want_mc_hash; | 253 | ar->cur_mc_hash = mc_hash; |
258 | |||
259 | return 0; | 254 | return 0; |
260 | } | 255 | } |
261 | 256 | ||
262 | int ar9170_update_frame_filter(struct ar9170 *ar) | 257 | int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter) |
263 | { | 258 | { |
264 | int err; | 259 | int err; |
265 | 260 | ||
266 | err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, | 261 | err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter); |
267 | ar->want_filter); | ||
268 | |||
269 | if (err) | 262 | if (err) |
270 | return err; | 263 | return err; |
271 | 264 | ||
272 | ar->cur_filter = ar->want_filter; | 265 | ar->cur_filter = filter; |
273 | |||
274 | return 0; | 266 | return 0; |
275 | } | 267 | } |
276 | 268 | ||
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index d30f33d4d41b..658b32312caf 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -1232,8 +1232,6 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
1232 | 1232 | ||
1233 | mutex_lock(&ar->mutex); | 1233 | mutex_lock(&ar->mutex); |
1234 | 1234 | ||
1235 | ar->filter_changed = 0; | ||
1236 | |||
1237 | /* reinitialize queues statistics */ | 1235 | /* reinitialize queues statistics */ |
1238 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); | 1236 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); |
1239 | for (i = 0; i < __AR9170_NUM_TXQ; i++) | 1237 | for (i = 0; i < __AR9170_NUM_TXQ; i++) |
@@ -1296,7 +1294,6 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) | |||
1296 | #ifdef CONFIG_AR9170_LEDS | 1294 | #ifdef CONFIG_AR9170_LEDS |
1297 | cancel_delayed_work_sync(&ar->led_work); | 1295 | cancel_delayed_work_sync(&ar->led_work); |
1298 | #endif | 1296 | #endif |
1299 | cancel_work_sync(&ar->filter_config_work); | ||
1300 | cancel_work_sync(&ar->beacon_work); | 1297 | cancel_work_sync(&ar->beacon_work); |
1301 | 1298 | ||
1302 | mutex_lock(&ar->mutex); | 1299 | mutex_lock(&ar->mutex); |
@@ -1973,8 +1970,7 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw, | |||
1973 | } | 1970 | } |
1974 | 1971 | ||
1975 | ar->cur_filter = 0; | 1972 | ar->cur_filter = 0; |
1976 | ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS; | 1973 | err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS); |
1977 | err = ar9170_update_frame_filter(ar); | ||
1978 | if (err) | 1974 | if (err) |
1979 | goto unlock; | 1975 | goto unlock; |
1980 | 1976 | ||
@@ -1992,8 +1988,7 @@ static void ar9170_op_remove_interface(struct ieee80211_hw *hw, | |||
1992 | 1988 | ||
1993 | mutex_lock(&ar->mutex); | 1989 | mutex_lock(&ar->mutex); |
1994 | ar->vif = NULL; | 1990 | ar->vif = NULL; |
1995 | ar->want_filter = 0; | 1991 | ar9170_update_frame_filter(ar, 0); |
1996 | ar9170_update_frame_filter(ar); | ||
1997 | ar9170_set_beacon_timers(ar); | 1992 | ar9170_set_beacon_timers(ar); |
1998 | dev_kfree_skb(ar->beacon); | 1993 | dev_kfree_skb(ar->beacon); |
1999 | ar->beacon = NULL; | 1994 | ar->beacon = NULL; |
@@ -2065,41 +2060,6 @@ out: | |||
2065 | return err; | 2060 | return err; |
2066 | } | 2061 | } |
2067 | 2062 | ||
2068 | static void ar9170_set_filters(struct work_struct *work) | ||
2069 | { | ||
2070 | struct ar9170 *ar = container_of(work, struct ar9170, | ||
2071 | filter_config_work); | ||
2072 | int err; | ||
2073 | |||
2074 | if (unlikely(!IS_STARTED(ar))) | ||
2075 | return ; | ||
2076 | |||
2077 | mutex_lock(&ar->mutex); | ||
2078 | if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE, | ||
2079 | &ar->filter_changed)) { | ||
2080 | err = ar9170_set_operating_mode(ar); | ||
2081 | if (err) | ||
2082 | goto unlock; | ||
2083 | } | ||
2084 | |||
2085 | if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST, | ||
2086 | &ar->filter_changed)) { | ||
2087 | err = ar9170_update_multicast(ar); | ||
2088 | if (err) | ||
2089 | goto unlock; | ||
2090 | } | ||
2091 | |||
2092 | if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, | ||
2093 | &ar->filter_changed)) { | ||
2094 | err = ar9170_update_frame_filter(ar); | ||
2095 | if (err) | ||
2096 | goto unlock; | ||
2097 | } | ||
2098 | |||
2099 | unlock: | ||
2100 | mutex_unlock(&ar->mutex); | ||
2101 | } | ||
2102 | |||
2103 | static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count, | 2063 | static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count, |
2104 | struct dev_addr_list *mclist) | 2064 | struct dev_addr_list *mclist) |
2105 | { | 2065 | { |
@@ -2126,6 +2086,11 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
2126 | { | 2086 | { |
2127 | struct ar9170 *ar = hw->priv; | 2087 | struct ar9170 *ar = hw->priv; |
2128 | 2088 | ||
2089 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
2090 | return ; | ||
2091 | |||
2092 | mutex_lock(&ar->mutex); | ||
2093 | |||
2129 | /* mask supported flags */ | 2094 | /* mask supported flags */ |
2130 | *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | | 2095 | *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | |
2131 | FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL; | 2096 | FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL; |
@@ -2136,12 +2101,10 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
2136 | */ | 2101 | */ |
2137 | 2102 | ||
2138 | if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) | 2103 | if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) |
2139 | multicast = ~0ULL; | 2104 | multicast = ~0ULL; |
2140 | 2105 | ||
2141 | if (multicast != ar->want_mc_hash) { | 2106 | if (multicast != ar->cur_mc_hash) |
2142 | ar->want_mc_hash = multicast; | 2107 | ar9170_update_multicast(ar, multicast); |
2143 | set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed); | ||
2144 | } | ||
2145 | 2108 | ||
2146 | if (changed_flags & FIF_CONTROL) { | 2109 | if (changed_flags & FIF_CONTROL) { |
2147 | u32 filter = AR9170_MAC_REG_FTF_PSPOLL | | 2110 | u32 filter = AR9170_MAC_REG_FTF_PSPOLL | |
@@ -2152,24 +2115,22 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
2152 | AR9170_MAC_REG_FTF_CFE_ACK; | 2115 | AR9170_MAC_REG_FTF_CFE_ACK; |
2153 | 2116 | ||
2154 | if (*new_flags & FIF_CONTROL) | 2117 | if (*new_flags & FIF_CONTROL) |
2155 | ar->want_filter = ar->cur_filter | filter; | 2118 | filter |= ar->cur_filter; |
2156 | else | 2119 | else |
2157 | ar->want_filter = ar->cur_filter & ~filter; | 2120 | filter &= (~ar->cur_filter); |
2158 | 2121 | ||
2159 | set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, | 2122 | ar9170_update_frame_filter(ar, filter); |
2160 | &ar->filter_changed); | ||
2161 | } | 2123 | } |
2162 | 2124 | ||
2163 | if (changed_flags & FIF_PROMISC_IN_BSS) { | 2125 | if (changed_flags & FIF_PROMISC_IN_BSS) { |
2164 | ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; | 2126 | ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; |
2165 | set_bit(AR9170_FILTER_CHANGED_MODE, | 2127 | ar9170_set_operating_mode(ar); |
2166 | &ar->filter_changed); | ||
2167 | } | 2128 | } |
2168 | 2129 | ||
2169 | if (likely(IS_STARTED(ar))) | 2130 | mutex_unlock(&ar->mutex); |
2170 | ieee80211_queue_work(ar->hw, &ar->filter_config_work); | ||
2171 | } | 2131 | } |
2172 | 2132 | ||
2133 | |||
2173 | static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | 2134 | static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, |
2174 | struct ieee80211_vif *vif, | 2135 | struct ieee80211_vif *vif, |
2175 | struct ieee80211_bss_conf *bss_conf, | 2136 | struct ieee80211_bss_conf *bss_conf, |
@@ -2423,9 +2384,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, | |||
2423 | default: | 2384 | default: |
2424 | break; | 2385 | break; |
2425 | } | 2386 | } |
2426 | |||
2427 | if (IS_STARTED(ar) && ar->filter_changed) | ||
2428 | ieee80211_queue_work(ar->hw, &ar->filter_config_work); | ||
2429 | } | 2387 | } |
2430 | 2388 | ||
2431 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 2389 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
@@ -2596,7 +2554,6 @@ void *ar9170_alloc(size_t priv_size) | |||
2596 | skb_queue_head_init(&ar->tx_pending[i]); | 2554 | skb_queue_head_init(&ar->tx_pending[i]); |
2597 | } | 2555 | } |
2598 | ar9170_rx_reset_rx_mpdu(ar); | 2556 | ar9170_rx_reset_rx_mpdu(ar); |
2599 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); | ||
2600 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | 2557 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); |
2601 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); | 2558 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); |
2602 | INIT_LIST_HEAD(&ar->tx_ampdu_list); | 2559 | INIT_LIST_HEAD(&ar->tx_ampdu_list); |