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
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 */
.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;
-}
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)
{
/* 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);
);
}
-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
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);