aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/fwio.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2011-04-24 11:22:59 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-26 15:50:30 -0400
commitbe8d98eab81d1f6445461a1631513f7091805e53 (patch)
treef543f18ff00ca8890b3d99afc733071be898c74a /drivers/net/wireless/p54/fwio.c
parent04ad1fb2640a4f23e99ccb705c179d64abac03f2 (diff)
p54: implement multicast filter
"For best CPU usage and power consumption, having as few frames as possible percolate through the stack is desirable. Hence, the hardware should filter as much as possible." Note: Not all firmwares include the multicast filter feature and the stack does not filter them either. The ARP filter on the other hand was dropped from the patch since it does not work correctly: Quote from: Max Filippov <jcmvbkbc@gmail.com> <http://www.spinics.net/lists/linux-wireless/msg67466.html> "In the ARP case, when there's no other traffic on p54spi, all ARP requests are dropped. But if there's some egress traffic from p54spi, filter seems to work correctly: only ARP requests that match filter pass through. In the multicast case filter seems to work correctly, but it treats broadcast as subject to that filtering too. By default only 01:00:5e:00:00:01 gets into priv->mc_maclist, so we miss all broadcasts. These two filters seem to interfere: - if we set ARP filter and multicast filter without bc => we miss all ARPs if there's no egress traffic; - if we set ARP filter and multicast filter with bc or don't set mc filter at all => we get all ARPs. This effect does not depend on filter setup order." Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Tested-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/fwio.c')
-rw-r--r--drivers/net/wireless/p54/fwio.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index 2fab7d20ffc2..b6a061cbbdec 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -727,3 +727,34 @@ int p54_fetch_statistics(struct p54_common *priv)
727 p54_tx(priv, skb); 727 p54_tx(priv, skb);
728 return 0; 728 return 0;
729} 729}
730
731int p54_set_groupfilter(struct p54_common *priv)
732{
733 struct p54_group_address_table *grp;
734 struct sk_buff *skb;
735 bool on = false;
736
737 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp),
738 P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL);
739 if (!skb)
740 return -ENOMEM;
741
742 grp = (struct p54_group_address_table *)skb_put(skb, sizeof(*grp));
743
744 on = !(priv->filter_flags & FIF_ALLMULTI) &&
745 (priv->mc_maclist_num > 0 &&
746 priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM);
747
748 if (on) {
749 grp->filter_enable = cpu_to_le16(1);
750 grp->num_address = cpu_to_le16(priv->mc_maclist_num);
751 memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list));
752 } else {
753 grp->filter_enable = cpu_to_le16(0);
754 grp->num_address = cpu_to_le16(0);
755 memset(grp->mac_list, 0, sizeof(grp->mac_list));
756 }
757
758 p54_tx(priv, skb);
759 return 0;
760}