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>
This commit is contained in:

committed by
John W. Linville

parent
ea416a793d
commit
3ac64beecd
@@ -366,15 +366,35 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw,
|
||||
int mc_count, struct dev_addr_list *mclist)
|
||||
{
|
||||
struct lbtf_private *priv = hw->priv;
|
||||
int i;
|
||||
|
||||
if (!mc_count || mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE)
|
||||
return mc_count;
|
||||
|
||||
priv->nr_of_multicastmacaddr = mc_count;
|
||||
for (i = 0; i < mc_count; i++) {
|
||||
if (!mclist)
|
||||
break;
|
||||
memcpy(&priv->multicastlist[i], mclist->da_addr,
|
||||
ETH_ALEN);
|
||||
mclist = mclist->next;
|
||||
}
|
||||
|
||||
return mc_count;
|
||||
}
|
||||
|
||||
#define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)
|
||||
static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
|
||||
unsigned int changed_flags,
|
||||
unsigned int *new_flags,
|
||||
int mc_count, struct dev_mc_list *mclist)
|
||||
u64 multicast)
|
||||
{
|
||||
struct lbtf_private *priv = hw->priv;
|
||||
int old_mac_control = priv->mac_control;
|
||||
int i;
|
||||
changed_flags &= SUPPORTED_FIF_FLAGS;
|
||||
*new_flags &= SUPPORTED_FIF_FLAGS;
|
||||
|
||||
@@ -386,20 +406,12 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
|
||||
else
|
||||
priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
|
||||
if (*new_flags & (FIF_ALLMULTI) ||
|
||||
mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) {
|
||||
multicast > MRVDRV_MAX_MULTICAST_LIST_SIZE) {
|
||||
priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
|
||||
priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;
|
||||
} else if (mc_count) {
|
||||
} else if (multicast) {
|
||||
priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
|
||||
priv->mac_control &= ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
|
||||
priv->nr_of_multicastmacaddr = mc_count;
|
||||
for (i = 0; i < mc_count; i++) {
|
||||
if (!mclist)
|
||||
break;
|
||||
memcpy(&priv->multicastlist[i], mclist->da_addr,
|
||||
ETH_ALEN);
|
||||
mclist = mclist->next;
|
||||
}
|
||||
lbtf_cmd_set_mac_multicast_addr(priv);
|
||||
} else {
|
||||
priv->mac_control &= ~(CMD_ACT_MAC_MULTICAST_ENABLE |
|
||||
@@ -461,6 +473,7 @@ static const struct ieee80211_ops lbtf_ops = {
|
||||
.add_interface = lbtf_op_add_interface,
|
||||
.remove_interface = lbtf_op_remove_interface,
|
||||
.config = lbtf_op_config,
|
||||
.prepare_multicast = lbtf_op_prepare_multicast,
|
||||
.configure_filter = lbtf_op_configure_filter,
|
||||
.bss_info_changed = lbtf_op_bss_info_changed,
|
||||
};
|
||||
|
Reference in New Issue
Block a user