]> www.infradead.org Git - users/griffoul/linux.git/commitdiff
net: ti: icssg-prueth: Fix HSR and switch offload Enablement during firwmare reload.
authorMD Danish Anwar <danishanwar@ti.com>
Thu, 14 Aug 2025 10:51:06 +0000 (16:21 +0530)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 19 Aug 2025 10:26:18 +0000 (12:26 +0200)
To enable HSR / Switch offload, certain configurations are needed.
Currently they are done inside icssg_change_mode(). This function only
gets called if we move from one mode to another without bringing the
links up / down.

Once in HSR / Switch mode, if we bring the links down and bring it back
up again. The callback sequence is,

- emac_ndo_stop()
Firmwares are stopped
- emac_ndo_open()
Firmwares are loaded

In this path icssg_change_mode() doesn't get called and as a result the
configurations needed for HSR / Switch is not done.

To fix this, put all these configurations in a separate function
icssg_enable_fw_offload() and call this from both icssg_change_mode()
and emac_ndo_open()

Fixes: 56375086d093 ("net: ti: icssg-prueth: Enable HSR Tx duplication, Tx Tag and Rx Tag offload")
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Link: https://patch.msgid.link/20250814105106.1491871-1-danishanwar@ti.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/ti/icssg/icssg_prueth.c

index 6c7d776ae4eed76d191f91e02bed1ba750106573..dadce6009791bc71402c99c1b8112f191276f335 100644 (file)
@@ -203,6 +203,44 @@ static void prueth_emac_stop(struct prueth *prueth)
        }
 }
 
+static void icssg_enable_fw_offload(struct prueth *prueth)
+{
+       struct prueth_emac *emac;
+       int mac;
+
+       for (mac = PRUETH_MAC0; mac < PRUETH_NUM_MACS; mac++) {
+               emac = prueth->emac[mac];
+               if (prueth->is_hsr_offload_mode) {
+                       if (emac->ndev->features & NETIF_F_HW_HSR_TAG_RM)
+                               icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE);
+                       else
+                               icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_DISABLE);
+               }
+
+               if (prueth->is_switch_mode || prueth->is_hsr_offload_mode) {
+                       if (netif_running(emac->ndev)) {
+                               icssg_fdb_add_del(emac, eth_stp_addr, prueth->default_vlan,
+                                                 ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
+                                                 ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
+                                                 ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
+                                                 ICSSG_FDB_ENTRY_BLOCK,
+                                                 true);
+                               icssg_vtbl_modify(emac, emac->port_vlan | DEFAULT_VID,
+                                                 BIT(emac->port_id) | DEFAULT_PORT_MASK,
+                                                 BIT(emac->port_id) | DEFAULT_UNTAG_MASK,
+                                                 true);
+                               if (prueth->is_hsr_offload_mode)
+                                       icssg_vtbl_modify(emac, DEFAULT_VID,
+                                                         DEFAULT_PORT_MASK,
+                                                         DEFAULT_UNTAG_MASK, true);
+                               icssg_set_pvid(prueth, emac->port_vlan, emac->port_id);
+                               if (prueth->is_switch_mode)
+                                       icssg_set_port_state(emac, ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE);
+                       }
+               }
+       }
+}
+
 static int prueth_emac_common_start(struct prueth *prueth)
 {
        struct prueth_emac *emac;
@@ -753,6 +791,7 @@ static int emac_ndo_open(struct net_device *ndev)
                ret = prueth_emac_common_start(prueth);
                if (ret)
                        goto free_rx_irq;
+               icssg_enable_fw_offload(prueth);
        }
 
        flow_cfg = emac->dram.va + ICSSG_CONFIG_OFFSET + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
@@ -1360,8 +1399,7 @@ static int prueth_emac_restart(struct prueth *prueth)
 
 static void icssg_change_mode(struct prueth *prueth)
 {
-       struct prueth_emac *emac;
-       int mac, ret;
+       int ret;
 
        ret = prueth_emac_restart(prueth);
        if (ret) {
@@ -1369,35 +1407,7 @@ static void icssg_change_mode(struct prueth *prueth)
                return;
        }
 
-       for (mac = PRUETH_MAC0; mac < PRUETH_NUM_MACS; mac++) {
-               emac = prueth->emac[mac];
-               if (prueth->is_hsr_offload_mode) {
-                       if (emac->ndev->features & NETIF_F_HW_HSR_TAG_RM)
-                               icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE);
-                       else
-                               icssg_set_port_state(emac, ICSSG_EMAC_HSR_RX_OFFLOAD_DISABLE);
-               }
-
-               if (netif_running(emac->ndev)) {
-                       icssg_fdb_add_del(emac, eth_stp_addr, prueth->default_vlan,
-                                         ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
-                                         ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
-                                         ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
-                                         ICSSG_FDB_ENTRY_BLOCK,
-                                         true);
-                       icssg_vtbl_modify(emac, emac->port_vlan | DEFAULT_VID,
-                                         BIT(emac->port_id) | DEFAULT_PORT_MASK,
-                                         BIT(emac->port_id) | DEFAULT_UNTAG_MASK,
-                                         true);
-                       if (prueth->is_hsr_offload_mode)
-                               icssg_vtbl_modify(emac, DEFAULT_VID,
-                                                 DEFAULT_PORT_MASK,
-                                                 DEFAULT_UNTAG_MASK, true);
-                       icssg_set_pvid(prueth, emac->port_vlan, emac->port_id);
-                       if (prueth->is_switch_mode)
-                               icssg_set_port_state(emac, ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE);
-               }
-       }
+       icssg_enable_fw_offload(prueth);
 }
 
 static int prueth_netdevice_port_link(struct net_device *ndev,