Commit c3727d61 authored by Lendacky, Thomas's avatar Lendacky, Thomas Committed by David S. Miller

amd-xgbe: Check Rx queue fifos before stopping Rx DMA

Check to be sure that the Rx queue fifos are empty before stopping the
Rx DMA channels.
Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b3b71597
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* License 1: GPLv2 * License 1: GPLv2
* *
* Copyright (c) 2014 Advanced Micro Devices, Inc. * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* *
* This file is free software; you may copy, redistribute and/or modify * This file is free software; you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
* *
* License 2: Modified BSD * License 2: Modified BSD
* *
* Copyright (c) 2014 Advanced Micro Devices, Inc. * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -768,12 +768,16 @@ ...@@ -768,12 +768,16 @@
#define MTL_Q_TQDR 0x08 #define MTL_Q_TQDR 0x08
#define MTL_Q_RQOMR 0x40 #define MTL_Q_RQOMR 0x40
#define MTL_Q_RQMPOCR 0x44 #define MTL_Q_RQMPOCR 0x44
#define MTL_Q_RQDR 0x4c #define MTL_Q_RQDR 0x48
#define MTL_Q_RQFCR 0x50 #define MTL_Q_RQFCR 0x50
#define MTL_Q_IER 0x70 #define MTL_Q_IER 0x70
#define MTL_Q_ISR 0x74 #define MTL_Q_ISR 0x74
/* MTL queue register entry bit positions and sizes */ /* MTL queue register entry bit positions and sizes */
#define MTL_Q_RQDR_PRXQ_INDEX 16
#define MTL_Q_RQDR_PRXQ_WIDTH 14
#define MTL_Q_RQDR_RXQSTS_INDEX 4
#define MTL_Q_RQDR_RXQSTS_WIDTH 2
#define MTL_Q_RQFCR_RFA_INDEX 1 #define MTL_Q_RQFCR_RFA_INDEX 1
#define MTL_Q_RQFCR_RFA_WIDTH 6 #define MTL_Q_RQFCR_RFA_WIDTH 6
#define MTL_Q_RQFCR_RFD_INDEX 17 #define MTL_Q_RQFCR_RFD_INDEX 17
......
...@@ -2656,6 +2656,32 @@ static void xgbe_disable_tx(struct xgbe_prv_data *pdata) ...@@ -2656,6 +2656,32 @@ static void xgbe_disable_tx(struct xgbe_prv_data *pdata)
} }
} }
static void xgbe_prepare_rx_stop(struct xgbe_prv_data *pdata,
unsigned int queue)
{
unsigned int rx_status;
unsigned long rx_timeout;
/* The Rx engine cannot be stopped if it is actively processing
* packets. Wait for the Rx queue to empty the Rx fifo. Don't
* wait forever though...
*/
rx_timeout = jiffies + (XGBE_DMA_STOP_TIMEOUT * HZ);
while (time_before(jiffies, rx_timeout)) {
rx_status = XGMAC_MTL_IOREAD(pdata, queue, MTL_Q_RQDR);
if ((XGMAC_GET_BITS(rx_status, MTL_Q_RQDR, PRXQ) == 0) &&
(XGMAC_GET_BITS(rx_status, MTL_Q_RQDR, RXQSTS) == 0))
break;
usleep_range(500, 1000);
}
if (!time_before(jiffies, rx_timeout))
netdev_info(pdata->netdev,
"timed out waiting for Rx queue %u to empty\n",
queue);
}
static void xgbe_enable_rx(struct xgbe_prv_data *pdata) static void xgbe_enable_rx(struct xgbe_prv_data *pdata)
{ {
struct xgbe_channel *channel; struct xgbe_channel *channel;
...@@ -2694,6 +2720,10 @@ static void xgbe_disable_rx(struct xgbe_prv_data *pdata) ...@@ -2694,6 +2720,10 @@ static void xgbe_disable_rx(struct xgbe_prv_data *pdata)
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0); XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0); XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0);
/* Prepare for Rx DMA channel stop */
for (i = 0; i < pdata->rx_q_count; i++)
xgbe_prepare_rx_stop(pdata, i);
/* Disable each Rx queue */ /* Disable each Rx queue */
XGMAC_IOWRITE(pdata, MAC_RQC0R, 0); XGMAC_IOWRITE(pdata, MAC_RQC0R, 0);
......
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