]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: eth: provide device specific hw_stop() helper
authorMarkus Stockhausen <markus.stockhausen@gmx.de>
Sat, 14 Mar 2026 12:33:33 +0000 (13:33 +0100)
committerRobert Marko <robimarko@gmail.com>
Wed, 25 Mar 2026 09:26:44 +0000 (10:26 +0100)
The hw_stop() function uses multiple family checks to determine
what needs to be done. Split that into device specific helpers
to simplify the code.

For further simplification common parts of the stop functions
have been kept in rteth_hw_stop().

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22421
Signed-off-by: Robert Marko <robimarko@gmail.com>
target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.c
target/linux/realtek/files-6.12/drivers/net/ethernet/rtl838x_eth.h

index b62a341b256775ce87188b093001a37db0d1f380..38dba61de0fc67bdaa3df12a67e1c0c512ddc847 100644 (file)
@@ -731,47 +731,64 @@ static int rteth_open(struct net_device *ndev)
        return 0;
 }
 
-static void rteth_hw_stop(struct rteth_ctrl *ctrl)
+static void rteth_838x_hw_stop(struct rteth_ctrl *ctrl)
 {
-       u32 force_mac = ctrl->r->family_id == RTL8380_FAMILY_ID ? 0x6192C : 0x75;
+       /* Block all ports */
+       sw_w32(0x03000000, RTL838X_TBL_ACCESS_DATA_0(0));
+       sw_w32(0x00000000, RTL838X_TBL_ACCESS_DATA_0(1));
+       sw_w32(1 << 15 | 2 << 12, RTL838X_TBL_ACCESS_CTRL_0);
 
-       /* Disable RX/TX from/to CPU-port */
-       sw_w32_mask(0x3, 0, ctrl->r->mac_l2_port_ctrl);
+       /* Disable FAST_AGE_OUT otherwise flush will hang */
+       sw_w32_mask(BIT(23), 0, RTL838X_L2_CTRL_1);
 
-       /* Disable traffic */
-       sw_w32_mask(ctrl->r->tx_rx_enable, 0, ctrl->r->dma_if_ctrl);
-       mdelay(200); /* Test, whether this is needed */
-
-       /* Block all ports */
-       if (ctrl->r->family_id == RTL8380_FAMILY_ID) {
-               sw_w32(0x03000000, RTL838X_TBL_ACCESS_DATA_0(0));
-               sw_w32(0x00000000, RTL838X_TBL_ACCESS_DATA_0(1));
-               sw_w32(1 << 15 | 2 << 12, RTL838X_TBL_ACCESS_CTRL_0);
+       /* Flush L2 address cache */
+       for (int i = 0; i <= ctrl->r->cpu_port; i++) {
+               sw_w32(BIT(26) | BIT(23) | i << 5, ctrl->r->l2_tbl_flush_ctrl);
+               do { } while (sw_r32(ctrl->r->l2_tbl_flush_ctrl) & BIT(26));
        }
 
+       /* CPU-Port: Link down */
+       sw_w32(0x6192C, ctrl->r->mac_force_mode_ctrl);
+}
+
+static void rteth_839x_hw_stop(struct rteth_ctrl *ctrl)
+{
        /* Flush L2 address cache */
-       if (ctrl->r->family_id == RTL8380_FAMILY_ID) {
-               /* Disable FAST_AGE_OUT otherwise flush will hang */
-               sw_w32_mask(BIT(23), 0, RTL838X_L2_CTRL_1);
-               for (int i = 0; i <= ctrl->r->cpu_port; i++) {
-                       sw_w32(BIT(26) | BIT(23) | i << 5, ctrl->r->l2_tbl_flush_ctrl);
-                       do { } while (sw_r32(ctrl->r->l2_tbl_flush_ctrl) & BIT(26));
-               }
-       } else if (ctrl->r->family_id == RTL8390_FAMILY_ID) {
-               for (int i = 0; i <= ctrl->r->cpu_port; i++) {
-                       sw_w32(BIT(28) | BIT(25) | i << 5, ctrl->r->l2_tbl_flush_ctrl);
-                       do { } while (sw_r32(ctrl->r->l2_tbl_flush_ctrl) & BIT(28));
-               }
+       for (int i = 0; i <= ctrl->r->cpu_port; i++) {
+               sw_w32(BIT(28) | BIT(25) | i << 5, ctrl->r->l2_tbl_flush_ctrl);
+               do { } while (sw_r32(ctrl->r->l2_tbl_flush_ctrl) & BIT(28));
        }
-       /* TODO: L2 flush register is 64 bit on RTL931X and 930X */
+
+       sw_w32(0x75, ctrl->r->mac_force_mode_ctrl);
+}
+
+static void rteth_930x_hw_stop(struct rteth_ctrl *ctrl)
+{
+       /* TODO: L2 flush needed */
 
        /* CPU-Port: Link down */
-       if (ctrl->r->family_id == RTL8380_FAMILY_ID || ctrl->r->family_id == RTL8390_FAMILY_ID)
-               sw_w32(force_mac, ctrl->r->mac_force_mode_ctrl);
-       else if (ctrl->r->family_id == RTL9300_FAMILY_ID)
-               sw_w32_mask(0x3, 0, ctrl->r->mac_force_mode_ctrl);
-       else if (ctrl->r->family_id == RTL9310_FAMILY_ID)
-               sw_w32_mask(BIT(0) | BIT(9), 0, ctrl->r->mac_force_mode_ctrl);
+       sw_w32_mask(0x3, 0, ctrl->r->mac_force_mode_ctrl);
+}
+
+static void rteth_931x_hw_stop(struct rteth_ctrl *ctrl)
+{
+       /* TODO: L2 flush needed */
+
+       /* CPU-Port: Link down */
+       sw_w32_mask(BIT(0) | BIT(9), 0, ctrl->r->mac_force_mode_ctrl);
+}
+
+static void rteth_hw_stop(struct rteth_ctrl *ctrl)
+{
+       /* Disable RX/TX from/to CPU-port */
+       sw_w32_mask(0x3, 0, ctrl->r->mac_l2_port_ctrl);
+
+       /* Disable traffic */
+       sw_w32_mask(ctrl->r->tx_rx_enable, 0, ctrl->r->dma_if_ctrl);
+       mdelay(200); /* Test, whether this is needed */
+
+       /* family specific stop */
+       ctrl->r->hw_stop(ctrl);
        mdelay(100);
 
        rteth_disable_all_irqs(ctrl);
@@ -1305,6 +1322,7 @@ static const struct rteth_config rteth_838x_cfg = {
        .update_counter = rteth_83xx_update_counter,
        .create_tx_header = rteth_838x_create_tx_header,
        .decode_tag = rteth_838x_decode_tag,
+       .hw_stop = &rteth_838x_hw_stop,
        .hw_reset = &rteth_838x_hw_reset,
        .init_mac = &rteth_838x_init_mac,
        .netdev_ops = &rteth_838x_netdev_ops,
@@ -1347,6 +1365,7 @@ static const struct rteth_config rteth_839x_cfg = {
        .update_counter = rteth_83xx_update_counter,
        .create_tx_header = rteth_839x_create_tx_header,
        .decode_tag = rteth_839x_decode_tag,
+       .hw_stop = &rteth_839x_hw_stop,
        .hw_reset = &rteth_839x_hw_reset,
        .init_mac = &rteth_839x_init_mac,
        .netdev_ops = &rteth_839x_netdev_ops,
@@ -1390,6 +1409,7 @@ static const struct rteth_config rteth_930x_cfg = {
        .update_counter = rteth_93xx_update_counter,
        .create_tx_header = rteth_93xx_create_tx_header,
        .decode_tag = rteth_930x_decode_tag,
+       .hw_stop = &rteth_930x_hw_stop,
        .hw_reset = &rteth_93xx_hw_reset,
        .init_mac = &rteth_930x_init_mac,
        .netdev_ops = &rteth_930x_netdev_ops,
@@ -1433,6 +1453,7 @@ static const struct rteth_config rteth_931x_cfg = {
        .update_counter = rteth_93xx_update_counter,
        .create_tx_header = rteth_93xx_create_tx_header,
        .decode_tag = rteth_931x_decode_tag,
+       .hw_stop = &rteth_931x_hw_stop,
        .hw_reset = &rteth_93xx_hw_reset,
        .init_mac = &rteth_931x_init_mac,
        .netdev_ops = &rteth_931x_netdev_ops,
index ea6ccddea7c56a63c02db5b5a0cac2907d53b945..7c66b2892b18273f0796b2c937ffafa181292cbc 100644 (file)
@@ -263,6 +263,7 @@ struct rteth_config {
        int l2_tbl_flush_ctrl;
        void (*create_tx_header)(struct rteth_packet *h, unsigned int dest_port, int prio);
        bool (*decode_tag)(struct rteth_packet *h, struct dsa_tag *tag);
+       void (*hw_stop)(struct rteth_ctrl *ctrl);
        void (*hw_reset)(struct rteth_ctrl *ctrl);
        int (*init_mac)(struct rteth_ctrl *ctrl);
        void (*update_counter)(struct rteth_ctrl *ctrl, int ring, int released);