aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2009-08-19 06:43:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-20 11:36:06 -0400
commiteeef41854deae30ea304544f18684df70ae3f87b (patch)
treec6824c4c75d0d8c50ac43df17d29ca3a33fcd737 /drivers/net/wireless/ath
parent5791ce18aa660df7d1dafebf6bd89d5aa05bd742 (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>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h14
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c22
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c75
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 */
269void *ar9170_alloc(size_t priv_size); 263void *ar9170_alloc(size_t priv_size);
270int ar9170_register(struct ar9170 *ar, struct device *pdev); 264int ar9170_register(struct ar9170 *ar, struct device *pdev);
@@ -278,8 +272,8 @@ int ar9170_nag_limiter(struct ar9170 *ar);
278int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); 272int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
279int ar9170_init_mac(struct ar9170 *ar); 273int ar9170_init_mac(struct ar9170 *ar);
280int ar9170_set_qos(struct ar9170 *ar); 274int ar9170_set_qos(struct ar9170 *ar);
281int ar9170_update_multicast(struct ar9170 *ar); 275int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
282int ar9170_update_frame_filter(struct ar9170 *ar); 276int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter);
283int ar9170_set_operating_mode(struct ar9170 *ar); 277int ar9170_set_operating_mode(struct ar9170 *ar);
284int ar9170_set_beacon_timers(struct ar9170 *ar); 278int ar9170_set_beacon_timers(struct ar9170 *ar);
285int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); 279int 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
241int ar9170_update_multicast(struct ar9170 *ar) 241int 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
262int ar9170_update_frame_filter(struct ar9170 *ar) 257int 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
2068static 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
2099unlock:
2100 mutex_unlock(&ar->mutex);
2101}
2102
2103static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count, 2063static 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
2173static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, 2134static 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
2431static int ar9170_get_stats(struct ieee80211_hw *hw, 2389static 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);