mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-03-14 23:09:45 +01:00
realtek: dsa: consolidate switch_irq()
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run
Build all core packages / Build all core packages for selected target (push) Waiting to run
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Waiting to run
Build host tools / Build host tools for linux and macos based systems (push) Waiting to run
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run
Build all core packages / Build all core packages for selected target (push) Waiting to run
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Waiting to run
Build host tools / Build host tools for linux and macos based systems (push) Waiting to run
The dsa irq handler works always in the same way for all SoCs. - Read register ISR_PORT_LINK_STS_CHG to determine the ports that triggered the irq. - Write the read value back to the register to confirm the irq - Read link status via MAC_LINK_STS - Trigger dsa_port_phylink_mac_change() for each changed port Currently each SoC has its own implementation. Drop that in favour of a generic implementation that makes use of the existing bit register read/write helpers. Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de> Link: https://github.com/openwrt/openwrt/pull/22273 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
42fcfe535c
commit
056176cde1
6 changed files with 23 additions and 125 deletions
|
|
@ -1532,6 +1532,27 @@ static int rtl83xx_fib_event(struct notifier_block *this, unsigned long event, v
|
|||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static irqreturn_t rtldsa_switch_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct rtl838x_switch_priv *priv;
|
||||
struct dsa_switch *ds = dev_id;
|
||||
u64 link, ports;
|
||||
|
||||
priv = ds->priv;
|
||||
ports = priv->r->get_port_reg_le(priv->r->isr_port_link_sts_chg);
|
||||
priv->r->set_port_reg_le(ports, priv->r->isr_port_link_sts_chg);
|
||||
|
||||
/* read latched */
|
||||
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
|
||||
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
|
||||
|
||||
for (int port = 0; port < priv->cpu_port; port++)
|
||||
if (ports & BIT_ULL(port))
|
||||
dsa_port_phylink_mac_change(ds, port, link & BIT_ULL(port));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: This check is usually built into the DSA initialization functions. After carving
|
||||
* out the mdio driver from the ethernet driver, there are two drivers that must be loaded
|
||||
|
|
@ -1699,24 +1720,8 @@ static int rtl83xx_sw_probe(struct platform_device *pdev)
|
|||
|
||||
priv->link_state_irq = platform_get_irq(pdev, 0);
|
||||
pr_info("LINK state irq: %d\n", priv->link_state_irq);
|
||||
switch (priv->family_id) {
|
||||
case RTL8380_FAMILY_ID:
|
||||
err = request_irq(priv->link_state_irq, rtl838x_switch_irq,
|
||||
IRQF_SHARED, "rtl838x-link-state", priv->ds);
|
||||
break;
|
||||
case RTL8390_FAMILY_ID:
|
||||
err = request_irq(priv->link_state_irq, rtl839x_switch_irq,
|
||||
IRQF_SHARED, "rtl839x-link-state", priv->ds);
|
||||
break;
|
||||
case RTL9300_FAMILY_ID:
|
||||
err = request_irq(priv->link_state_irq, rtldsa_930x_switch_irq,
|
||||
IRQF_SHARED, "rtl930x-link-state", priv->ds);
|
||||
break;
|
||||
case RTL9310_FAMILY_ID:
|
||||
err = request_irq(priv->link_state_irq, rtl931x_switch_irq,
|
||||
IRQF_SHARED, "rtl931x-link-state", priv->ds);
|
||||
break;
|
||||
}
|
||||
err = request_irq(priv->link_state_irq, rtldsa_switch_irq,
|
||||
IRQF_SHARED, "rtldsa-link-state", priv->ds);
|
||||
if (err) {
|
||||
dev_err(dev, "Error setting up switch interrupt.\n");
|
||||
/* Need to free allocated switch here */
|
||||
|
|
|
|||
|
|
@ -1898,27 +1898,3 @@ const struct rtldsa_config rtldsa_838x_cfg = {
|
|||
.lag_set_port_members = rtldsa_838x_lag_set_port_members,
|
||||
.lag_setup_algomask = rtldsa_83xx_lag_setup_algomask,
|
||||
};
|
||||
|
||||
irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct dsa_switch *ds = dev_id;
|
||||
u32 status = sw_r32(RTL838X_ISR_GLB_SRC);
|
||||
u32 ports = sw_r32(RTL838X_ISR_PORT_LINK_STS_CHG);
|
||||
u32 link;
|
||||
|
||||
/* Clear status */
|
||||
sw_w32(ports, RTL838X_ISR_PORT_LINK_STS_CHG);
|
||||
pr_debug("RTL8380 Link change: status: %x, ports %x\n", status, ports);
|
||||
|
||||
for (int i = 0; i < 28; i++) {
|
||||
if (ports & BIT(i)) {
|
||||
link = sw_r32(RTL838X_MAC_LINK_STS);
|
||||
if (link & BIT(i))
|
||||
dsa_port_phylink_mac_change(ds, i, true);
|
||||
else
|
||||
dsa_port_phylink_mac_change(ds, i, false);
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -708,30 +708,6 @@ static void rtl839x_set_static_move_action(int port, bool forward)
|
|||
RTL839X_L2_PORT_STATIC_MV_ACT(port));
|
||||
}
|
||||
|
||||
irqreturn_t rtl839x_switch_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct dsa_switch *ds = dev_id;
|
||||
u32 status = sw_r32(RTL839X_ISR_GLB_SRC);
|
||||
u64 ports = rtl839x_get_port_reg_le(RTL839X_ISR_PORT_LINK_STS_CHG);
|
||||
u64 link;
|
||||
|
||||
/* Clear status */
|
||||
rtl839x_set_port_reg_le(ports, RTL839X_ISR_PORT_LINK_STS_CHG);
|
||||
pr_debug("RTL8390 Link change: status: %x, ports %llx\n", status, ports);
|
||||
|
||||
for (int i = 0; i < RTL839X_CPU_PORT; i++) {
|
||||
if (ports & BIT_ULL(i)) {
|
||||
link = rtl839x_get_port_reg_le(RTL839X_MAC_LINK_STS);
|
||||
if (link & BIT_ULL(i))
|
||||
dsa_port_phylink_mac_change(ds, i, true);
|
||||
else
|
||||
dsa_port_phylink_mac_change(ds, i, false);
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void
|
||||
rtldsa_839x_vlan_profile_dump(struct rtl838x_switch_priv *priv, int idx)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -159,23 +159,18 @@ int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate
|
|||
|
||||
/* RTL838x-specific */
|
||||
u32 rtl838x_hash(struct rtl838x_switch_priv *priv, u64 seed);
|
||||
irqreturn_t rtl838x_switch_irq(int irq, void *dev_id);
|
||||
void rtldsa_838x_print_matrix(void);
|
||||
|
||||
/* RTL839x-specific */
|
||||
u32 rtl839x_hash(struct rtl838x_switch_priv *priv, u64 seed);
|
||||
irqreturn_t rtl839x_switch_irq(int irq, void *dev_id);
|
||||
void rtl839x_exec_tbl2_cmd(u32 cmd);
|
||||
void rtldsa_839x_print_matrix(void);
|
||||
|
||||
/* RTL930x-specific */
|
||||
u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed);
|
||||
irqreturn_t rtldsa_930x_switch_irq(int irq, void *dev_id);
|
||||
irqreturn_t rtl839x_switch_irq(int irq, void *dev_id);
|
||||
void rtldsa_930x_print_matrix(void);
|
||||
|
||||
/* RTL931x-specific */
|
||||
irqreturn_t rtl931x_switch_irq(int irq, void *dev_id);
|
||||
void rtldsa_931x_print_matrix(void);
|
||||
|
||||
int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info);
|
||||
|
|
|
|||
|
|
@ -1112,29 +1112,6 @@ void rtl9300_dump_debug(void)
|
|||
);
|
||||
}
|
||||
|
||||
irqreturn_t rtldsa_930x_switch_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct dsa_switch *ds = dev_id;
|
||||
struct rtl838x_switch_priv *priv = ds->priv;
|
||||
unsigned long ports = sw_r32(RTL930X_ISR_PORT_LINK_STS_CHG);
|
||||
unsigned int i;
|
||||
u32 link;
|
||||
|
||||
/* Clear status */
|
||||
sw_w32(ports, RTL930X_ISR_PORT_LINK_STS_CHG);
|
||||
|
||||
/* Read the register twice because of issues with latency at least
|
||||
* with the external RTL8226 PHY on the XGS1210
|
||||
*/
|
||||
link = sw_r32(RTL930X_MAC_LINK_STS);
|
||||
link = sw_r32(RTL930X_MAC_LINK_STS);
|
||||
|
||||
for_each_set_bit(i, &ports, priv->cpu_port)
|
||||
dsa_port_phylink_mac_change(ds, i, link & BIT(i));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Calculate both the block 0 and the block 1 hash, and return in
|
||||
* lower and higher word of the return value since only 12 bit of
|
||||
* the hash are significant
|
||||
|
|
|
|||
|
|
@ -462,37 +462,6 @@ static int rtldsa_931x_port_rate_police_del(struct dsa_switch *ds, int port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
irqreturn_t rtl931x_switch_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct dsa_switch *ds = dev_id;
|
||||
u32 status = sw_r32(RTL931X_ISR_GLB_SRC);
|
||||
u64 ports = rtl839x_get_port_reg_le(RTL931X_ISR_PORT_LINK_STS_CHG);
|
||||
u64 link;
|
||||
|
||||
/* Clear status */
|
||||
rtl839x_set_port_reg_le(ports, RTL931X_ISR_PORT_LINK_STS_CHG);
|
||||
pr_debug("RTL931X Link change: status: %x, ports %016llx\n", status, ports);
|
||||
|
||||
link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS);
|
||||
/* Must re-read this to get correct status */
|
||||
link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS);
|
||||
pr_debug("RTL931X Link change: status: %x, link status %016llx\n", status, link);
|
||||
|
||||
for (int i = 0; i < 56; i++) {
|
||||
if (ports & BIT_ULL(i)) {
|
||||
if (link & BIT_ULL(i)) {
|
||||
pr_debug("%s port %d up\n", __func__, i);
|
||||
dsa_port_phylink_mac_change(ds, i, true);
|
||||
} else {
|
||||
pr_debug("%s port %d down\n", __func__, i);
|
||||
dsa_port_phylink_mac_change(ds, i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void rtldsa_931x_print_matrix(void)
|
||||
{
|
||||
struct table_reg *r = rtl_table_get(RTL9310_TBL_2, 1);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue