aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2009-10-22 14:19:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-11-04 18:44:44 -0500
commit447ced07d04525218ae586cd70b759b48bcb1fc8 (patch)
tree761f8bfde50e7582b01cc7548319d0b4d3012227 /drivers/net/wireless/mwl8k.c
parent3779752d764b86077375510b1fd13d8fb2c7c3a5 (diff)
mwl8k: implement FIF_ALLMULTI
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 77985e9a13a2..cc58ecba211a 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1543,16 +1543,14 @@ struct mwl8k_cmd_mac_multicast_adr {
1543#define MWL8K_ENABLE_RX_BROADCAST 0x0008 1543#define MWL8K_ENABLE_RX_BROADCAST 0x0008
1544 1544
1545static struct mwl8k_cmd_pkt * 1545static struct mwl8k_cmd_pkt *
1546__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, 1546__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
1547 int mc_count, struct dev_addr_list *mclist) 1547 int mc_count, struct dev_addr_list *mclist)
1548{ 1548{
1549 struct mwl8k_priv *priv = hw->priv; 1549 struct mwl8k_priv *priv = hw->priv;
1550 struct mwl8k_cmd_mac_multicast_adr *cmd; 1550 struct mwl8k_cmd_mac_multicast_adr *cmd;
1551 int allmulti;
1552 int size; 1551 int size;
1553 1552
1554 allmulti = 0; 1553 if (allmulti || mc_count > priv->num_mcaddrs) {
1555 if (mc_count > priv->num_mcaddrs) {
1556 allmulti = 1; 1554 allmulti = 1;
1557 mc_count = 0; 1555 mc_count = 0;
1558 } 1556 }
@@ -2680,7 +2678,14 @@ static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
2680{ 2678{
2681 struct mwl8k_cmd_pkt *cmd; 2679 struct mwl8k_cmd_pkt *cmd;
2682 2680
2683 cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist); 2681 /*
2682 * Synthesize and return a command packet that programs the
2683 * hardware multicast address filter. At this point we don't
2684 * know whether FIF_ALLMULTI is being requested, but if it is,
2685 * we'll end up throwing this packet away and creating a new
2686 * one in mwl8k_configure_filter().
2687 */
2688 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_count, mclist);
2684 2689
2685 return (unsigned long)cmd; 2690 return (unsigned long)cmd;
2686} 2691}
@@ -2691,10 +2696,10 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
2691 u64 multicast) 2696 u64 multicast)
2692{ 2697{
2693 struct mwl8k_priv *priv = hw->priv; 2698 struct mwl8k_priv *priv = hw->priv;
2694 struct mwl8k_cmd_pkt *multicast_adr_cmd; 2699 struct mwl8k_cmd_pkt *cmd;
2695 2700
2696 /* Clear unsupported feature flags */ 2701 /* Clear unsupported feature flags */
2697 *total_flags &= FIF_BCN_PRBRESP_PROMISC; 2702 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
2698 2703
2699 if (mwl8k_fw_lock(hw)) 2704 if (mwl8k_fw_lock(hw))
2700 return; 2705 return;
@@ -2713,10 +2718,22 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
2713 } 2718 }
2714 } 2719 }
2715 2720
2716 multicast_adr_cmd = (void *)(unsigned long)multicast; 2721 cmd = (void *)(unsigned long)multicast;
2717 if (multicast_adr_cmd != NULL) { 2722
2718 mwl8k_post_cmd(hw, multicast_adr_cmd); 2723 /*
2719 kfree(multicast_adr_cmd); 2724 * If FIF_ALLMULTI is being requested, throw away the command
2725 * packet that ->prepare_multicast() built and replace it with
2726 * a command packet that enables reception of all multicast
2727 * packets.
2728 */
2729 if (*total_flags & FIF_ALLMULTI) {
2730 kfree(cmd);
2731 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, 0, NULL);
2732 }
2733
2734 if (cmd != NULL) {
2735 mwl8k_post_cmd(hw, cmd);
2736 kfree(cmd);
2720 } 2737 }
2721 2738
2722 mwl8k_fw_unlock(hw); 2739 mwl8k_fw_unlock(hw);