Commit 619812c1 authored by Josua Mayer's avatar Josua Mayer

linux: fix dpdk support

- add back support for original 10.28.100 FW supporting online dpmac
  protocol change
- ensure serdes phy is always enabled as workaround for dpdk link-up
- backport a slightly suspicious tweak for bqman from NXP LF-6.1 release
parent 6650ab53
From 9f9ff122580a3cc0b669e00d2f349e82293e889f Mon Sep 17 00:00:00 2001
From: Josua Mayer <josua@solid-run.com>
Date: Sat, 13 May 2023 16:51:21 +0300
Subject: [PATCH] net: dpaa2: support changing dpmac protocol with FW 10.28.100
10.28.100 was the first PoC NXP had released for changing the dpmac
protocol at runtime between 1 & 10 Gbps.
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
.../net/ethernet/freescale/dpaa2/dpaa2-mac.c | 45 ++++++++++++++++---
.../net/ethernet/freescale/dpaa2/dpaa2-mac.h | 1 +
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index a4aad5431e82..5ca5fdc7eb8a 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -30,11 +30,25 @@ static int dpaa2_mac_cmp_ver(struct dpaa2_mac *mac,
static void dpaa2_mac_detect_features(struct dpaa2_mac *mac)
{
+ struct fsl_mc_version *fw_vers;
+ unsigned long if_mode_addr;
+
mac->features = 0;
if (dpaa2_mac_cmp_ver(mac, DPMAC_PROTOCOL_CHANGE_VER_MAJOR,
DPMAC_PROTOCOL_CHANGE_VER_MINOR) >= 0)
mac->features |= DPAA2_MAC_FEATURE_PROTOCOL_CHANGE;
+
+
+ fw_vers = fsl_mc_get_version();
+ if (fw_vers->major == 10 && fw_vers->minor == 28 && fw_vers->revision == 100) {
+ if_mode_addr = 0x8c07080 + 0x4000 * (mac->mc_dev->obj_desc.id - 1);
+ mac->if_mode_reg = ioremap(if_mode_addr, 4);
+ if (!mac->if_mode_reg)
+ netdev_err(mac->net_dev, "ioremap on if_mode failed\n");
+ else
+ mac->features |= DPAA2_MAC_FEATURE_PROTOCOL_CHANGE;
+ }
}
static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)
@@ -267,6 +281,7 @@ static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
struct dpmac_link_state *dpmac_state = &mac->state;
int err;
int i;
+ u32 val;
if (state->an_enabled)
dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
@@ -282,11 +297,31 @@ static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
if (!mac->serdes_phy)
return;
- /* This happens only if we support changing of protocol at runtime */
- err = dpmac_set_protocol(mac->mc_io, 0, mac->mc_dev->mc_handle,
- dpmac_eth_if_mode(state->interface));
- if (err)
- netdev_err(mac->net_dev, "dpmac_set_protocol() = %d\n", err);
+ if (mac->if_mode_reg) {
+ val = ioread32(mac->if_mode_reg);
+ val &= ~0x3;
+ switch (state->interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ val |= 0x3;
+ fallthrough;
+ case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_USXGMII:
+ val |= 0x1;
+ iowrite32(val, mac->if_mode_reg);
+ break;
+ default:
+ netdev_err(mac->net_dev, "%s: unhandled link mode %i, expect rx/tx errors!\n", __func__, state->interface);
+ }
+ } else {
+ /* This happens only if we support changing of protocol at runtime */
+ err = dpmac_set_protocol(mac->mc_io, 0, mac->mc_dev->mc_handle,
+ dpmac_eth_if_mode(state->interface));
+ if (err)
+ netdev_err(mac->net_dev, "dpmac_set_protocol() = %d\n", err);
+ }
err = phy_set_mode_ext(mac->serdes_phy, PHY_MODE_ETHERNET, state->interface);
if (err)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
index 0bc767248f6c..dd9fd02b96b8 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
@@ -28,6 +28,7 @@ struct dpaa2_mac {
enum dpmac_link_type if_link_type;
struct lynx_pcs *pcs;
struct fwnode_handle *fw_node;
+ void __iomem *if_mode_reg;
struct phy *serdes_phy;
struct phy *retimer_phys[2];
--
2.35.3
From 374083918c5220f01ab6c1324516f471e73ff398 Mon Sep 17 00:00:00 2001
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Date: Tue, 24 May 2022 15:07:31 +0300
Subject: [PATCH 71/72] dpaa2-eth: increase busy retries when interracting with
QBMAN
It seems that there are circumstances when access to QBMAN through the
software portals will be delayed. Accessing some lower speeds interfaces
while also QBMAN commands are issued from the kernel will lead to
software timeouts happening in the dpaa2-eth driver.
What we have observed is that management commands like re-arming the
interrupts on a specific channel, waiting for a dequeue response to be
available etc, will take a longer time to complete.
All these commands have to wait for a valid bit to be set for the
command to be interpreted as successfully completed.
Increase the maximum number of times the Linux kernel drivers will busy
poll for a successful result of one of these commands.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 2 +-
drivers/soc/fsl/dpio/qbman-portal.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index dbfd9c60b9da..5ccefdd020d9 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -347,7 +347,7 @@ static inline struct dpaa2_faead *dpaa2_get_faead(void *buf_addr, bool swa)
* hardware becomes unresponsive, but not give up too easily if
* the portal really is busy for valid reasons
*/
-#define DPAA2_ETH_SWP_BUSY_RETRIES 1000
+#define DPAA2_ETH_SWP_BUSY_RETRIES 10000
/* Driver statistics, other than those in struct rtnl_link_stats64.
* These are usually collected per-CPU and aggregated by ethtool.
diff --git a/drivers/soc/fsl/dpio/qbman-portal.h b/drivers/soc/fsl/dpio/qbman-portal.h
index b6b79e3bb526..0370be1de533 100644
--- a/drivers/soc/fsl/dpio/qbman-portal.h
+++ b/drivers/soc/fsl/dpio/qbman-portal.h
@@ -536,7 +536,7 @@ static inline int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s,
static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
u8 cmd_verb)
{
- int loopvar = 2000;
+ int loopvar = 10000;
qbman_swp_mc_submit(swp, cmd, cmd_verb);
--
2.35.3
From ea0b7fa03ee483a97e22c8219fc01cfd04b424af Mon Sep 17 00:00:00 2001
From: Josua Mayer <josua@solid-run.com>
Date: Sat, 13 May 2023 17:50:48 +0300
Subject: [PATCH 72/72] [HACK] net: dpaa2: never power-off serdes phy
When network interfaces are bound to DPDK rather than the Linux kernel,
it has been observed that the serdes phy is powered off, and never
powered on again.
As a workaround replace all occurencs of phy_power_off with phy_power_on,
and re-add prepare and finish callbacks to power on serdes.
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
.../net/ethernet/freescale/dpaa2/dpaa2-mac.c | 28 ++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index baf7dfbba079..295c62b6ba21 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -394,11 +394,37 @@ static void dpaa2_mac_link_down(struct phylink_config *config,
led_set_brightness(mac->link_status_led, LED_OFF);
}
+static int dpaa2_mac_prepare(struct phylink_config *config, unsigned int mode,
+ phy_interface_t interface)
+{
+ struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
+
+ dpaa2_mac_link_down(config, mode, interface);
+
+ if (mac->serdes_phy)
+ phy_power_on(mac->serdes_phy);
+
+ return 0;
+}
+
+static int dpaa2_mac_finish(struct phylink_config *config, unsigned int mode,
+ phy_interface_t interface)
+{
+ struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
+
+ if (mac->serdes_phy)
+ phy_power_on(mac->serdes_phy);
+
+ return 0;
+}
+
static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
.validate = dpaa2_mac_validate,
.mac_config = dpaa2_mac_config,
.mac_link_up = dpaa2_mac_link_up,
.mac_link_down = dpaa2_mac_link_down,
+ .mac_prepare = dpaa2_mac_prepare,
+ .mac_finish = dpaa2_mac_finish,
};
static int dpaa2_pcs_create(struct dpaa2_mac *mac,
@@ -457,7 +483,7 @@ void dpaa2_mac_start(struct dpaa2_mac *mac)
void dpaa2_mac_stop(struct dpaa2_mac *mac)
{
if (mac->serdes_phy)
- phy_power_off(mac->serdes_phy);
+ phy_power_on(mac->serdes_phy);
}
int dpaa2_mac_connect(struct dpaa2_mac *mac)
--
2.35.3
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment