be2net: drop pkts that do not belong to the port
authorSathya Perla <sathya.perla@emulex.com>
Tue, 2 Aug 2011 19:57:46 +0000 (19:57 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 3 Aug 2011 10:23:30 +0000 (03:23 -0700)
On some BE skews, while in promiscuous mode, pkts that do not belong to a
port can arrive on that port. Drop such pkts.

Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/benet/be.h
drivers/net/benet/be_main.c

index 1e7f0094e382c99712f51c33f63b05d43c829cdd..12b5b5168dca36a3b5153c635564bbb6aa32a615 100644 (file)
@@ -217,7 +217,7 @@ struct be_rx_compl_info {
        u16 vlan_tag;
        u16 pkt_size;
        u16 rxq_idx;
-       u16 mac_id;
+       u16 port;
        u8 vlanf;
        u8 num_rcvd;
        u8 err;
index dba6941f868aa4896f3650cfd983462670af7e35..1a3accab3d1721fa79ef3461d73ce70bf3460ea2 100644 (file)
@@ -1213,6 +1213,7 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter,
                rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
                                               compl);
        }
+       rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
 }
 
 static void be_parse_rx_compl_v0(struct be_adapter *adapter,
@@ -1245,6 +1246,7 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter,
                rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
                                               compl);
        }
+       rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
 }
 
 static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@ -1833,16 +1835,30 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
                if (!rxcp)
                        break;
 
-               /* Ignore flush completions */
-               if (rxcp->num_rcvd && rxcp->pkt_size) {
-                       if (do_gro(rxcp))
-                               be_rx_compl_process_gro(adapter, rxo, rxcp);
-                       else
-                               be_rx_compl_process(adapter, rxo, rxcp);
-               } else if (rxcp->pkt_size == 0) {
+               /* Is it a flush compl that has no data */
+               if (unlikely(rxcp->num_rcvd == 0))
+                       goto loop_continue;
+
+               /* Discard compl with partial DMA Lancer B0 */
+               if (unlikely(!rxcp->pkt_size)) {
                        be_rx_compl_discard(adapter, rxo, rxcp);
+                       goto loop_continue;
                }
 
+               /* On BE drop pkts that arrive due to imperfect filtering in
+                * promiscuous mode on some skews
+                */
+               if (unlikely(rxcp->port != adapter->port_num &&
+                               !lancer_chip(adapter))) {
+                       be_rx_compl_discard(adapter, rxo, rxcp);
+                       goto loop_continue;
+               }
+
+               if (do_gro(rxcp))
+                       be_rx_compl_process_gro(adapter, rxo, rxcp);
+               else
+                       be_rx_compl_process(adapter, rxo, rxcp);
+loop_continue:
                be_rx_stats_update(rxo, rxcp);
        }