include $(TOPDIR)/rules.mk
PKG_NAME:=qca-nss-dp
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git
PKG_SOURCE_PROTO:=git
--- /dev/null
+From c318c90b824c59539bf2e33618e381293398616c Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 16 Apr 2024 15:02:49 +0200
+Subject: [PATCH 1/6] edma_v1: rework hw_reset logic to permit rmmod and insmod
+
+Rework hw_reset logic for edma v1 to permit rmmod and insmod by using
+get_exclusive_released variant (assuming the reset control was released)
+and manually acquire and release it.
+
+This permits rmmod and insmod without triggering warning or receiving
+-EBUSY errors.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ hal/dp_ops/edma_dp/edma_v1/edma_cfg.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/hal/dp_ops/edma_dp/edma_v1/edma_cfg.c
++++ b/hal/dp_ops/edma_dp/edma_v1/edma_cfg.c
+@@ -719,18 +719,22 @@ int edma_hw_reset(struct edma_hw *ehw)
+ struct reset_control *rst;
+ struct platform_device *pdev = ehw->pdev;
+
+- rst = devm_reset_control_get(&pdev->dev, EDMA_HW_RESET_ID);
++ rst = devm_reset_control_get_exclusive_released(&pdev->dev, EDMA_HW_RESET_ID);
+ if (IS_ERR(rst)) {
+ pr_warn("DTS Node: %s does not exist\n", EDMA_HW_RESET_ID);
+ return -EINVAL;
+ }
+
++ reset_control_acquire(rst);
++
+ reset_control_assert(rst);
+ udelay(100);
+
+ reset_control_deassert(rst);
+ udelay(100);
+
++ reset_control_release(rst);
++
+ pr_info("EDMA HW Reset completed succesfully\n");
+
+ return 0;
--- /dev/null
+From 079bfe441b274a8c06474be82e4ccc88599a5e0e Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 16 Apr 2024 16:08:46 +0200
+Subject: [PATCH 2/6] nss_dp_switchdev: correctly unregister notifier on
+ dp_remove
+
+Correctly unregister notifier on dp_remove to fix kernel panic on system
+reboot.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ include/nss_dp_dev.h | 1 +
+ nss_dp_main.c | 4 ++++
+ nss_dp_switchdev.c | 13 +++++++++++++
+ 3 files changed, 18 insertions(+)
+
+--- a/include/nss_dp_dev.h
++++ b/include/nss_dp_dev.h
+@@ -312,6 +312,7 @@ void nss_dp_set_ethtool_ops(struct net_d
+ */
+ #ifdef CONFIG_NET_SWITCHDEV
+ void nss_dp_switchdev_setup(struct net_device *dev);
++void nss_dp_switchdev_remove(struct net_device *dev);
+ bool nss_dp_is_phy_dev(struct net_device *dev);
+ #endif
+
+--- a/nss_dp_main.c
++++ b/nss_dp_main.c
+@@ -913,6 +913,10 @@ static int nss_dp_remove(struct platform
+ if (!dp_priv)
+ continue;
+
++ #ifdef CONFIG_NET_SWITCHDEV
++ nss_dp_switchdev_remove(dp_priv->netdev);
++ #endif
++
+ dp_ops = dp_priv->data_plane_ops;
+ hal_ops = dp_priv->gmac_hal_ops;
+
+--- a/nss_dp_switchdev.c
++++ b/nss_dp_switchdev.c
+@@ -635,4 +635,17 @@ void nss_dp_switchdev_setup(struct net_d
+
+ switch_init_done = true;
+ }
++
++void nss_dp_switchdev_remove(struct net_device *dev)
++{
++ if (!switch_init_done)
++ return;
++
++ if (nss_dp_sw_ev_nb)
++ unregister_switchdev_notifier(nss_dp_sw_ev_nb);
++
++ unregister_switchdev_blocking_notifier(&nss_dp_switchdev_notifier);
++
++ switch_init_done = false;
++}
+ #endif
--- /dev/null
+From ab7b1a361d51157118e1a61ce6530a59bcef4b61 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 16 Apr 2024 16:10:09 +0200
+Subject: [PATCH 3/6] nss_dp_main: swap dp_exit function call
+
+First unregister nss_dp platform devices then cleanup the HAL.
+
+This is to fix kernel panic by cleaning data that needs to be used by
+platform driver unregister functions.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ nss_dp_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/nss_dp_main.c
++++ b/nss_dp_main.c
+@@ -1082,6 +1082,8 @@ int __init nss_dp_init(void)
+ */
+ void __exit nss_dp_exit(void)
+ {
++ platform_driver_unregister(&nss_dp_drv);
++
+ /*
+ * TODO Move this to soc_ops
+ */
+@@ -1089,8 +1091,6 @@ void __exit nss_dp_exit(void)
+ nss_dp_hal_cleanup();
+ dp_global_ctx.common_init_done = false;
+ }
+-
+- platform_driver_unregister(&nss_dp_drv);
+ }
+
+ module_init(nss_dp_init);
--- /dev/null
+From 33dd3aa6d0f9cd240d63f53a49157ae44ebccf87 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 16 Apr 2024 16:12:11 +0200
+Subject: [PATCH 4/6] nss_dp_main: call unregister_netdev first in dp_remove
+ and carrifer_off
+
+In dp_remove move unregister_netdev up before calling exit and deinit
+and first call netif_carrier_off to stop any traffic from happening and
+prevent kernel panics for napi in the middle of transfer.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ nss_dp_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/nss_dp_main.c
++++ b/nss_dp_main.c
+@@ -920,6 +920,9 @@ static int nss_dp_remove(struct platform
+ dp_ops = dp_priv->data_plane_ops;
+ hal_ops = dp_priv->gmac_hal_ops;
+
++ netif_carrier_off(dp_priv->netdev);
++ unregister_netdev(dp_priv->netdev);
++
+ if (dp_priv->phydev)
+ phy_disconnect(dp_priv->phydev);
+
+@@ -931,7 +934,6 @@ static int nss_dp_remove(struct platform
+ #endif
+ hal_ops->exit(dp_priv->gmac_hal_ctx);
+ dp_ops->deinit(dp_priv->dpc);
+- unregister_netdev(dp_priv->netdev);
+ free_netdev(dp_priv->netdev);
+ dp_global_ctx.nss_dp[i] = NULL;
+ }
--- /dev/null
+From 655b07b701271bc00952fe64aeb14f993a48a50e Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 16 Apr 2024 16:17:36 +0200
+Subject: [PATCH 5/6] nss_dp_main: use phy_detach instead of disconnect in
+ dp_remove
+
+Use phy_detach instead of disconnect in dp_remove. On Module remove, phy
+are already disconnected but they need to be detached to be correctly
+reattached later with an insmod.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ nss_dp_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/nss_dp_main.c
++++ b/nss_dp_main.c
+@@ -924,7 +924,7 @@ static int nss_dp_remove(struct platform
+ unregister_netdev(dp_priv->netdev);
+
+ if (dp_priv->phydev)
+- phy_disconnect(dp_priv->phydev);
++ phy_detach(dp_priv->phydev);
+
+ #if defined(NSS_DP_PPE_SUPPORT)
+ /*
--- /dev/null
+From c7c59c6097d94dbab8fc68dae798017bdbc5b3b9 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 16 Apr 2024 16:22:32 +0200
+Subject: [PATCH 6/6] edma_v1: skip edma_disable_port in edma_cleanup
+ subsequent run
+
+Skip edma_disable_port in edma_cleanup subsequent run as it will cause
+the kernel panic as the regs are already freed by previous run of
+edma_cleanup. It's use it's not clear but the call is already done in
+the first run of edma_cleanup. Maybe an oversight never dropped?
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
++++ b/hal/dp_ops/edma_dp/edma_v1/edma_data_plane.c
+@@ -326,9 +326,15 @@ void edma_cleanup(bool is_dp_override)
+ * Disable EDMA only at module exit time, since NSS firmware
+ * depends on this setting.
+ */
+- if (!is_dp_override) {
+- edma_disable_port();
+- }
++ /* This call will make the kernel panic as reg used by
++ * edma_disable_port are already freed by previous call of
++ * edma_cleanup. Logic is not clear of WHY this is called.
++ * Keep this here for reference if someone EVER wants
++ * to investigate.
++ */
++ // if (!is_dp_override) {
++ // edma_disable_port();
++ // }
+ return;
+ }
+