summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
authorPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>2012-04-25 01:46:06 (GMT)
committerDavid S. Miller <davem@davemloft.net>2012-04-26 09:03:31 (GMT)
commit0fc16ebf69fc57b42110712eaaf8a6aa2492afbe (patch)
treedf3e300116074ad8ad7ca89a1a8c1edbeb30e86d /drivers/net/ethernet/emulex
parent9cf6ace5f5c7981f5df76af3e1b90d77cc3cdece (diff)
downloadlinux-0fc16ebf69fc57b42110712eaaf8a6aa2492afbe.tar.xz
be2net: Fix VLAN/multicast packet reception
VLAN and multicast hardware filters are limited and can get exhausted in adapters with many PCI functions. If setting a VLAN or multicast filter fails due to lack of sufficient hardware resources, these packets get dropped. Fix this by switching to VLAN or multicast promiscous mode so that these packets are not dropped. Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a5bc608..a9a11d4 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -797,22 +797,30 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
if (adapter->promiscuous)
return 0;
- if (adapter->vlans_added <= adapter->max_vlans) {
- /* Construct VLAN Table to give to HW */
- for (i = 0; i < VLAN_N_VID; i++) {
- if (adapter->vlan_tag[i]) {
- vtag[ntags] = cpu_to_le16(i);
- ntags++;
- }
- }
- status = be_cmd_vlan_config(adapter, adapter->if_handle,
- vtag, ntags, 1, 0);
- } else {
- status = be_cmd_vlan_config(adapter, adapter->if_handle,
- NULL, 0, 1, 1);
+ if (adapter->vlans_added > adapter->max_vlans)
+ goto set_vlan_promisc;
+
+ /* Construct VLAN Table to give to HW */
+ for (i = 0; i < VLAN_N_VID; i++)
+ if (adapter->vlan_tag[i])
+ vtag[ntags++] = cpu_to_le16(i);
+
+ status = be_cmd_vlan_config(adapter, adapter->if_handle,
+ vtag, ntags, 1, 0);
+
+ /* Set to VLAN promisc mode as setting VLAN filter failed */
+ if (status) {
+ dev_info(&adapter->pdev->dev, "Exhausted VLAN HW filters.\n");
+ dev_info(&adapter->pdev->dev, "Disabling HW VLAN filtering.\n");
+ goto set_vlan_promisc;
}
return status;
+
+set_vlan_promisc:
+ status = be_cmd_vlan_config(adapter, adapter->if_handle,
+ NULL, 0, 1, 1);
+ return status;
}
static int be_vlan_add_vid(struct net_device *netdev, u16 vid)
@@ -862,6 +870,7 @@ ret:
static void be_set_rx_mode(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
+ int status;
if (netdev->flags & IFF_PROMISC) {
be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
@@ -908,7 +917,14 @@ static void be_set_rx_mode(struct net_device *netdev)
}
}
- be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
+ status = be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
+
+ /* Set to MCAST promisc mode if setting MULTICAST address fails */
+ if (status) {
+ dev_info(&adapter->pdev->dev, "Exhausted multicast HW filters.\n");
+ dev_info(&adapter->pdev->dev, "Disabling HW multicast filtering.\n");
+ be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
+ }
done:
return;
}