aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSathya Perla <sathyap@serverengines.com>2010-02-16 20:35:26 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-17 16:35:39 -0500
commit89420424fce28769c338909393518087befe8b37 (patch)
tree1f3f40831ff18d40200bb8ff808d87ab5dbe9f48
parent7a1e9b2059d147461cff3dfbabbfb43f296a1eef (diff)
be2net: fix rx-path to ignore a flush completion
The flush compl (compl with numfrags == 0; no data) is rcvd from hw to indicate completion of RXQ destory operation. Fix the RX path to not process it as RX data. Signed-off-by: Sathya Perla <sathyap@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/benet/be_main.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 43dbe288a5ef..2c3deadd2d83 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -680,17 +680,17 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
680 * indicated by rxcp. 680 * indicated by rxcp.
681 */ 681 */
682static void skb_fill_rx_data(struct be_adapter *adapter, 682static void skb_fill_rx_data(struct be_adapter *adapter,
683 struct sk_buff *skb, struct be_eth_rx_compl *rxcp) 683 struct sk_buff *skb, struct be_eth_rx_compl *rxcp,
684 u16 num_rcvd)
684{ 685{
685 struct be_queue_info *rxq = &adapter->rx_obj.q; 686 struct be_queue_info *rxq = &adapter->rx_obj.q;
686 struct be_rx_page_info *page_info; 687 struct be_rx_page_info *page_info;
687 u16 rxq_idx, i, num_rcvd, j; 688 u16 rxq_idx, i, j;
688 u32 pktsize, hdr_len, curr_frag_len, size; 689 u32 pktsize, hdr_len, curr_frag_len, size;
689 u8 *start; 690 u8 *start;
690 691
691 rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); 692 rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
692 pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); 693 pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
693 num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
694 694
695 page_info = get_rx_page_info(adapter, rxq_idx); 695 page_info = get_rx_page_info(adapter, rxq_idx);
696 696
@@ -766,8 +766,14 @@ static void be_rx_compl_process(struct be_adapter *adapter,
766{ 766{
767 struct sk_buff *skb; 767 struct sk_buff *skb;
768 u32 vlanf, vid; 768 u32 vlanf, vid;
769 u16 num_rcvd;
769 u8 vtm; 770 u8 vtm;
770 771
772 num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
773 /* Is it a flush compl that has no data */
774 if (unlikely(num_rcvd == 0))
775 return;
776
771 skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); 777 skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
772 if (unlikely(!skb)) { 778 if (unlikely(!skb)) {
773 if (net_ratelimit()) 779 if (net_ratelimit())
@@ -776,7 +782,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
776 return; 782 return;
777 } 783 }
778 784
779 skb_fill_rx_data(adapter, skb, rxcp); 785 skb_fill_rx_data(adapter, skb, rxcp, num_rcvd);
780 786
781 if (do_pkt_csum(rxcp, adapter->rx_csum)) 787 if (do_pkt_csum(rxcp, adapter->rx_csum))
782 skb->ip_summed = CHECKSUM_NONE; 788 skb->ip_summed = CHECKSUM_NONE;
@@ -823,6 +829,10 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
823 u8 vtm; 829 u8 vtm;
824 830
825 num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); 831 num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
832 /* Is it a flush compl that has no data */
833 if (unlikely(num_rcvd == 0))
834 return;
835
826 pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); 836 pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
827 vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); 837 vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
828 rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); 838 rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
@@ -1273,6 +1283,11 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
1273 q = &adapter->rx_obj.q; 1283 q = &adapter->rx_obj.q;
1274 if (q->created) { 1284 if (q->created) {
1275 be_cmd_q_destroy(adapter, q, QTYPE_RXQ); 1285 be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
1286
1287 /* After the rxq is invalidated, wait for a grace time
1288 * of 1ms for all dma to end and the flush compl to arrive
1289 */
1290 mdelay(1);
1276 be_rx_q_clean(adapter); 1291 be_rx_q_clean(adapter);
1277 } 1292 }
1278 be_queue_free(adapter, q); 1293 be_queue_free(adapter, q);