aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ar9170/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-17 10:16:53 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-20 11:35:58 -0400
commit3ac64beecd27400d12cc7afb4108eef26c499f6a (patch)
treeda0220085f68e30fe61ba9b8833dc6311d6dc25e /drivers/net/wireless/ath/ar9170/main.c
parentea416a793d2b611f22b42ba094fd2e5bd30fff43 (diff)
mac80211: allow configure_filter callback to sleep
Over time, a whole bunch of drivers have come up with their own scheme to delay the configure_filter operation to a workqueue. To be able to simplify things, allow configure_filter to sleep, and add a new prepare_multicast callback that drivers that need the multicast address list implement. This new callback must be atomic, but most drivers either don't care or just calculate a hash which can be done atomically and then uploaded to the hardware non-atomically. A cursory look suggests that at76c50x-usb, ar9170, mwl8k (which is actually very broken now), rt2x00, wl1251, wl1271 and zd1211 should make use of this new capability. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ar9170/main.c')
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index ea8c9419336d..6a9462e4fd87 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -2100,10 +2100,29 @@ unlock:
2100 mutex_unlock(&ar->mutex); 2100 mutex_unlock(&ar->mutex);
2101} 2101}
2102 2102
2103static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
2104 struct dev_addr_list *mclist)
2105{
2106 u64 mchash;
2107 int i;
2108
2109 /* always get broadcast frames */
2110 mchash = 1ULL << (0xff >> 2);
2111
2112 for (i = 0; i < mc_count; i++) {
2113 if (WARN_ON(!mclist))
2114 break;
2115 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2116 mclist = mclist->next;
2117 }
2118
2119 return mchash;
2120}
2121
2103static void ar9170_op_configure_filter(struct ieee80211_hw *hw, 2122static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2104 unsigned int changed_flags, 2123 unsigned int changed_flags,
2105 unsigned int *new_flags, 2124 unsigned int *new_flags,
2106 int mc_count, struct dev_mc_list *mclist) 2125 u64 multicast)
2107{ 2126{
2108 struct ar9170 *ar = hw->priv; 2127 struct ar9170 *ar = hw->priv;
2109 2128
@@ -2116,24 +2135,11 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2116 * then checking the error flags, later. 2135 * then checking the error flags, later.
2117 */ 2136 */
2118 2137
2119 if (changed_flags & FIF_ALLMULTI) { 2138 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
2120 if (*new_flags & FIF_ALLMULTI) { 2139 multicast = ~0ULL;
2121 ar->want_mc_hash = ~0ULL;
2122 } else {
2123 u64 mchash;
2124 int i;
2125
2126 /* always get broadcast frames */
2127 mchash = 1ULL << (0xff >> 2);
2128 2140
2129 for (i = 0; i < mc_count; i++) { 2141 if (multicast != ar->want_mc_hash) {
2130 if (WARN_ON(!mclist)) 2142 ar->want_mc_hash = multicast;
2131 break;
2132 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2133 mclist = mclist->next;
2134 }
2135 ar->want_mc_hash = mchash;
2136 }
2137 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed); 2143 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
2138 } 2144 }
2139 2145
@@ -2543,6 +2549,7 @@ static const struct ieee80211_ops ar9170_ops = {
2543 .add_interface = ar9170_op_add_interface, 2549 .add_interface = ar9170_op_add_interface,
2544 .remove_interface = ar9170_op_remove_interface, 2550 .remove_interface = ar9170_op_remove_interface,
2545 .config = ar9170_op_config, 2551 .config = ar9170_op_config,
2552 .prepare_multicast = ar9170_op_prepare_multicast,
2546 .configure_filter = ar9170_op_configure_filter, 2553 .configure_filter = ar9170_op_configure_filter,
2547 .conf_tx = ar9170_conf_tx, 2554 .conf_tx = ar9170_conf_tx,
2548 .bss_info_changed = ar9170_op_bss_info_changed, 2555 .bss_info_changed = ar9170_op_bss_info_changed,