summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDave Lim <dlim@nvidia.com>2016-05-10 14:08:55 -0400
committerAshutosh Jha <ajha@nvidia.com>2016-05-10 21:10:45 -0400
commit558fa62396b2477eb7414e03571c062b9dfc3fe1 (patch)
treed1d180f78fe2faac4e781e6b12a182a947ec47d3 /drivers/net
parent4ad7aab2aba4ac345da3cbd79c6c48c0be4e8736 (diff)
net: eqos: Fix race condition with rx own bit.
Resolved race condition where there could be dma outstanding for same rx descriptor which has own bit set to zero. Bug 1762280 Change-Id: I53a9361037d1783b030db78ddd249295b61651e1 Signed-off-by: Dave Lim <dlim@nvidia.com> Reviewed-on: http://git-master/r/1144836 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Anirban Ray <aray@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/nvidia/eqos/dev.c5
-rw-r--r--drivers/net/ethernet/nvidia/eqos/drv.c19
-rw-r--r--drivers/net/ethernet/nvidia/eqos/yheader.h4
3 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/ethernet/nvidia/eqos/dev.c b/drivers/net/ethernet/nvidia/eqos/dev.c
index 41cb8dad1..16aabbc90 100644
--- a/drivers/net/ethernet/nvidia/eqos/dev.c
+++ b/drivers/net/ethernet/nvidia/eqos/dev.c
@@ -29,7 +29,7 @@
29 * DAMAGE. 29 * DAMAGE.
30 * ========================================================================= */ 30 * ========================================================================= */
31/* 31/*
32 * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. 32 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
33 * 33 *
34 * This program is free software; you can redistribute it and/or modify it 34 * This program is free software; you can redistribute it and/or modify it
35 * under the terms and conditions of the GNU General Public License, 35 * under the terms and conditions of the GNU General Public License,
@@ -2869,6 +2869,9 @@ static void rx_descriptor_init(struct eqos_prv_data *pdata, UINT qinx)
2869 /* update the starting address of desc chain/ring */ 2869 /* update the starting address of desc chain/ring */
2870 DMA_RDLAR_WR(qinx, GET_RX_DESC_DMA_ADDR(qinx, start_index)); 2870 DMA_RDLAR_WR(qinx, GET_RX_DESC_DMA_ADDR(qinx, start_index));
2871 2871
2872 prx_ring->hw_last_rx_desc_addr =
2873 GET_RX_DESC_DMA_ADDR(qinx, start_index);
2874
2872 DBGPR("<--rx_descriptor_init\n"); 2875 DBGPR("<--rx_descriptor_init\n");
2873} 2876}
2874 2877
diff --git a/drivers/net/ethernet/nvidia/eqos/drv.c b/drivers/net/ethernet/nvidia/eqos/drv.c
index 617027371..2c56f3bda 100644
--- a/drivers/net/ethernet/nvidia/eqos/drv.c
+++ b/drivers/net/ethernet/nvidia/eqos/drv.c
@@ -29,7 +29,7 @@
29 * DAMAGE. 29 * DAMAGE.
30 * ========================================================================= */ 30 * ========================================================================= */
31/* 31/*
32 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 32 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
33 * 33 *
34 * This program is free software; you can redistribute it and/or modify it 34 * This program is free software; you can redistribute it and/or modify it
35 * under the terms and conditions of the GNU General Public License, 35 * under the terms and conditions of the GNU General Public License,
@@ -2338,18 +2338,33 @@ static int process_rx_completions(struct eqos_prv_data *pdata,
2338 struct s_rx_desc *prx_desc = NULL; 2338 struct s_rx_desc *prx_desc = NULL;
2339 UINT pkt_len; 2339 UINT pkt_len;
2340 UINT err_bits = EQOS_RDESC3_ES_BITS; 2340 UINT err_bits = EQOS_RDESC3_ES_BITS;
2341 u32 sw_cur_rx_desc_addr = 0;
2342 u32 hw_cur_rx_desc_addr = 0;
2341 2343
2342 int ret; 2344 int ret;
2343 2345
2344 DBGPR("-->%s(): qinx = %u, quota = %d\n", __func__, qinx, quota); 2346 DBGPR("-->%s(): qinx = %u, quota = %d\n", __func__, qinx, quota);
2345 2347
2348 hw_cur_rx_desc_addr = prx_ring->hw_last_rx_desc_addr;
2346 while (received < quota) { 2349 while (received < quota) {
2347 prx_swcx_desc = GET_RX_BUF_PTR(qinx, prx_ring->cur_rx); 2350 prx_swcx_desc = GET_RX_BUF_PTR(qinx, prx_ring->cur_rx);
2348 prx_desc = GET_RX_DESC_PTR(qinx, prx_ring->cur_rx); 2351 prx_desc = GET_RX_DESC_PTR(qinx, prx_ring->cur_rx);
2349 2352
2353 sw_cur_rx_desc_addr =
2354 GET_RX_DESC_DMA_ADDR(qinx, prx_ring->cur_rx);
2355
2350 /* check for data availability */ 2356 /* check for data availability */
2351 if (!(prx_desc->rdes3 & EQOS_RDESC3_OWN) && 2357 if (!(prx_desc->rdes3 & EQOS_RDESC3_OWN) &&
2352 prx_swcx_desc->skb) { 2358 prx_swcx_desc->skb) {
2359 if (hw_cur_rx_desc_addr == sw_cur_rx_desc_addr) {
2360 DMA_CHRDR_RD(qinx,
2361 prx_ring->hw_last_rx_desc_addr);
2362 if (prx_ring->hw_last_rx_desc_addr ==
2363 hw_cur_rx_desc_addr)
2364 break;
2365 hw_cur_rx_desc_addr =
2366 prx_ring->hw_last_rx_desc_addr;
2367 }
2353#ifdef EQOS_ENABLE_RX_DESC_DUMP 2368#ifdef EQOS_ENABLE_RX_DESC_DUMP
2354 dump_rx_desc(qinx, prx_desc, prx_ring->cur_rx); 2369 dump_rx_desc(qinx, prx_desc, prx_ring->cur_rx);
2355#endif 2370#endif
diff --git a/drivers/net/ethernet/nvidia/eqos/yheader.h b/drivers/net/ethernet/nvidia/eqos/yheader.h
index 2e4e5b7e5..bc1cb7823 100644
--- a/drivers/net/ethernet/nvidia/eqos/yheader.h
+++ b/drivers/net/ethernet/nvidia/eqos/yheader.h
@@ -29,7 +29,7 @@
29 * DAMAGE. 29 * DAMAGE.
30 * ========================================================================= */ 30 * ========================================================================= */
31/* 31/*
32 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 32 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
33 * 33 *
34 * This program is free software; you can redistribute it and/or modify it 34 * This program is free software; you can redistribute it and/or modify it
35 * under the terms and conditions of the GNU General Public License, 35 * under the terms and conditions of the GNU General Public License,
@@ -1019,6 +1019,8 @@ struct rx_ring {
1019 /* for rx vlan stripping */ 1019 /* for rx vlan stripping */
1020 u32 rx_inner_vlan_strip; 1020 u32 rx_inner_vlan_strip;
1021 u32 rx_outer_vlan_strip; 1021 u32 rx_outer_vlan_strip;
1022
1023 u32 hw_last_rx_desc_addr;
1022}; 1024};
1023 1025
1024struct eqos_rx_queue { 1026struct eqos_rx_queue {