From 447ced07d04525218ae586cd70b759b48bcb1fc8 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Thu, 22 Oct 2009 20:19:50 +0200 Subject: [PATCH] mwl8k: implement FIF_ALLMULTI Signed-off-by: Lennert Buytenhek Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 39 ++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 77985e9a13a..cc58ecba211 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1543,16 +1543,14 @@ struct mwl8k_cmd_mac_multicast_adr { #define MWL8K_ENABLE_RX_BROADCAST 0x0008 static struct mwl8k_cmd_pkt * -__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, +__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti, int mc_count, struct dev_addr_list *mclist) { struct mwl8k_priv *priv = hw->priv; struct mwl8k_cmd_mac_multicast_adr *cmd; - int allmulti; int size; - allmulti = 0; - if (mc_count > priv->num_mcaddrs) { + if (allmulti || mc_count > priv->num_mcaddrs) { allmulti = 1; mc_count = 0; } @@ -2680,7 +2678,14 @@ static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw, { struct mwl8k_cmd_pkt *cmd; - cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist); + /* + * Synthesize and return a command packet that programs the + * hardware multicast address filter. At this point we don't + * know whether FIF_ALLMULTI is being requested, but if it is, + * we'll end up throwing this packet away and creating a new + * one in mwl8k_configure_filter(). + */ + cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_count, mclist); return (unsigned long)cmd; } @@ -2691,10 +2696,10 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw, u64 multicast) { struct mwl8k_priv *priv = hw->priv; - struct mwl8k_cmd_pkt *multicast_adr_cmd; + struct mwl8k_cmd_pkt *cmd; /* Clear unsupported feature flags */ - *total_flags &= FIF_BCN_PRBRESP_PROMISC; + *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; if (mwl8k_fw_lock(hw)) return; @@ -2713,10 +2718,22 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw, } } - multicast_adr_cmd = (void *)(unsigned long)multicast; - if (multicast_adr_cmd != NULL) { - mwl8k_post_cmd(hw, multicast_adr_cmd); - kfree(multicast_adr_cmd); + cmd = (void *)(unsigned long)multicast; + + /* + * If FIF_ALLMULTI is being requested, throw away the command + * packet that ->prepare_multicast() built and replace it with + * a command packet that enables reception of all multicast + * packets. + */ + if (*total_flags & FIF_ALLMULTI) { + kfree(cmd); + cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, 0, NULL); + } + + if (cmd != NULL) { + mwl8k_post_cmd(hw, cmd); + kfree(cmd); } mwl8k_fw_unlock(hw); -- 2.41.0