Commit 837d4eb6 authored by Sudarsana Reddy Kalluru's avatar Sudarsana Reddy Kalluru Committed by David S. Miller

qede: Loopback implementation should ignore the normal traffic

During the execution of loopback test, driver may receive the packets which
are not originated by this test, loopback implementation need to skip those
packets.
Signed-off-by: default avatarSudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: default avatarYuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ba300ce3
...@@ -348,6 +348,7 @@ bool qede_has_rx_work(struct qede_rx_queue *rxq); ...@@ -348,6 +348,7 @@ bool qede_has_rx_work(struct qede_rx_queue *rxq);
int qede_txq_has_work(struct qede_tx_queue *txq); int qede_txq_has_work(struct qede_tx_queue *txq);
void qede_recycle_rx_bd_ring(struct qede_rx_queue *rxq, struct qede_dev *edev, void qede_recycle_rx_bd_ring(struct qede_rx_queue *rxq, struct qede_dev *edev,
u8 count); u8 count);
void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq);
#define RX_RING_SIZE_POW 13 #define RX_RING_SIZE_POW 13
#define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW)) #define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW))
......
...@@ -1207,8 +1207,8 @@ static int qede_selftest_receive_traffic(struct qede_dev *edev) ...@@ -1207,8 +1207,8 @@ static int qede_selftest_receive_traffic(struct qede_dev *edev)
struct qede_rx_queue *rxq = NULL; struct qede_rx_queue *rxq = NULL;
struct sw_rx_data *sw_rx_data; struct sw_rx_data *sw_rx_data;
union eth_rx_cqe *cqe; union eth_rx_cqe *cqe;
int i, rc = 0;
u8 *data_ptr; u8 *data_ptr;
int i;
for_each_queue(i) { for_each_queue(i) {
if (edev->fp_array[i].type & QEDE_FASTPATH_RX) { if (edev->fp_array[i].type & QEDE_FASTPATH_RX) {
...@@ -1227,46 +1227,60 @@ static int qede_selftest_receive_traffic(struct qede_dev *edev) ...@@ -1227,46 +1227,60 @@ static int qede_selftest_receive_traffic(struct qede_dev *edev)
* queue and that the loopback traffic is not IP. * queue and that the loopback traffic is not IP.
*/ */
for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) { for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) {
if (qede_has_rx_work(rxq)) if (!qede_has_rx_work(rxq)) {
usleep_range(100, 200);
continue;
}
hw_comp_cons = le16_to_cpu(*rxq->hw_cons_ptr);
sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring);
/* Memory barrier to prevent the CPU from doing speculative
* reads of CQE/BD before reading hw_comp_cons. If the CQE is
* read before it is written by FW, then FW writes CQE and SB,
* and then the CPU reads the hw_comp_cons, it will use an old
* CQE.
*/
rmb();
/* Get the CQE from the completion ring */
cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring);
/* Get the data from the SW ring */
sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS_MAX;
sw_rx_data = &rxq->sw_rx_ring[sw_rx_index];
fp_cqe = &cqe->fast_path_regular;
len = le16_to_cpu(fp_cqe->len_on_first_bd);
data_ptr = (u8 *)(page_address(sw_rx_data->data) +
fp_cqe->placement_offset +
sw_rx_data->page_offset);
if (ether_addr_equal(data_ptr, edev->ndev->dev_addr) &&
ether_addr_equal(data_ptr + ETH_ALEN,
edev->ndev->dev_addr)) {
for (i = ETH_HLEN; i < len; i++)
if (data_ptr[i] != (unsigned char)(i & 0xff)) {
rc = -1;
break;
}
qede_recycle_rx_bd_ring(rxq, edev, 1);
qed_chain_recycle_consumed(&rxq->rx_comp_ring);
break; break;
usleep_range(100, 200); }
DP_INFO(edev, "Not the transmitted packet\n");
qede_recycle_rx_bd_ring(rxq, edev, 1);
qed_chain_recycle_consumed(&rxq->rx_comp_ring);
} }
if (!qede_has_rx_work(rxq)) { if (i == QEDE_SELFTEST_POLL_COUNT) {
DP_NOTICE(edev, "Failed to receive the traffic\n"); DP_NOTICE(edev, "Failed to receive the traffic\n");
return -1; return -1;
} }
hw_comp_cons = le16_to_cpu(*rxq->hw_cons_ptr); qede_update_rx_prod(edev, rxq);
sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring);
/* Memory barrier to prevent the CPU from doing speculative reads of CQE
* / BD before reading hw_comp_cons. If the CQE is read before it is
* written by FW, then FW writes CQE and SB, and then the CPU reads the
* hw_comp_cons, it will use an old CQE.
*/
rmb();
/* Get the CQE from the completion ring */
cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring);
/* Get the data from the SW ring */
sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS_MAX;
sw_rx_data = &rxq->sw_rx_ring[sw_rx_index];
fp_cqe = &cqe->fast_path_regular;
len = le16_to_cpu(fp_cqe->len_on_first_bd);
data_ptr = (u8 *)(page_address(sw_rx_data->data) +
fp_cqe->placement_offset + sw_rx_data->page_offset);
for (i = ETH_HLEN; i < len; i++)
if (data_ptr[i] != (unsigned char)(i & 0xff)) {
DP_NOTICE(edev, "Loopback test failed\n");
qede_recycle_rx_bd_ring(rxq, edev, 1);
return -1;
}
qede_recycle_rx_bd_ring(rxq, edev, 1);
return 0; return rc;
} }
static int qede_selftest_run_loopback(struct qede_dev *edev, u32 loopback_mode) static int qede_selftest_run_loopback(struct qede_dev *edev, u32 loopback_mode)
......
...@@ -943,8 +943,7 @@ static inline int qede_realloc_rx_buffer(struct qede_dev *edev, ...@@ -943,8 +943,7 @@ static inline int qede_realloc_rx_buffer(struct qede_dev *edev,
return 0; return 0;
} }
static inline void qede_update_rx_prod(struct qede_dev *edev, void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq)
struct qede_rx_queue *rxq)
{ {
u16 bd_prod = qed_chain_get_prod_idx(&rxq->rx_bd_ring); u16 bd_prod = qed_chain_get_prod_idx(&rxq->rx_bd_ring);
u16 cqe_prod = qed_chain_get_prod_idx(&rxq->rx_comp_ring); u16 cqe_prod = qed_chain_get_prod_idx(&rxq->rx_comp_ring);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment