Skip to content

Commit a4446c2

Browse files
authored
recipes-kernel: add the qps615 ethernet driver (#1698)
Add support for the QPS615 Ethernet out of tree DLKM by introducing a new recipes-connectivity/qps615 recipe along with the required driver and firmware patches. The recipe pulls the Toshiba QPS615 driver and firmware sources and applies Qualcomm‑specific extensions and compatibility fixes to enable QPS615 on Qualcomm platforms. The QPS615 hardware implementation on Qualcomm boards requires platform specific logic to deal with PHY regulators, SoC GPIOs, WoL IRQs, NVMEM. For that, the following patches have been introduced: 1. Patch 1: Introduce tc956x_qcom.c to deal with platform level logic specific to Qualcomm boards. Without it, the base driver is unable to control the PHY regulators, or deal with SoC GPIOs and interrupts. 2. Patch 2: Updates the Makefile so that Yocto/OE and other cross-build environments can override the kernel build tree. 3. Patch 3: Adds support for retrieving the MAC address from the board's EEPROM (if available). The base driver has no way of fetching the MAC address from NVMEM, but Qualcomm boards (specifically IQ8 and IQ9) have a dedicated EEPROM chip for storing factory flashed MAC addresses for each of the interfaces. 4. Patch 4: Driver upgrade to support Kernel 6.18. The original driver does not compile for any Kernel higher than 6.6. This patch resolves the compilation errors while maintaining the original functionality. 5. Patch 5: Add a module table entry so that udev can autoload the driver. **Exception details:** Until the QPS615 driver is upstreamed (third party ETA: end of 2026), an exception has been approved to include the driver as an out of tree DLKM (QLIJIRA-99).
2 parents c9ec8f9 + 437df45 commit a4446c2

14 files changed

Lines changed: 1315 additions & 0 deletions
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
From e474ec61bdd6064f9c826a7d3162adc4e7f169bc Mon Sep 17 00:00:00 2001
2+
From: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
3+
Date: Mon, 30 Mar 2026 01:24:25 +0530
4+
Subject: [PATCH 01/12] net: ethernet: tc956x: Makefile: support cross-build
5+
via KERNEL_SRC
6+
7+
Replace the hardcoded 'all:' and 'clean:' targets with conventional
8+
'modules', 'modules_install', and 'clean' targets that delegate to
9+
$(MAKE) instead of bare make. Introduce KERNEL_SRC with a ?= default
10+
so that Yocto/OE and other cross-build environments can override the
11+
kernel build tree without editing the file, while native development
12+
builds continue to fall back to /lib/modules/$(uname -r)/build.
13+
14+
Upstream-Status: Submitted [https://github.com/TC956X/TC9564_Host_Driver/pull/2]
15+
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
16+
---
17+
drivers/net/ethernet/toshiba/tc956x/Makefile | 13 ++++++++++---
18+
1 file changed, 10 insertions(+), 3 deletions(-)
19+
20+
diff --git a/drivers/net/ethernet/toshiba/tc956x/Makefile b/drivers/net/ethernet/toshiba/tc956x/Makefile
21+
index 908c52b..d6279c1 100644
22+
--- a/drivers/net/ethernet/toshiba/tc956x/Makefile
23+
+++ b/drivers/net/ethernet/toshiba/tc956x/Makefile
24+
@@ -81,8 +81,15 @@ endif
25+
endif
26+
ccflags-y := -Wmissing-prototypes
27+
28+
-all:
29+
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
30+
+# Allow KERNEL_SRC to be set externally (e.g. by Yocto/OE); fall back to
31+
+# the running kernel's build tree for native development builds.
32+
+KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
33+
+
34+
+modules:
35+
+ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules
36+
+
37+
+modules_install:
38+
+ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules_install
39+
40+
clean:
41+
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
42+
+ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
43+
--
44+
2.34.1
45+
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
From 1d10902d43db9320fa51dfeef24ab0672950c56f Mon Sep 17 00:00:00 2001
2+
From: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
3+
Date: Mon, 30 Mar 2026 01:24:43 +0530
4+
Subject: [PATCH 02/12] net: ethernet: tc956x: read MAC address from DT/NVMEM
5+
on platform
6+
7+
Attempt to read the MAC address from the device tree or NVMEM via
8+
of_get_mac_address() before falling back to parse_config_file().
9+
Return -EPROBE_DEFER immediately if the NVMEM provider is not yet
10+
available, so the driver is re-probed once the dependency is ready.
11+
This allows platform DTS nodes to supply the MAC address through the
12+
standard 'mac-address' / 'local-mac-address' properties or a linked
13+
NVMEM cell without requiring a config.ini file.
14+
15+
Upstream-Status: Submitted [https://github.com/TC956X/TC9564_Host_Driver/pull/3]
16+
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
17+
---
18+
drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c | 10 +++++++---
19+
1 file changed, 7 insertions(+), 3 deletions(-)
20+
21+
diff --git a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
22+
index a4d8ca8..30031a9 100644
23+
--- a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
24+
+++ b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
25+
@@ -223,6 +223,7 @@
26+
#include "tc956xmac.h"
27+
#include <linux/reset.h>
28+
#include <linux/of_mdio.h>
29+
+#include <linux/of_net.h>
30+
#include <linux/version.h>
31+
#include <linux/ctype.h>
32+
#include "dwxgmac2.h"
33+
@@ -15732,10 +15733,13 @@ int tc956xmac_vf_dvr_probe(struct device *device,
34+
/* To be enabled for config.ini parsing */
35+
parse_config_file(priv->port_num, priv->plat->vf_id);
36+
#else
37+
- /* To be enabled for config.ini parsing */
38+
- parse_config_file(priv->port_num, 0);
39+
+ ret = of_get_mac_address(priv->device->of_node, dev_addr[priv->probe_seq_no]);
40+
+ if (ret == -EPROBE_DEFER)
41+
+ return dev_err_probe(priv->device, ret,
42+
+ "Deferring probe for MAC address from DTB/NVMEM\n");
43+
+ if (ret)
44+
+ parse_config_file(priv->port_num, 0);
45+
#endif
46+
-
47+
#endif /* EEPROM_MAC_ADDR */
48+
#ifndef TC956X_SRIOV_VF
49+
res->mac = &dev_addr[priv->probe_seq_no][0];
50+
--
51+
2.34.1
52+
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
From 983d0c51f2c7a07aa8199a21aabdb7d81ec2aefe Mon Sep 17 00:00:00 2001
2+
From: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
3+
Date: Mon, 30 Mar 2026 01:22:05 +0530
4+
Subject: [PATCH 03/12] net: ethernet: tc956x: Replace phylink .validate with
5+
.mac_get_caps (kernel 6.7)
6+
7+
The phylink_mac_ops.validate callback was removed in kernel 6.7 in favour
8+
of mac_get_caps(). Guard the old tc956xmac_validate() function behind a
9+
LINUX_VERSION_CODE < 6.7.0 check and add the new tc956xmac_mac_get_caps()
10+
implementation in the #else branch.
11+
12+
Populate mac->link.caps in dwxgmac2_setup() and add the caps field to
13+
struct mac_link in common.h so that mac_get_caps() can return the
14+
supported MAC capabilities.
15+
16+
Upstream-Status: Submitted [https://github.com/TC956X/TC9564_Host_Driver/pull/4]
17+
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
18+
---
19+
drivers/net/ethernet/toshiba/tc956x/common.h | 1 +
20+
.../ethernet/toshiba/tc956x/dwxgmac2_core.c | 3 +++
21+
.../ethernet/toshiba/tc956x/tc956xmac_main.c | 20 +++++++++++++++++++
22+
3 files changed, 24 insertions(+)
23+
24+
diff --git a/drivers/net/ethernet/toshiba/tc956x/common.h b/drivers/net/ethernet/toshiba/tc956x/common.h
25+
index d983381..0c21913 100644
26+
--- a/drivers/net/ethernet/toshiba/tc956x/common.h
27+
+++ b/drivers/net/ethernet/toshiba/tc956x/common.h
28+
@@ -2887,6 +2887,7 @@ extern const struct tc956xmac_hwtimestamp tc956xmac_ptp;
29+
extern const struct tc956xmac_mode_ops dwmac4_ring_mode_ops;
30+
31+
struct mac_link {
32+
+ u32 caps;
33+
u32 speed_mask;
34+
u32 speed10;
35+
u32 speed100;
36+
diff --git a/drivers/net/ethernet/toshiba/tc956x/dwxgmac2_core.c b/drivers/net/ethernet/toshiba/tc956x/dwxgmac2_core.c
37+
index a6f1956..30bbe24 100644
38+
--- a/drivers/net/ethernet/toshiba/tc956x/dwxgmac2_core.c
39+
+++ b/drivers/net/ethernet/toshiba/tc956x/dwxgmac2_core.c
40+
@@ -3285,6 +3285,9 @@ int dwxgmac2_setup(struct tc956xmac_priv *priv)
41+
mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
42+
mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
43+
mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
44+
+ mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
45+
+ MAC_10 | MAC_100 | MAC_1000FD |
46+
+ MAC_2500FD | MAC_5000FD | MAC_10000FD;
47+
48+
mac->mii.addr = XGMAC_MDIO_ADDR;
49+
mac->mii.data = XGMAC_MDIO_DATA;
50+
diff --git a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
51+
index 30031a9..4d6eb09 100644
52+
--- a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
53+
+++ b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
54+
@@ -2997,6 +2997,7 @@ static void tc956xmac_mac_flow_ctrl(struct tc956xmac_priv *priv, u32 duplex)
55+
priv->pause, tx_cnt);
56+
}
57+
58+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0)
59+
static void tc956xmac_validate(struct phylink_config *config,
60+
unsigned long *supported,
61+
struct phylink_link_state *state)
62+
@@ -3099,6 +3100,21 @@ static void tc956xmac_validate(struct phylink_config *config,
63+
bitmap_andnot(state->advertising, state->advertising, mask,
64+
__ETHTOOL_LINK_MODE_MASK_NBITS);
65+
}
66+
+#else
67+
+static unsigned long tc956xmac_mac_get_caps(struct phylink_config *config,
68+
+ phy_interface_t interface)
69+
+{
70+
+ struct tc956xmac_priv *priv = netdev_priv(to_net_dev(config->dev));
71+
+
72+
+ priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD | MAC_1000HD);
73+
+ config->mac_capabilities = priv->hw->link.caps;
74+
+
75+
+ if (priv->plat->max_speed)
76+
+ phylink_limit_mac_speed(config, priv->plat->max_speed);
77+
+
78+
+ return config->mac_capabilities;
79+
+}
80+
+#endif /* KERNEL_VERSION(6,7,0) */
81+
#endif /* TC956X_SRIOV_VF */
82+
83+
#ifndef TC956X_SRIOV_VF
84+
@@ -4456,7 +4472,11 @@ static void tc956xmac_mac_link_up(struct phylink_config *config,
85+
}
86+
87+
static const struct phylink_mac_ops tc956xmac_phylink_mac_ops = {
88+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0)
89+
.validate = tc956xmac_validate,
90+
+#else
91+
+ .mac_get_caps = tc956xmac_mac_get_caps,
92+
+#endif
93+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
94+
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
95+
.mac_pcs_get_state = tc956xmac_mac_pcs_get_state,
96+
--
97+
2.34.1
98+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
From 1cbc509df65f0fe47be49c5c6f285d91c20b9d9e Mon Sep 17 00:00:00 2001
2+
From: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
3+
Date: Mon, 30 Mar 2026 01:22:24 +0530
4+
Subject: [PATCH 04/12] net: ethernet: tc956x: Replace strlcpy() with strscpy()
5+
(kernel 6.8)
6+
7+
strlcpy() was removed in kernel 6.8. Replace all remaining call sites
8+
in tc956xmac_ethtool_getdrvinfo() and tc956x_dump_regs() with the
9+
equivalent strscpy().
10+
11+
Upstream-Status: Submitted [https://github.com/TC956X/TC9564_Host_Driver/pull/4]
12+
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
13+
---
14+
.../net/ethernet/toshiba/tc956x/tc956xmac_ethtool.c | 12 ++++++------
15+
drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c | 6 +++---
16+
2 files changed, 9 insertions(+), 9 deletions(-)
17+
18+
diff --git a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_ethtool.c b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_ethtool.c
19+
index 76d0d1b..8dae37b 100644
20+
--- a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_ethtool.c
21+
+++ b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_ethtool.c
22+
@@ -941,18 +941,18 @@ static void tc956xmac_ethtool_getdrvinfo(struct net_device *dev,
23+
fw_version->major, fw_version->minor,
24+
fw_version->sub_minor);
25+
26+
- strlcpy(info->fw_version, fw_version_str, sizeof(info->fw_version));
27+
+ strscpy(info->fw_version, fw_version_str, sizeof(info->fw_version));
28+
29+
if (priv->plat->has_gmac || priv->plat->has_gmac4)
30+
- strlcpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver));
31+
+ strscpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver));
32+
else if (priv->plat->has_xgmac)
33+
- strlcpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver));
34+
+ strscpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver));
35+
else
36+
- strlcpy(info->driver, MAC100_ETHTOOL_NAME,
37+
+ strscpy(info->driver, MAC100_ETHTOOL_NAME,
38+
sizeof(info->driver));
39+
40+
- strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
41+
- strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
42+
+ strscpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
43+
+ strscpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
44+
45+
info->n_priv_flags = TC956X_PRIV_FLAGS_STR_LEN;
46+
}
47+
diff --git a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
48+
index 4d6eb09..08294a0 100644
49+
--- a/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
50+
+++ b/drivers/net/ethernet/toshiba/tc956x/tc956xmac_main.c
51+
@@ -712,14 +712,14 @@ int tc956x_dump_regs(struct net_device *net_device, struct tc956x_regs *regs)
52+
}
53+
54+
/* Driver & FW Information */
55+
- strlcpy(regs->info.driver, TC956X_RESOURCE_NAME, sizeof(regs->info.driver));
56+
- strlcpy(regs->info.version, DRV_MODULE_VERSION, sizeof(regs->info.version));
57+
+ strscpy(regs->info.driver, TC956X_RESOURCE_NAME, sizeof(regs->info.driver));
58+
+ strscpy(regs->info.version, DRV_MODULE_VERSION, sizeof(regs->info.version));
59+
60+
reg = readl(priv->tc956x_SRAM_pci_base_addr + TC956X_M3_DBG_VER_START);
61+
fw_version = (struct tc956x_version *)(&reg);
62+
scnprintf(fw_version_str, sizeof(fw_version_str), "FW Version %s_%d.%d-%d", (fw_version->rel_dbg == 'D')?"DBG":"REL",
63+
fw_version->major, fw_version->minor, fw_version->sub_minor);
64+
- strlcpy(regs->info.fw_version, fw_version_str, sizeof(regs->info.fw_version));
65+
+ strscpy(regs->info.fw_version, fw_version_str, sizeof(regs->info.fw_version));
66+
67+
/* Updating statistics */
68+
tc956xmac_mmc_read(priv, priv->mmcaddr, &priv->mmc);
69+
--
70+
2.34.1
71+

0 commit comments

Comments
 (0)