diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c index 63c024c81e8..15e6ed09269 100644 --- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c @@ -121,28 +121,45 @@ void rtl_table_release(struct table_reg *r) // pr_info("Unlock done\n"); } +static int rtl_table_exec(struct table_reg *r, bool is_write, int idx) +{ + int ret = 0; + u32 cmd, val; + + /* Read/write bit has inverted meaning on RTL838x */ + if (r->rmode) + cmd = is_write ? 0 : BIT(r->c_bit); + else + cmd = is_write ? BIT(r->c_bit) : 0; + + cmd |= BIT(r->c_bit + 1); /* Execute bit */ + cmd |= r->tbl << r->t_bit; /* Table type */ + cmd |= idx & (BIT(r->t_bit) - 1); /* Index */ + + sw_w32(cmd, r->addr); + + ret = readx_poll_timeout(sw_r32, r->addr, val, + !(val & BIT(r->c_bit + 1)), 20, 10000); + if (ret) + pr_err("%s: timeout\n", __func__); + + return ret; +} + /* * Reads table index idx into the data registers of the table */ -void rtl_table_read(struct table_reg *r, int idx) +int rtl_table_read(struct table_reg *r, int idx) { - u32 cmd = r->rmode ? BIT(r->c_bit) : 0; - - cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1)); - sw_w32(cmd, r->addr); - do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1)); + return rtl_table_exec(r, false, idx); } /* * Writes the content of the table data registers into the table at index idx */ -void rtl_table_write(struct table_reg *r, int idx) +int rtl_table_write(struct table_reg *r, int idx) { - u32 cmd = r->rmode ? 0 : BIT(r->c_bit); - - cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1)); - sw_w32(cmd, r->addr); - do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1)); + return rtl_table_exec(r, true, idx); } /* diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl83xx.h index 107016469c6..485d0e8a7e9 100644 --- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl83xx.h +++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl83xx.h @@ -67,8 +67,8 @@ typedef enum { void rtl_table_init(void); struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t); void rtl_table_release(struct table_reg *r); -void rtl_table_read(struct table_reg *r, int idx); -void rtl_table_write(struct table_reg *r, int idx); +int rtl_table_read(struct table_reg *r, int idx); +int rtl_table_write(struct table_reg *r, int idx); inline u16 rtl_table_data(struct table_reg *r, int i); inline u32 rtl_table_data_r(struct table_reg *r, int i); inline void rtl_table_data_w(struct table_reg *r, u32 v, int i); diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c index 8b0b55d8919..fb359dc4faa 100644 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c @@ -121,28 +121,45 @@ void rtl_table_release(struct table_reg *r) // pr_info("Unlock done\n"); } +static int rtl_table_exec(struct table_reg *r, bool is_write, int idx) +{ + int ret = 0; + u32 cmd, val; + + /* Read/write bit has inverted meaning on RTL838x */ + if (r->rmode) + cmd = is_write ? 0 : BIT(r->c_bit); + else + cmd = is_write ? BIT(r->c_bit) : 0; + + cmd |= BIT(r->c_bit + 1); /* Execute bit */ + cmd |= r->tbl << r->t_bit; /* Table type */ + cmd |= idx & (BIT(r->t_bit) - 1); /* Index */ + + sw_w32(cmd, r->addr); + + ret = readx_poll_timeout(sw_r32, r->addr, val, + !(val & BIT(r->c_bit + 1)), 20, 10000); + if (ret) + pr_err("%s: timeout\n", __func__); + + return ret; +} + /* * Reads table index idx into the data registers of the table */ -void rtl_table_read(struct table_reg *r, int idx) +int rtl_table_read(struct table_reg *r, int idx) { - u32 cmd = r->rmode ? BIT(r->c_bit) : 0; - - cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1)); - sw_w32(cmd, r->addr); - do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1)); + return rtl_table_exec(r, false, idx); } /* * Writes the content of the table data registers into the table at index idx */ -void rtl_table_write(struct table_reg *r, int idx) +int rtl_table_write(struct table_reg *r, int idx) { - u32 cmd = r->rmode ? 0 : BIT(r->c_bit); - - cmd |= BIT(r->c_bit + 1) | (r->tbl << r->t_bit) | (idx & (BIT(r->t_bit) - 1)); - sw_w32(cmd, r->addr); - do { } while (sw_r32(r->addr) & BIT(r->c_bit + 1)); + return rtl_table_exec(r, true, idx); } /* diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h index 107016469c6..485d0e8a7e9 100644 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h +++ b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h @@ -67,8 +67,8 @@ typedef enum { void rtl_table_init(void); struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t); void rtl_table_release(struct table_reg *r); -void rtl_table_read(struct table_reg *r, int idx); -void rtl_table_write(struct table_reg *r, int idx); +int rtl_table_read(struct table_reg *r, int idx); +int rtl_table_write(struct table_reg *r, int idx); inline u16 rtl_table_data(struct table_reg *r, int i); inline u32 rtl_table_data_r(struct table_reg *r, int i); inline void rtl_table_data_w(struct table_reg *r, u32 v, int i);