atl1c: add module parameter for l1c_wait_until_idle
l1c_wait_until_idle is called for serval modules (TXQ/RXQ/TXMAC/RXMAC).
specific moudle have specific idle/busy status in reg REG_IDLE_STATUS.
the previous code return wrongly if all modules are in idle status,
regardless the 'stop' action is applied on individual module.
Refine the reg REG_IDLE_STATUS definition as well.
Signed-off-by: xiong <xiong@qca.qualcomm.com>
Tested-by: Liu David <dwliu@qca.qualcomm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 2e1c9f3..d2f89f0 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -185,14 +185,14 @@
* atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
* of the idle status register until the device is actually idle
*/
-static u32 atl1c_wait_until_idle(struct atl1c_hw *hw)
+static u32 atl1c_wait_until_idle(struct atl1c_hw *hw, u32 modu_ctrl)
{
int timeout;
u32 data;
for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
AT_READ_REG(hw, REG_IDLE_STATUS, &data);
- if ((data & IDLE_STATUS_MASK) == 0)
+ if ((data & modu_ctrl) == 0)
return 0;
msleep(1);
}
@@ -1119,13 +1119,14 @@
data &= ~TXQ_CTRL_EN;
AT_WRITE_REG(hw, REG_TXQ_CTRL, data);
- atl1c_wait_until_idle(hw);
+ atl1c_wait_until_idle(hw, IDLE_STATUS_RXQ_BUSY | IDLE_STATUS_TXQ_BUSY);
AT_READ_REG(hw, REG_MAC_CTRL, &data);
data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
AT_WRITE_REG(hw, REG_MAC_CTRL, data);
- return (int)atl1c_wait_until_idle(hw);
+ return (int)atl1c_wait_until_idle(hw,
+ IDLE_STATUS_TXMAC_BUSY | IDLE_STATUS_RXMAC_BUSY);
}
static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
@@ -1176,7 +1177,7 @@
msleep(10);
/* Wait at least 10ms for All module to be Idle */
- if (atl1c_wait_until_idle(hw)) {
+ if (atl1c_wait_until_idle(hw, IDLE_STATUS_MASK)) {
dev_err(&pdev->dev,
"MAC state machine can't be idle since"
" disabled for 10ms second\n");