Commit 969a7ee2 authored by Huang, Xiong's avatar Huang, Xiong Committed by David S. Miller

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: default avatarxiong <xiong@qca.qualcomm.com>
Tested-by: default avatarLiu David <dwliu@qca.qualcomm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9c528218
...@@ -227,17 +227,25 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw); ...@@ -227,17 +227,25 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw);
GPHY_CTRL_HIB_PULSE |\ GPHY_CTRL_HIB_PULSE |\
GPHY_CTRL_PWDOWN_HW |\ GPHY_CTRL_PWDOWN_HW |\
GPHY_CTRL_PHY_IDDQ) GPHY_CTRL_PHY_IDDQ)
/* Block IDLE Status Register */ /* Block IDLE Status Register */
#define REG_IDLE_STATUS 0x1410 #define REG_IDLE_STATUS 0x1410
#define IDLE_STATUS_MASK 0x00FF #define IDLE_STATUS_SFORCE_MASK 0xFUL
#define IDLE_STATUS_RXMAC_NO_IDLE 0x1 #define IDLE_STATUS_SFORCE_SHIFT 14
#define IDLE_STATUS_TXMAC_NO_IDLE 0x2 #define IDLE_STATUS_CALIB_DONE BIT(13)
#define IDLE_STATUS_RXQ_NO_IDLE 0x4 #define IDLE_STATUS_CALIB_RES_MASK 0x1FUL
#define IDLE_STATUS_TXQ_NO_IDLE 0x8 #define IDLE_STATUS_CALIB_RES_SHIFT 8
#define IDLE_STATUS_DMAR_NO_IDLE 0x10 #define IDLE_STATUS_CALIBERR_MASK 0xFUL
#define IDLE_STATUS_DMAW_NO_IDLE 0x20 #define IDLE_STATUS_CALIBERR_SHIFT 4
#define IDLE_STATUS_SMB_NO_IDLE 0x40 #define IDLE_STATUS_TXQ_BUSY BIT(3)
#define IDLE_STATUS_CMB_NO_IDLE 0x80 #define IDLE_STATUS_RXQ_BUSY BIT(2)
#define IDLE_STATUS_TXMAC_BUSY BIT(1)
#define IDLE_STATUS_RXMAC_BUSY BIT(0)
#define IDLE_STATUS_MASK (\
IDLE_STATUS_TXQ_BUSY |\
IDLE_STATUS_RXQ_BUSY |\
IDLE_STATUS_TXMAC_BUSY |\
IDLE_STATUS_RXMAC_BUSY)
/* MDIO Control Register */ /* MDIO Control Register */
#define REG_MDIO_CTRL 0x1414 #define REG_MDIO_CTRL 0x1414
......
...@@ -185,14 +185,14 @@ static inline void atl1c_irq_reset(struct atl1c_adapter *adapter) ...@@ -185,14 +185,14 @@ static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
* atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads * atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
* of the idle status register until the device is actually idle * 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; int timeout;
u32 data; u32 data;
for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
AT_READ_REG(hw, REG_IDLE_STATUS, &data); AT_READ_REG(hw, REG_IDLE_STATUS, &data);
if ((data & IDLE_STATUS_MASK) == 0) if ((data & modu_ctrl) == 0)
return 0; return 0;
msleep(1); msleep(1);
} }
...@@ -1119,13 +1119,14 @@ static int atl1c_stop_mac(struct atl1c_hw *hw) ...@@ -1119,13 +1119,14 @@ static int atl1c_stop_mac(struct atl1c_hw *hw)
data &= ~TXQ_CTRL_EN; data &= ~TXQ_CTRL_EN;
AT_WRITE_REG(hw, REG_TXQ_CTRL, data); 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); AT_READ_REG(hw, REG_MAC_CTRL, &data);
data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN); data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
AT_WRITE_REG(hw, REG_MAC_CTRL, data); 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) static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
...@@ -1176,7 +1177,7 @@ static int atl1c_reset_mac(struct atl1c_hw *hw) ...@@ -1176,7 +1177,7 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
msleep(10); msleep(10);
/* Wait at least 10ms for All module to be Idle */ /* 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, dev_err(&pdev->dev,
"MAC state machine can't be idle since" "MAC state machine can't be idle since"
" disabled for 10ms second\n"); " disabled for 10ms second\n");
......
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