realtek: clean up rtl838x MDIO busy wait loop
[openwrt/staging/jow.git] / target / linux / realtek / files-5.10 / drivers / net / dsa / rtl83xx / rtl838x.c
index 8e48cbf6442fc130e4e040bb62e9b33ca81e1299..524594d725fce7cb1a5f0c81cf1bf17bc718e29a 100644 (file)
@@ -1673,6 +1673,26 @@ void rtl838x_set_distribution_algorithm(int group, int algoidx, u32 algomsk)
        sw_w32(algomsk, RTL838X_TRK_HASH_CTRL + (algoidx << 2));
 }
 
+void rtl838x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action)
+{
+       switch(type) {
+       case BPDU:
+               sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1),
+                           RTL838X_RMA_BPDU_CTRL + ((port >> 4) << 2));
+       break;
+       case PTP:
+               sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1),
+                           RTL838X_RMA_PTP_CTRL + ((port >> 4) << 2));
+       break;
+       case LLTP:
+               sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1),
+                           RTL838X_RMA_LLTP_CTRL + ((port >> 4) << 2));
+       break;
+       default:
+       break;
+       }
+}
+
 const struct rtl838x_reg rtl838x_reg = {
        .mask_port_reg_be = rtl838x_mask_port_reg,
        .set_port_reg_be = rtl838x_set_port_reg,
@@ -1756,6 +1776,7 @@ const struct rtl838x_reg rtl838x_reg = {
        .route_write = rtl838x_route_write,
        .l3_setup = rtl838x_l3_setup,
        .set_distribution_algorithm = rtl838x_set_distribution_algorithm,
+       .set_receive_management_action = rtl838x_set_receive_management_action,
 };
 
 irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
@@ -1784,13 +1805,20 @@ irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
 
 int rtl838x_smi_wait_op(int timeout)
 {
-       do {
-               timeout--;
-               udelay(10);
-       } while ((sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & 0x1) && (timeout >= 0));
-       if (timeout <= 0)
-               return -1;
-       return 0;
+       unsigned long end = jiffies + usecs_to_jiffies(timeout);
+
+       while (1) {
+               if (!(sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & 0x1))
+                       return 0;
+
+               if (time_after(jiffies, end))
+                       break;
+
+               usleep_range(10, 20);
+       }
+
+       pr_err("rtl838x_smi_wait_op: timeout\n");
+       return -1;
 }
 
 /*
@@ -1811,7 +1839,7 @@ int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
 
        mutex_lock(&smi_lock);
 
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
@@ -1821,7 +1849,7 @@ int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
        sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
        sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
 
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
@@ -1847,7 +1875,7 @@ int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
                return -ENOTSUPP;
 
        mutex_lock(&smi_lock);
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        sw_w32(BIT(port), RTL838X_SMI_ACCESS_PHY_CTRL_0);
@@ -1860,7 +1888,7 @@ int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
        sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
        sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
 
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        mutex_unlock(&smi_lock);
@@ -1880,7 +1908,7 @@ int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
 
        mutex_lock(&smi_lock);
 
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
@@ -1895,7 +1923,7 @@ int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
        v = 1 << 1 | 0 << 2 | 1;
        sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
 
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
@@ -1919,7 +1947,7 @@ int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
        val &= 0xffff;
        mutex_lock(&smi_lock);
 
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
@@ -1933,7 +1961,7 @@ int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
        v = 1 << 1 | 1 << 2 | 1;
        sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
 
-       if (rtl838x_smi_wait_op(10000))
+       if (rtl838x_smi_wait_op(100000))
                goto timeout;
 
        mutex_unlock(&smi_lock);