From 5d1dedd9f7fc7a7c893e14ec6c1548e2be7a1a13 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 29 Mar 2025 21:31:49 +0100 Subject: [PATCH 01/14] generic: qca8k: backport bridge port isolation support Bridge port isolation offload support has been added to the bridge core and many DSA drivers. mt7530 support was backported in OpenWrt commit c4e6a147a6c0 ("generic: 6.6: mt7530: add support for bridge port isolation"). Backport qca8k support as well. Signed-off-by: Matthias Schiffer Link: https://github.com/openwrt/openwrt/pull/18375 Signed-off-by: Christian Marangi --- ...-not-write-port-mask-twice-in-bridge.patch | 58 +++++++ ...k-factor-out-bridge-join-leave-logic.patch | 153 ++++++++++++++++++ ...dd-support-for-bridge-port-isolation.patch | 91 +++++++++++ ...-qca8k-implement-lag_fdb_add-del-ops.patch | 4 +- ...-add-IPQ4019-built-in-switch-support.patch | 23 +-- 5 files changed, 311 insertions(+), 18 deletions(-) create mode 100644 target/linux/generic/backport-6.6/793-01-v6.11-net-dsa-qca8k-do-not-write-port-mask-twice-in-bridge.patch create mode 100644 target/linux/generic/backport-6.6/793-02-v6.11-net-dsa-qca8k-factor-out-bridge-join-leave-logic.patch create mode 100644 target/linux/generic/backport-6.6/793-03-v6.11-net-dsa-qca8k-add-support-for-bridge-port-isolation.patch diff --git a/target/linux/generic/backport-6.6/793-01-v6.11-net-dsa-qca8k-do-not-write-port-mask-twice-in-bridge.patch b/target/linux/generic/backport-6.6/793-01-v6.11-net-dsa-qca8k-do-not-write-port-mask-twice-in-bridge.patch new file mode 100644 index 0000000000..22b544c433 --- /dev/null +++ b/target/linux/generic/backport-6.6/793-01-v6.11-net-dsa-qca8k-do-not-write-port-mask-twice-in-bridge.patch @@ -0,0 +1,58 @@ +From e85d3e6fea05c8ae21a40809a3c6b7adc97411c7 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Matthias Schiffer +Date: Thu, 20 Jun 2024 19:25:48 +0200 +Subject: [PATCH] net: dsa: qca8k: do not write port mask twice in bridge + join/leave + +qca8k_port_bridge_join() set QCA8K_PORT_LOOKUP_CTRL() for i == port twice, +once in the loop handling all other port's masks, and finally at the end +with the accumulated port_mask. + +The first time it would incorrectly set the port's own bit in the mask, +only to correct the mistake a moment later. qca8k_port_bridge_leave() had +the same issue, but here the regmap_clear_bits() was a no-op rather than +setting an unintended value. + +Remove the duplicate assignment by skipping the whole loop iteration for +i == port. The unintended bit setting doesn't seem to have any negative +effects (even when not reverted right away), so the change is submitted +as a simple cleanup rather than a fix. + +Signed-off-by: Matthias Schiffer +Reviewed-by: Wojciech Drewek +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-common.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -654,6 +654,8 @@ int qca8k_port_bridge_join(struct dsa_sw + port_mask = BIT(cpu_port); + + for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (i == port) ++ continue; + if (dsa_is_cpu_port(ds, i)) + continue; + if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) +@@ -666,8 +668,7 @@ int qca8k_port_bridge_join(struct dsa_sw + BIT(port)); + if (ret) + return ret; +- if (i != port) +- port_mask |= BIT(i); ++ port_mask |= BIT(i); + } + + /* Add all other ports to this ports portvlan mask */ +@@ -686,6 +687,8 @@ void qca8k_port_bridge_leave(struct dsa_ + cpu_port = dsa_to_port(ds, port)->cpu_dp->index; + + for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (i == port) ++ continue; + if (dsa_is_cpu_port(ds, i)) + continue; + if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) diff --git a/target/linux/generic/backport-6.6/793-02-v6.11-net-dsa-qca8k-factor-out-bridge-join-leave-logic.patch b/target/linux/generic/backport-6.6/793-02-v6.11-net-dsa-qca8k-factor-out-bridge-join-leave-logic.patch new file mode 100644 index 0000000000..fdb7e7b8b6 --- /dev/null +++ b/target/linux/generic/backport-6.6/793-02-v6.11-net-dsa-qca8k-factor-out-bridge-join-leave-logic.patch @@ -0,0 +1,153 @@ +From 412e1775f413c944b8c51bdadb675be957d83dc8 Mon Sep 17 00:00:00 2001 +Message-ID: <412e1775f413c944b8c51bdadb675be957d83dc8.1728674648.git.mschiffer@universe-factory.net> +In-Reply-To: +References: +From: Matthias Schiffer +Date: Thu, 20 Jun 2024 19:25:49 +0200 +Subject: [PATCH] net: dsa: qca8k: factor out bridge join/leave logic + +Most of the logic in qca8k_port_bridge_join() and qca8k_port_bridge_leave() +is the same. Refactor to reduce duplication and prepare for reusing the +code for implementing bridge port isolation. + +dsa_port_offloads_bridge_dev() is used instead of +dsa_port_offloads_bridge(), passing the bridge in as a struct netdevice *, +as we won't have a struct dsa_bridge in qca8k_port_bridge_flags(). + +The error handling is changed slightly in the bridge leave case, +returning early and emitting an error message when a regmap access fails. +This shouldn't matter in practice, as there isn't much we can do if +communication with the switch breaks down in the middle of reconfiguration. + +Signed-off-by: Matthias Schiffer +Reviewed-by: Wojciech Drewek +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-common.c | 101 ++++++++++++++--------------- + 1 file changed, 50 insertions(+), 51 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -615,6 +615,49 @@ void qca8k_port_stp_state_set(struct dsa + qca8k_port_configure_learning(ds, port, learning); + } + ++static int qca8k_update_port_member(struct qca8k_priv *priv, int port, ++ const struct net_device *bridge_dev, ++ bool join) ++{ ++ struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp; ++ u32 port_mask = BIT(dp->cpu_dp->index); ++ int i, ret; ++ ++ for (i = 0; i < QCA8K_NUM_PORTS; i++) { ++ if (i == port) ++ continue; ++ if (dsa_is_cpu_port(priv->ds, i)) ++ continue; ++ ++ other_dp = dsa_to_port(priv->ds, i); ++ if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev)) ++ continue; ++ ++ /* Add/remove this port to/from the portvlan mask of the other ++ * ports in the bridge ++ */ ++ if (join) { ++ port_mask |= BIT(i); ++ ret = regmap_set_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ } else { ++ ret = regmap_clear_bits(priv->regmap, ++ QCA8K_PORT_LOOKUP_CTRL(i), ++ BIT(port)); ++ } ++ ++ if (ret) ++ return ret; ++ } ++ ++ /* Add/remove all other ports to/from this port's portvlan mask */ ++ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), ++ QCA8K_PORT_LOOKUP_MEMBER, port_mask); ++ ++ return ret; ++} ++ + int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port, + struct switchdev_brport_flags flags, + struct netlink_ext_ack *extack) +@@ -647,65 +690,21 @@ int qca8k_port_bridge_join(struct dsa_sw + struct netlink_ext_ack *extack) + { + struct qca8k_priv *priv = ds->priv; +- int port_mask, cpu_port; +- int i, ret; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- port_mask = BIT(cpu_port); + +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (i == port) +- continue; +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) +- continue; +- /* Add this port to the portvlan mask of the other ports +- * in the bridge +- */ +- ret = regmap_set_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- if (ret) +- return ret; +- port_mask |= BIT(i); +- } +- +- /* Add all other ports to this ports portvlan mask */ +- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, port_mask); +- +- return ret; ++ return qca8k_update_port_member(priv, port, bridge.dev, true); + } + + void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge) + { + struct qca8k_priv *priv = ds->priv; +- int cpu_port, i; +- +- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +- +- for (i = 0; i < QCA8K_NUM_PORTS; i++) { +- if (i == port) +- continue; +- if (dsa_is_cpu_port(ds, i)) +- continue; +- if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) +- continue; +- /* Remove this port to the portvlan mask of the other ports +- * in the bridge +- */ +- regmap_clear_bits(priv->regmap, +- QCA8K_PORT_LOOKUP_CTRL(i), +- BIT(port)); +- } ++ int err; + +- /* Set the cpu port to be the only one in the portvlan mask of +- * this port +- */ +- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), +- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); ++ err = qca8k_update_port_member(priv, port, bridge.dev, false); ++ if (err) ++ dev_err(priv->dev, ++ "Failed to update switch config for bridge leave: %d\n", ++ err); + } + + void qca8k_port_fast_age(struct dsa_switch *ds, int port) diff --git a/target/linux/generic/backport-6.6/793-03-v6.11-net-dsa-qca8k-add-support-for-bridge-port-isolation.patch b/target/linux/generic/backport-6.6/793-03-v6.11-net-dsa-qca8k-add-support-for-bridge-port-isolation.patch new file mode 100644 index 0000000000..263fe10d4b --- /dev/null +++ b/target/linux/generic/backport-6.6/793-03-v6.11-net-dsa-qca8k-add-support-for-bridge-port-isolation.patch @@ -0,0 +1,91 @@ +From 422b64025ec10981c48f9367311846bf4bd38042 Mon Sep 17 00:00:00 2001 +Message-ID: <422b64025ec10981c48f9367311846bf4bd38042.1728674648.git.mschiffer@universe-factory.net> +In-Reply-To: +References: +From: Matthias Schiffer +Date: Thu, 20 Jun 2024 19:25:50 +0200 +Subject: [PATCH] net: dsa: qca8k: add support for bridge port isolation + +Remove a pair of ports from the port matrix when both ports have the +isolated flag set. + +Signed-off-by: Matthias Schiffer +Reviewed-by: Wojciech Drewek +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-common.c | 22 ++++++++++++++++++++-- + drivers/net/dsa/qca/qca8k.h | 1 + + 2 files changed, 21 insertions(+), 2 deletions(-) + +--- a/drivers/net/dsa/qca/qca8k-common.c ++++ b/drivers/net/dsa/qca/qca8k-common.c +@@ -619,6 +619,7 @@ static int qca8k_update_port_member(stru + const struct net_device *bridge_dev, + bool join) + { ++ bool isolated = !!(priv->port_isolated_map & BIT(port)), other_isolated; + struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp; + u32 port_mask = BIT(dp->cpu_dp->index); + int i, ret; +@@ -633,10 +634,12 @@ static int qca8k_update_port_member(stru + if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev)) + continue; + ++ other_isolated = !!(priv->port_isolated_map & BIT(i)); ++ + /* Add/remove this port to/from the portvlan mask of the other + * ports in the bridge + */ +- if (join) { ++ if (join && !(isolated && other_isolated)) { + port_mask |= BIT(i); + ret = regmap_set_bits(priv->regmap, + QCA8K_PORT_LOOKUP_CTRL(i), +@@ -662,7 +665,7 @@ int qca8k_port_pre_bridge_flags(struct d + struct switchdev_brport_flags flags, + struct netlink_ext_ack *extack) + { +- if (flags.mask & ~BR_LEARNING) ++ if (flags.mask & ~(BR_LEARNING | BR_ISOLATED)) + return -EINVAL; + + return 0; +@@ -672,6 +675,7 @@ int qca8k_port_bridge_flags(struct dsa_s + struct switchdev_brport_flags flags, + struct netlink_ext_ack *extack) + { ++ struct qca8k_priv *priv = ds->priv; + int ret; + + if (flags.mask & BR_LEARNING) { +@@ -680,6 +684,20 @@ int qca8k_port_bridge_flags(struct dsa_s + if (ret) + return ret; + } ++ ++ if (flags.mask & BR_ISOLATED) { ++ struct dsa_port *dp = dsa_to_port(ds, port); ++ struct net_device *bridge_dev = dsa_port_bridge_dev_get(dp); ++ ++ if (flags.val & BR_ISOLATED) ++ priv->port_isolated_map |= BIT(port); ++ else ++ priv->port_isolated_map &= ~BIT(port); ++ ++ ret = qca8k_update_port_member(priv, port, bridge_dev, true); ++ if (ret) ++ return ret; ++ } + + return 0; + } +--- a/drivers/net/dsa/qca/qca8k.h ++++ b/drivers/net/dsa/qca/qca8k.h +@@ -451,6 +451,7 @@ struct qca8k_priv { + * Bit 1: port enabled. Bit 0: port disabled. + */ + u8 port_enabled_map; ++ u8 port_isolated_map; + struct qca8k_ports_config ports_config; + struct regmap *regmap; + struct mii_bus *bus; diff --git a/target/linux/generic/pending-6.6/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch b/target/linux/generic/pending-6.6/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch index 3197aea091..8d815dd2f2 100644 --- a/target/linux/generic/pending-6.6/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch +++ b/target/linux/generic/pending-6.6/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch @@ -27,7 +27,7 @@ Signed-off-by: Christian Marangi .port_mirror_add = qca8k_port_mirror_add, --- a/drivers/net/dsa/qca/qca8k-common.c +++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -1215,6 +1215,42 @@ int qca8k_port_lag_leave(struct dsa_swit +@@ -1235,6 +1235,42 @@ int qca8k_port_lag_leave(struct dsa_swit return qca8k_lag_refresh_portmap(ds, port, lag, true); } @@ -72,7 +72,7 @@ Signed-off-by: Christian Marangi u32 val; --- a/drivers/net/dsa/qca/qca8k.h +++ b/drivers/net/dsa/qca/qca8k.h -@@ -590,5 +590,11 @@ int qca8k_port_lag_join(struct dsa_switc +@@ -591,5 +591,11 @@ int qca8k_port_lag_join(struct dsa_switc struct netlink_ext_ack *extack); int qca8k_port_lag_leave(struct dsa_switch *ds, int port, struct dsa_lag lag); diff --git a/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch b/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch index 9bd5ca515e..76539cea88 100644 --- a/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch +++ b/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch @@ -67,24 +67,15 @@ Signed-off-by: Robert Marko mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); if ((reg & mask) != mask) { -@@ -653,7 +653,7 @@ int qca8k_port_bridge_join(struct dsa_sw - cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - port_mask = BIT(cpu_port); +@@ -624,7 +624,7 @@ static int qca8k_update_port_member(stru + u32 port_mask = BIT(dp->cpu_dp->index); + int i, ret; - for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ for (i = 0; i < ds->num_ports; i++) { - if (dsa_is_cpu_port(ds, i)) ++ for (i = 0; i < priv->ds->num_ports; i++) { + if (i == port) continue; - if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) -@@ -685,7 +685,7 @@ void qca8k_port_bridge_leave(struct dsa_ - - cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ for (i = 0; i < ds->num_ports; i++) { - if (dsa_is_cpu_port(ds, i)) - continue; - if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) + if (dsa_is_cpu_port(priv->ds, i)) --- /dev/null +++ b/drivers/net/dsa/qca/qca8k-ipq4019.c @@ -0,0 +1,948 @@ @@ -1119,7 +1110,7 @@ Signed-off-by: Robert Marko enum { QCA8K_PORT_SPEED_10M = 0, QCA8K_PORT_SPEED_100M = 1, -@@ -466,6 +518,10 @@ struct qca8k_priv { +@@ -467,6 +519,10 @@ struct qca8k_priv { struct qca8k_pcs pcs_port_6; const struct qca8k_match_data *info; struct qca8k_led ports_led[QCA8K_LED_COUNT]; From af93874f4e5e4f6a8646964fecf385711d527e89 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 29 Mar 2025 21:32:08 +0100 Subject: [PATCH 02/14] ipq40xx: qca8k: hook up IPQ4019 bridge flag offloading Adds support for setting bridge port learning and isolation flags on ipq40xx. Signed-off-by: Matthias Schiffer Link: https://github.com/openwrt/openwrt/pull/18375 Signed-off-by: Christian Marangi --- ...06-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch b/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch index 76539cea88..73e99f2bdc 100644 --- a/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch +++ b/target/linux/ipq40xx/patches-6.6/706-net-dsa-qca8k-add-IPQ4019-built-in-switch-support.patch @@ -78,7 +78,7 @@ Signed-off-by: Robert Marko if (dsa_is_cpu_port(priv->ds, i)) --- /dev/null +++ b/drivers/net/dsa/qca/qca8k-ipq4019.c -@@ -0,0 +1,948 @@ +@@ -0,0 +1,950 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2009 Felix Fietkau @@ -870,6 +870,8 @@ Signed-off-by: Robert Marko + .port_change_mtu = qca8k_port_change_mtu, + .port_max_mtu = qca8k_port_max_mtu, + .port_stp_state_set = qca8k_port_stp_state_set, ++ .port_pre_bridge_flags = qca8k_port_pre_bridge_flags, ++ .port_bridge_flags = qca8k_port_bridge_flags, + .port_bridge_join = qca8k_port_bridge_join, + .port_bridge_leave = qca8k_port_bridge_leave, + .port_fast_age = qca8k_port_fast_age, From f44984f19c447db30b76ca7f49572aac97270145 Mon Sep 17 00:00:00 2001 From: Andrew LaMarche Date: Fri, 28 Mar 2025 01:06:03 +0000 Subject: [PATCH 03/14] an7581: fix phy2 led1 function PHY2 led1 is configured to control PHY1's LED. Change it to PHY2. Signed-off-by: Andrew LaMarche Link: https://github.com/openwrt/openwrt/pull/18361 Signed-off-by: Hauke Mehrtens --- target/linux/airoha/dts/an7581.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 762a6aa1a8..58aed4b255 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -816,7 +816,7 @@ gsw_phy2_led1: gsw-phy2-led1@1 { reg = <1>; - function = "phy1_led1"; + function = "phy2_led1"; status = "disabled"; }; }; From 1cb5297ac317e8084590853cd894f23a6cf734a2 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Tue, 8 Apr 2025 17:39:47 +0200 Subject: [PATCH 04/14] ipq-wifi: update to Git HEAD (2025-04-08) 5aa50e188feb ipq40xx: add BDF for Alibaba AP4220 7d2a86c01a52 ipq6018: add TP-Link EAP623-Outdoor HD v1 BDF 9591c9b7578a Remove executable permissions Signed-off-by: Robert Marko --- package/firmware/ipq-wifi/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index 31f2364b06..45109491f1 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -6,9 +6,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git -PKG_SOURCE_DATE:=2025-04-01 -PKG_SOURCE_VERSION:=c220fac7fdb35628ba53ff53ed36cf883a401161 -PKG_MIRROR_HASH:=26338b4f165eb2e90273cd61ed26715b99e496ccf738167e22ff9213ca42c973 +PKG_SOURCE_DATE:=2025-04-08 +PKG_SOURCE_VERSION:=9591c9b7578af3548c35bb80cd6c37978669f7c9 +PKG_MIRROR_HASH:=b5c0024a0c0ebeb61ad6bc037f897685d161f1578aca5a1366dd33603661338b PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/package.mk From 5dbf93c8c56edb919d0a02a1981ae3c28cb983ef Mon Sep 17 00:00:00 2001 From: Yang Xiwen Date: Mon, 31 Mar 2025 08:48:23 +0800 Subject: [PATCH 05/14] ipq60xx: add support for TP-Link EAP623-Outdoor HD v1 Specifications: * SoC: Qualcomm IPQ6018 (64-bit Quad-core Arm Cortex-A53 @ 1800MHz) * Memory: 1 GiB * Serial Port: 3v3 TTL 115200n8 * Wi-Fi: QCN9074 (4x4 5 GHz 802.11ax) * Wi-Fi: IPQ6018 (4x4 2.4 GHz 802.11b/g/n/ax) * Ethernet: RTL8211F (10/100/1GBASE-T) * Flash: ESMT F59D1G81MB (128 MiB) * LEDs: 1x Green Status (GPIO 37 Active High), 1x Yellow Status (GPIO 32 Active High) and an LED global control GPIO (GPIO 36 Active High, set up by U-Boot) * Buttons: 1x Reset (GPIO 9 Active Low) Installation Instructions (Serial+TFTP): 1. Solder 4 pin header to the pads near T32 and T31. 2. Connect 3V3 TTL port to TX, RX, and GND, which are pad T31, T32 and the pad near T31 respectively. Be sure not to connect VCC and crossover TX and RX. 3. Copy RAM firmware image openwrt-qualcommax-ipq60xx-tplink_eap623od-hd-v1-initramfs-uImage.itb to TFTP server root, available at 192.168.0.1. 4. Connect PoE ethernet cable to the RJ45 port and hold Ctrl+B in the serial console (115200 baud) until autoboot is halted. 5. Run the following commands in the U-boot prompt: # setenv serverip 192.168.0.1 # setenv ipaddr 192.168.0.99 # tftpboot 0x44000000 openwrt-qualcommax-ipq60xx-tplink_eap623od-hd-v1-initramfs-uImage.itb # bootm You may need to type Ctrl+C and Enter before running these commands to clear invisible characters from the buffer. 6. Run the following command in a terminal to copy the sysupgrade image to be installed (check IP address): $ scp openwrt-qualcommax-ipq60xx-tplink_eap623od-hd-v1-squashfs-sysupgrade.bin root@192.168.1.1:/tmp/ 7. Activate the OpenWrt serial console and run the following commands: # cd /tmp # sysupgrade -n openwrt-qualcommax-ipq60xx-tplink_eap623od-hd-v1-squashfs-sysupgrade.bin 8. The AP will reboot and OpenWrt will be successfully installed. Signed-off-by: Yang Xiwen Link: https://github.com/openwrt/openwrt/pull/18389 Signed-off-by: Robert Marko --- .../uboot-envtools/files/qualcommax_ipq60xx | 3 +- package/firmware/ipq-wifi/Makefile | 2 + .../boot/dts/qcom/ipq6018-eap623od-hd-v1.dts | 151 ++++++++++++++++++ target/linux/qualcommax/image/ipq60xx.mk | 16 ++ .../ipq60xx/base-files/etc/board.d/02_network | 6 +- .../etc/hotplug.d/firmware/11-ath11k-caldata | 3 +- .../lib/preinit/09_mount_factory_data | 3 +- .../base-files/lib/upgrade/platform.sh | 3 +- 8 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-eap623od-hd-v1.dts diff --git a/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq60xx b/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq60xx index 02926424ab..7a89f78e79 100644 --- a/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq60xx +++ b/package/boot/uboot-tools/uboot-envtools/files/qualcommax_ipq60xx @@ -28,7 +28,8 @@ linksys,mr7500) netgear,wax214|\ netgear,wax610|\ netgear,wax610y|\ -tplink,eap610-outdoor) +tplink,eap610-outdoor|\ +tplink,eap623od-hd-v1) ubootenv_add_mtd "0:appsblenv" "0x0" "0x40000" "0x20000" ;; yuncore,fap650) diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index 45109491f1..bf7d553df3 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -68,6 +68,7 @@ ALLWIFIBOARDS:= \ spectrum_sax1v1k \ tplink_eap610-outdoor \ tplink_eap620hd-v1 \ + tplink_eap623od-hd-v1 \ tplink_eap660hd-v1 \ wallys_dr40x9 \ xiaomi_ax3600 \ @@ -216,6 +217,7 @@ $(eval $(call generate-ipq-wifi-package,skspruce_wia3300-20,SKSpruce WIA3300-20) $(eval $(call generate-ipq-wifi-package,spectrum_sax1v1k,Spectrum SAX1V1K)) $(eval $(call generate-ipq-wifi-package,tplink_eap610-outdoor,TPLink EAP610-Outdoor)) $(eval $(call generate-ipq-wifi-package,tplink_eap620hd-v1,TP-Link EAP620 HD v1)) +$(eval $(call generate-ipq-wifi-package,tplink_eap623od-hd-v1,TP-Link EAP623-Outdoor HD v1)) $(eval $(call generate-ipq-wifi-package,tplink_eap660hd-v1,TP-Link EAP660 HD v1)) $(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9)) $(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600)) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-eap623od-hd-v1.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-eap623od-hd-v1.dts new file mode 100644 index 0000000000..a4e49c9d6f --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-eap623od-hd-v1.dts @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: MIT, GPL-2.0 or later +/* Copyright (c) 2025, Yang Xiwen */ + +/dts-v1/; + +#include "ipq6018.dtsi" +#include "ipq6018-cp-cpu.dtsi" +#include "ipq6018-ess.dtsi" +#include +#include +#include + +/ { + model = "TP-Link EAP623-Outdoor HD V1.0"; + compatible = "tplink,eap623od-hd-v1", "qcom,ipq6018"; + + aliases { + serial0 = &blsp1_uart3; + led-boot = &led_system; + led-failsafe = &led_system; + led-running = &led_system; + led-upgrade = &led_system; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs-append = " root=/dev/ubiblock0_1"; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&tlmm 9 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_system: system { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>; + }; + + wlan { + color = ; + function = LED_FUNCTION_WLAN; + gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&blsp1_uart3 { + pinctrl-0 = <&serial_3_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&tlmm { + mdio_pins: mdio-pins { + mdc { + pins = "gpio64"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio { + pins = "gpio65"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + phy_pins: phy-reset-pin { + pins = "gpio77"; + function = "gpio"; + bias-pull-up; + }; +}; + +&mdio { + status = "okay"; + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + + rtl8211f: ethernet-phy@4 { + compatible = "ethernet-phy-id001c.c916"; + reg = <4>; + reset-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&phy_pins>; + pinctrl-names = "default"; + + realtek,clkout-disable; + realtek,aldps-enable; + }; +}; + +&switch { + status = "okay"; + switch_lan_bmp = ; /* lan port bitmap */ + switch_mac_mode1 = ; /* mac mode for uniphy instance0*/ + + qcom,port_phyinfo { + port@5 { + port_id = <5>; + phy_address = <4>; + port_mac_sel = "QGMAC_PORT"; + }; + }; +}; + +&edma { + status = "okay"; +}; + +&dp5 { + status = "okay"; + phy-handle = <&rtl8211f>; + phy-mode = "sgmii"; + label = "lan"; +}; + +&qpic_bam { + status = "okay"; +}; + +&qpic_nand { + status = "okay"; + + nand@0 { + reg = <0>; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + + partitions { + compatible = "qcom,smem-part"; + }; + }; +}; + +&wifi { + qcom,ath11k-calibration-variant = "TPLink-EAP623-Outdoor-HD-v1"; + status = "okay"; +}; diff --git a/target/linux/qualcommax/image/ipq60xx.mk b/target/linux/qualcommax/image/ipq60xx.mk index 8c77890966..5c630df3a6 100644 --- a/target/linux/qualcommax/image/ipq60xx.mk +++ b/target/linux/qualcommax/image/ipq60xx.mk @@ -167,6 +167,22 @@ define Device/tplink_eap610-outdoor endef TARGET_DEVICES += tplink_eap610-outdoor +define Device/tplink_eap623od-hd-v1 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := TP-Link + DEVICE_MODEL := EAP623-Outdoor HD + DEVICE_VARIANT := v1 + BLOCKSIZE := 128k + PAGESIZE := 2048 + SOC := ipq6018 + DEVICE_PACKAGES := ipq-wifi-tplink_eap623od-hd-v1 kmod-phy-realtek + IMAGES += web-ui-factory.bin + IMAGE/web-ui-factory.bin := append-ubi | tplink-image-2022 + TPLINK_SUPPORT_STRING := SupportList:\r\nEAP623-Outdoor HD(TP-Link|UN|AX1800-D):1.0\r\n +endef +TARGET_DEVICES += tplink_eap623od-hd-v1 + define Device/yuncore_fap650 $(call Device/FitImage) $(call Device/UbiFit) diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network index f907a29ae0..a3a86490de 100644 --- a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network +++ b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network @@ -32,7 +32,8 @@ ipq60xx_setup_interfaces() ;; netgear,wax610|\ netgear,wax610y|\ - tplink,eap610-outdoor) + tplink,eap610-outdoor|\ + tplink,eap623od-hd-v1) ucidef_set_interface_lan "lan" "dhcp" ;; *) @@ -54,7 +55,8 @@ ipq60xx_setup_macs() wan_mac=$(macaddr_add "$lan_mac" 1) label_mac=$lan_mac ;; - tplink,eap610-outdoor) + tplink,eap610-outdoor|\ + tplink,eap623od-hd-v1) label_mac=$(get_mac_binary /tmp/factory_data/default-mac 0) lan_mac=$label_mac ;; diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata index ef8afd6bd4..8102524e30 100644 --- a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata +++ b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11k-caldata @@ -50,7 +50,8 @@ case "$FIRMWARE" in ath11k_patch_mac $(macaddr_add $label_mac 2) 1 ath11k_set_macflag ;; - tplink,eap610-outdoor) + tplink,eap610-outdoor|\ + tplink,eap623od-hd-v1) caldata_from_file "/tmp/factory_data/radio" 0 0x10000 label_mac=$(get_mac_binary /tmp/factory_data/default-mac 0) ath11k_patch_mac $label_mac 1 diff --git a/target/linux/qualcommax/ipq60xx/base-files/lib/preinit/09_mount_factory_data b/target/linux/qualcommax/ipq60xx/base-files/lib/preinit/09_mount_factory_data index 97608db55d..488267a01b 100644 --- a/target/linux/qualcommax/ipq60xx/base-files/lib/preinit/09_mount_factory_data +++ b/target/linux/qualcommax/ipq60xx/base-files/lib/preinit/09_mount_factory_data @@ -7,7 +7,8 @@ preinit_mount_factory_data() { . /lib/functions/system.sh case $(board_name) in - tplink,eap610-outdoor) + tplink,eap610-outdoor|\ + tplink,eap623od-hd-v1) mtd_path=$(find_mtd_chardev "factory_data") ubiattach --dev-path="$mtd_path" --devn=1 mkdir /tmp/factory_data diff --git a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh index bc3603682d..4588688405 100644 --- a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh @@ -133,7 +133,8 @@ platform_do_upgrade() { fw_setenv auto_recovery yes nand_do_upgrade "$1" ;; - tplink,eap610-outdoor) + tplink,eap610-outdoor|\ + tplink,eap623od-hd-v1) tplink_do_upgrade "$1" ;; yuncore,fap650) From 45f0eb106bed8868c02e0ccfb545b7e1c4279841 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Apr 2025 13:30:12 +0200 Subject: [PATCH 06/14] build: bpf: drop clang-11 lookup CLANG_MIN_VER is 12, so there is no point in looking for clang-11. Signed-off-by: Matthias Schiffer Link: https://github.com/openwrt/openwrt/pull/18422 Signed-off-by: Robert Marko --- include/bpf.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bpf.mk b/include/bpf.mk index 8a0121aabe..915662a4fe 100644 --- a/include/bpf.mk +++ b/include/bpf.mk @@ -10,7 +10,7 @@ ifneq ($(CONFIG_USE_LLVM_HOST),) else BPF_PATH:=$(PATH) endif - CLANG:=$(firstword $(shell PATH='$(BPF_PATH)' command -v clang clang-13 clang-12 clang-11)) + CLANG:=$(firstword $(shell PATH='$(BPF_PATH)' command -v clang clang-13 clang-12)) LLVM_VER:=$(subst clang,,$(notdir $(CLANG))) endif ifneq ($(CONFIG_USE_LLVM_PREBUILT),) From 89f1d56a7eab7d530be4bbb5cf21dfc80b3485b1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Apr 2025 12:23:44 +0200 Subject: [PATCH 07/14] build: bpf: fix LLVM tool paths with host toolchain Do not assume that the various tools like llc can be found under the same path as clang; instead, look them up through BPF_PATH (while still preferring ones found next to clang). This fixes build in common setups with ccache, where clang resolves to a path like /usr/lib/ccache/bin/clang, but no other tools can be found at that location. Signed-off-by: Matthias Schiffer Link: https://github.com/openwrt/openwrt/pull/18422 Signed-off-by: Robert Marko --- include/bpf.mk | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/include/bpf.mk b/include/bpf.mk index 915662a4fe..b9c8034c68 100644 --- a/include/bpf.mk +++ b/include/bpf.mk @@ -1,30 +1,40 @@ BPF_DEPENDS := @HAS_BPF_TOOLCHAIN +@NEED_BPF_TOOLCHAIN -LLVM_VER:= CLANG_MIN_VER:=12 ifneq ($(CONFIG_USE_LLVM_HOST),) + find-llvm-tool=$(firstword $(shell PATH='$(BPF_PATH)' command -v $(1) || echo '$(firstword $(1))-not-found')) + BPF_TOOLCHAIN_HOST_PATH:=$(call qstrip,$(CONFIG_BPF_TOOLCHAIN_HOST_PATH)) ifneq ($(BPF_TOOLCHAIN_HOST_PATH),) BPF_PATH:=$(BPF_TOOLCHAIN_HOST_PATH)/bin:$(PATH) else BPF_PATH:=$(PATH) endif - CLANG:=$(firstword $(shell PATH='$(BPF_PATH)' command -v clang clang-13 clang-12)) + CLANG:=$(call find-llvm-tool,clang clang-13 clang-12) LLVM_VER:=$(subst clang,,$(notdir $(CLANG))) -endif -ifneq ($(CONFIG_USE_LLVM_PREBUILT),) - CLANG:=$(TOPDIR)/llvm-bpf/bin/clang -endif -ifneq ($(CONFIG_USE_LLVM_BUILD),) - CLANG:=$(STAGING_DIR_HOST)/llvm-bpf/bin/clang -endif -LLVM_PATH:=$(dir $(CLANG)) -LLVM_LLC:=$(LLVM_PATH)/llc$(LLVM_VER) -LLVM_DIS:=$(LLVM_PATH)/llvm-dis$(LLVM_VER) -LLVM_OPT:=$(LLVM_PATH)/opt$(LLVM_VER) -LLVM_STRIP:=$(LLVM_PATH)/llvm-strip$(LLVM_VER) + BPF_PATH:=$(dir $(CLANG)):$(BPF_PATH) + LLVM_LLC:=$(call find-llvm-tool,llc$(LLVM_VER)) + LLVM_DIS:=$(call find-llvm-tool,llvm-dis$(LLVM_VER)) + LLVM_OPT:=$(call find-llvm-tool,opt$(LLVM_VER)) + LLVM_STRIP:=$(call find-llvm-tool,llvm-strip$(LLVM_VER)) +else + LLVM_PATH:=/invalid + + ifneq ($(CONFIG_USE_LLVM_PREBUILT),) + LLVM_PATH:=$(TOPDIR)/llvm-bpf/bin + endif + ifneq ($(CONFIG_USE_LLVM_BUILD),) + LLVM_PATH:=$(STAGING_DIR_HOST)/llvm-bpf/bin + endif + + CLANG:=$(LLVM_PATH)/clang + LLVM_LLC:=$(LLVM_PATH)/llc + LLVM_DIS:=$(LLVM_PATH)/llvm-dis + LLVM_OPT:=$(LLVM_PATH)/opt + LLVM_STRIP:=$(LLVM_PATH)/llvm-strip +endif BPF_KARCH:=mips BPF_ARCH:=mips$(if $(CONFIG_ARCH_64BIT),64)$(if $(CONFIG_BIG_ENDIAN),,el) From e78dc2eae49c5980a5201c98b26cd4a1b177c9a5 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 31 Dec 2024 13:20:06 -0800 Subject: [PATCH 08/14] mac80211: ath9k: clean up gpiochip Simplify patch with gpiochip_add_data, struct reduction, new GPIO API, and header cleanup. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/17445 Signed-off-by: Robert Marko --- .../ath9k/548-ath9k_enable_gpio_chip.patch | 118 ++++++------------ .../ath9k/549-ath9k_enable_gpio_buttons.patch | 22 ++-- .../patches/ath9k/552-ath9k-ahb_of.patch | 6 +- 3 files changed, 55 insertions(+), 91 deletions(-) diff --git a/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch index 9fb549cc19..9696ea5c88 100644 --- a/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch +++ b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch @@ -10,47 +10,32 @@ Signed-off-by: Felix Fietkau --- --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -25,6 +25,7 @@ +@@ -25,6 +25,8 @@ #include #include #include +#include ++#include #include "common.h" #include "debug.h" -@@ -991,6 +992,14 @@ struct ath_led { - struct led_classdev cdev; - }; - -+#ifdef CONFIG_GPIOLIB -+struct ath9k_gpio_chip { -+ struct ath_softc *sc; -+ char label[32]; -+ struct gpio_chip gchip; -+}; -+#endif -+ - struct ath_softc { - struct ieee80211_hw *hw; - struct device *dev; -@@ -1046,6 +1055,9 @@ struct ath_softc { +@@ -1046,6 +1048,10 @@ struct ath_softc { #ifdef CPTCFG_MAC80211_LEDS const char *led_default_trigger; struct list_head leds; +#ifdef CONFIG_GPIOLIB -+ struct ath9k_gpio_chip *gpiochip; ++ struct gpio_chip *gpiochip; ++ struct gpio_desc *gpiodesc; +#endif #endif #ifdef CPTCFG_ATH9K_DEBUGFS --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -16,13 +16,135 @@ - +@@ -17,12 +17,120 @@ #include "ath9k.h" #include -+#include -+ + +#ifdef CPTCFG_MAC80211_LEDS + +#ifdef CONFIG_GPIOLIB @@ -62,10 +47,9 @@ Signed-off-by: Felix Fietkau +/* gpio_chip handler : set GPIO to input */ +static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset) +{ -+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -+ gchip); ++ struct ath_softc *sc = gpiochip_get_data(chip); + -+ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio"); ++ ath9k_hw_gpio_request_in(sc->sc_ah, offset, "ath9k-gpio"); + + return 0; +} @@ -74,12 +58,11 @@ Signed-off-by: Felix Fietkau +static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset, + int value) +{ -+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -+ gchip); ++ struct ath_softc *sc = gpiochip_get_data(chip); + -+ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio", ++ ath9k_hw_gpio_request_out(sc->sc_ah, offset, "ath9k-gpio", + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); ++ ath9k_hw_set_gpio(sc->sc_ah, offset, value); + + return 0; +} @@ -87,9 +70,8 @@ Signed-off-by: Felix Fietkau +/* gpio_chip handler : query GPIO direction (0=out, 1=in) */ +static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset) +{ -+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -+ gchip); -+ struct ath_hw *ah = gc->sc->sc_ah; ++ struct ath_softc *sc = gpiochip_get_data(chip); ++ struct ath_hw *ah = sc->sc_ah; + + return !((REG_READ(ah, AR_GPIO_OE_OUT(ah)) >> (offset * 2)) & 3); +} @@ -97,69 +79,59 @@ Signed-off-by: Felix Fietkau +/* gpio_chip handler : get GPIO pin value */ +static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset) +{ -+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -+ gchip); ++ struct ath_softc *sc = gpiochip_get_data(chip); + -+ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset); ++ return ath9k_hw_gpio_get(sc->sc_ah, offset); +} + +/* gpio_chip handler : set GPIO pin to value */ +static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset, + int value) +{ -+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -+ gchip); ++ struct ath_softc *sc = gpiochip_get_data(chip); + -+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); ++ ath9k_hw_set_gpio(sc->sc_ah, offset, value); +} + +/* register GPIO chip */ +static void ath9k_register_gpio_chip(struct ath_softc *sc) +{ -+ struct ath9k_gpio_chip *gc; ++ struct gpio_chip *gc = sc->gpiochip; + struct ath_hw *ah = sc->sc_ah; + -+ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL); ++ gc = kzalloc(sizeof(struct gpio_chip), GFP_KERNEL); + if (!gc) + return; + -+ gc->sc = sc; -+ snprintf(gc->label, sizeof(gc->label), "ath9k-%s", -+ wiphy_name(sc->hw->wiphy)); -+#ifdef CONFIG_OF -+ gc->gchip.parent = sc->dev; -+#endif -+ gc->gchip.label = gc->label; -+ gc->gchip.base = -1; /* determine base automatically */ -+ gc->gchip.ngpio = ah->caps.num_gpio_pins; -+ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input; -+ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output; -+ gc->gchip.get_direction = ath9k_gpio_pin_get_dir; -+ gc->gchip.get = ath9k_gpio_pin_get; -+ gc->gchip.set = ath9k_gpio_pin_set; ++ gc->label = kasprintf(GFP_KERNEL, "ath9k-%s", ++ wiphy_name(sc->hw->wiphy)); ++ gc->parent = sc->dev; ++ gc->base = -1; /* determine base automatically */ ++ gc->ngpio = ah->caps.num_gpio_pins; ++ gc->direction_input = ath9k_gpio_pin_cfg_input; ++ gc->direction_output = ath9k_gpio_pin_cfg_output; ++ gc->get_direction = ath9k_gpio_pin_get_dir; ++ gc->get = ath9k_gpio_pin_get; ++ gc->set = ath9k_gpio_pin_set; + -+ if (gpiochip_add(&gc->gchip)) { ++ if (gpiochip_add_data(gc, sc)) { ++ kfree(gc->label); + kfree(gc); + return; + } -+ -+#ifdef CONFIG_OF -+ gc->gchip.owner = NULL; -+#endif -+ sc->gpiochip = gc; +} + +/* remove GPIO chip */ +static void ath9k_unregister_gpio_chip(struct ath_softc *sc) +{ -+ struct ath9k_gpio_chip *gc = sc->gpiochip; ++ struct gpio_chip *gc = sc->gpiochip; + + if (!gc) + return; + -+ gpiochip_remove(&gc->gchip); ++ gpiochip_remove(gc); ++ kfree(gc->label); + kfree(gc); -+ sc->gpiochip = NULL; +} + +#else /* CONFIG_GPIOLIB */ @@ -173,7 +145,7 @@ Signed-off-by: Felix Fietkau +} + +#endif /* CONFIG_GPIOLIB */ - ++ /********************************/ /* LED functions */ /********************************/ @@ -183,27 +155,27 @@ Signed-off-by: Felix Fietkau static void ath_fill_led_pin(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; -@@ -80,6 +202,12 @@ static int ath_add_led(struct ath_softc +@@ -80,6 +188,12 @@ static int ath_add_led(struct ath_softc else ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); +#ifdef CONFIG_GPIOLIB + /* If there is GPIO chip configured, reserve LED pin */ + if (sc->gpiochip) -+ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name); ++ sc->gpiodesc = gpiod_get(sc->dev, gpio->name, GPIOD_ASIS); +#endif + return 0; } -@@ -136,17 +264,24 @@ void ath_deinit_leds(struct ath_softc *s +@@ -136,17 +250,24 @@ void ath_deinit_leds(struct ath_softc *s while (!list_empty(&sc->leds)) { led = list_first_entry(&sc->leds, struct ath_led, list); +#ifdef CONFIG_GPIOLIB + /* If there is GPIO chip configured, free LED pin */ + if (sc->gpiochip) -+ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio); ++ gpiod_put(sc->gpiodesc); +#endif list_del(&led->list); ath_led_brightness(&led->cdev, LED_OFF); @@ -221,7 +193,7 @@ Signed-off-by: Felix Fietkau char led_name[32]; const char *trigger; int i; -@@ -156,6 +291,15 @@ void ath_init_leds(struct ath_softc *sc) +@@ -156,6 +277,15 @@ void ath_init_leds(struct ath_softc *sc) if (AR_SREV_9100(sc->sc_ah)) return; @@ -237,11 +209,3 @@ Signed-off-by: Felix Fietkau ath_fill_led_pin(sc); if (pdata && pdata->leds && pdata->num_leds) -@@ -180,6 +324,7 @@ void ath_init_leds(struct ath_softc *sc) - ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, - !sc->sc_ah->config.led_active_high); - } -+ - #endif - - /*******************/ diff --git a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch index d164d89031..83f7a146e3 100644 --- a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch +++ b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch @@ -10,27 +10,27 @@ Signed-off-by: Felix Fietkau --- --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -1057,6 +1057,7 @@ struct ath_softc { - struct list_head leds; +@@ -1051,6 +1051,7 @@ struct ath_softc { #ifdef CONFIG_GPIOLIB - struct ath9k_gpio_chip *gpiochip; + struct gpio_chip *gpiochip; + struct gpio_desc *gpiodesc; + struct platform_device *btnpdev; /* gpio-keys-polled */ #endif #endif --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -17,6 +17,8 @@ +@@ -16,6 +16,8 @@ + #include "ath9k.h" #include - #include +#include +#include #ifdef CPTCFG_MAC80211_LEDS -@@ -129,6 +131,67 @@ static void ath9k_unregister_gpio_chip(s - sc->gpiochip = NULL; +@@ -115,6 +117,67 @@ static void ath9k_unregister_gpio_chip(s + kfree(gc); } +/******************/ @@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau + + ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio, + "ath9k-gpio"); -+ bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio; ++ bt[i].gpio = sc->gpiochip->base + pdata->btns[i].gpio; + } + + memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); @@ -97,7 +97,7 @@ Signed-off-by: Felix Fietkau #else /* CONFIG_GPIOLIB */ static inline void ath9k_register_gpio_chip(struct ath_softc *sc) -@@ -139,6 +202,14 @@ static inline void ath9k_unregister_gpio +@@ -125,6 +188,14 @@ static inline void ath9k_unregister_gpio { } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau #endif /* CONFIG_GPIOLIB */ /********************************/ -@@ -262,6 +333,7 @@ void ath_deinit_leds(struct ath_softc *s +@@ -248,6 +319,7 @@ void ath_deinit_leds(struct ath_softc *s { struct ath_led *led; @@ -120,7 +120,7 @@ Signed-off-by: Felix Fietkau while (!list_empty(&sc->leds)) { led = list_first_entry(&sc->leds, struct ath_led, list); #ifdef CONFIG_GPIOLIB -@@ -301,6 +373,7 @@ void ath_init_leds(struct ath_softc *sc) +@@ -287,6 +359,7 @@ void ath_init_leds(struct ath_softc *sc) } ath_fill_led_pin(sc); diff --git a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch index 3adc8bb8d6..0e4407b439 100644 --- a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch +++ b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch @@ -264,15 +264,15 @@ }; --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -26,6 +26,7 @@ - #include +@@ -27,6 +27,7 @@ #include #include + #include +#include #include "common.h" #include "debug.h" -@@ -1013,6 +1014,9 @@ struct ath_softc { +@@ -1006,6 +1007,9 @@ struct ath_softc { struct ath_hw *sc_ah; void __iomem *mem; int irq; From baf73daaacdef46307454bc5d507c31d9033c01c Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 31 Dec 2024 14:09:44 -0800 Subject: [PATCH 09/14] mac80211: ath9k: remove platform leds These only work with and are useful with mach files. Now that those are gone, this can go too. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/17445 Signed-off-by: Robert Marko --- .../ath9k/531-ath9k_extra_platform_leds.patch | 64 ------------------- .../ath9k/547-ath9k_led_defstate_fix.patch | 2 +- .../ath9k/548-ath9k_enable_gpio_chip.patch | 15 ++--- .../ath9k/549-ath9k_enable_gpio_buttons.patch | 17 ++--- .../files/include/linux/ath9k_platform.h | 3 - 5 files changed, 17 insertions(+), 84 deletions(-) delete mode 100644 package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch diff --git a/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch deleted file mode 100644 index 1055bd335c..0000000000 --- a/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/gpio.c -+++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -15,6 +15,7 @@ - */ - - #include "ath9k.h" -+#include - - /********************************/ - /* LED functions */ -@@ -108,6 +109,24 @@ int ath_create_gpio_led(struct ath_softc - return ret; - } - -+static int ath_create_platform_led(struct ath_softc *sc, -+ const struct gpio_led *gpio) -+{ -+ struct ath_led *led; -+ int ret; -+ -+ led = kzalloc(sizeof(*led), GFP_KERNEL); -+ if (!led) -+ return -ENOMEM; -+ -+ led->gpio = gpio; -+ ret = ath_add_led(sc, led); -+ if (ret < 0) -+ kfree(led); -+ -+ return ret; -+} -+ - void ath_deinit_leds(struct ath_softc *sc) - { - struct ath_led *led; -@@ -124,8 +143,10 @@ void ath_deinit_leds(struct ath_softc *s - - void ath_init_leds(struct ath_softc *sc) - { -+ struct ath9k_platform_data *pdata = sc->dev->platform_data; - char led_name[32]; - const char *trigger; -+ int i; - - INIT_LIST_HEAD(&sc->leds); - -@@ -134,6 +155,17 @@ void ath_init_leds(struct ath_softc *sc) - - ath_fill_led_pin(sc); - -+ if (pdata && pdata->leds && pdata->num_leds) -+ for (i = 0; i < pdata->num_leds; i++) { -+ if (pdata->leds[i].gpio == sc->sc_ah->led_pin) -+ sc->sc_ah->led_pin = -1; -+ -+ ath_create_platform_led(sc, &pdata->leds[i]); -+ } -+ -+ if (sc->sc_ah->led_pin < 0) -+ return; -+ - snprintf(led_name, sizeof(led_name), "ath9k-%s", - wiphy_name(sc->hw->wiphy)); - diff --git a/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch index 5d84cf0c42..d633c051b0 100644 --- a/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch +++ b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch @@ -13,7 +13,7 @@ Signed-off-by: Michal Cieslakiewicz --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -74,8 +74,11 @@ static int ath_add_led(struct ath_softc +@@ -73,8 +73,11 @@ static int ath_add_led(struct ath_softc ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); diff --git a/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch index 9696ea5c88..288948c838 100644 --- a/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch +++ b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch @@ -32,9 +32,9 @@ Signed-off-by: Felix Fietkau #ifdef CPTCFG_ATH9K_DEBUGFS --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -17,12 +17,120 @@ +@@ -16,12 +16,120 @@ + #include "ath9k.h" - #include +#ifdef CPTCFG_MAC80211_LEDS + @@ -155,7 +155,7 @@ Signed-off-by: Felix Fietkau static void ath_fill_led_pin(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; -@@ -80,6 +188,12 @@ static int ath_add_led(struct ath_softc +@@ -79,6 +187,12 @@ static int ath_add_led(struct ath_softc else ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); @@ -168,7 +168,7 @@ Signed-off-by: Felix Fietkau return 0; } -@@ -136,17 +250,24 @@ void ath_deinit_leds(struct ath_softc *s +@@ -117,16 +231,23 @@ void ath_deinit_leds(struct ath_softc *s while (!list_empty(&sc->leds)) { led = list_first_entry(&sc->leds, struct ath_led, list); @@ -188,12 +188,11 @@ Signed-off-by: Felix Fietkau void ath_init_leds(struct ath_softc *sc) { - struct ath9k_platform_data *pdata = sc->dev->platform_data; + struct device_node *np = sc->dev->of_node; char led_name[32]; const char *trigger; - int i; -@@ -156,6 +277,15 @@ void ath_init_leds(struct ath_softc *sc) + +@@ -135,6 +256,15 @@ void ath_init_leds(struct ath_softc *sc) if (AR_SREV_9100(sc->sc_ah)) return; @@ -208,4 +207,4 @@ Signed-off-by: Felix Fietkau + ath_fill_led_pin(sc); - if (pdata && pdata->leds && pdata->num_leds) + snprintf(led_name, sizeof(led_name), "ath9k-%s", diff --git a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch index 83f7a146e3..5a8c057b31 100644 --- a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch +++ b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch @@ -20,16 +20,17 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -16,6 +16,8 @@ +@@ -15,6 +15,9 @@ + */ #include "ath9k.h" - #include ++#include +#include +#include #ifdef CPTCFG_MAC80211_LEDS -@@ -115,6 +117,67 @@ static void ath9k_unregister_gpio_chip(s +@@ -114,6 +117,67 @@ static void ath9k_unregister_gpio_chip(s kfree(gc); } @@ -97,7 +98,7 @@ Signed-off-by: Felix Fietkau #else /* CONFIG_GPIOLIB */ static inline void ath9k_register_gpio_chip(struct ath_softc *sc) -@@ -125,6 +188,14 @@ static inline void ath9k_unregister_gpio +@@ -124,6 +188,14 @@ static inline void ath9k_unregister_gpio { } @@ -112,7 +113,7 @@ Signed-off-by: Felix Fietkau #endif /* CONFIG_GPIOLIB */ /********************************/ -@@ -248,6 +319,7 @@ void ath_deinit_leds(struct ath_softc *s +@@ -229,6 +301,7 @@ void ath_deinit_leds(struct ath_softc *s { struct ath_led *led; @@ -120,11 +121,11 @@ Signed-off-by: Felix Fietkau while (!list_empty(&sc->leds)) { led = list_first_entry(&sc->leds, struct ath_led, list); #ifdef CONFIG_GPIOLIB -@@ -287,6 +359,7 @@ void ath_init_leds(struct ath_softc *sc) +@@ -266,6 +339,7 @@ void ath_init_leds(struct ath_softc *sc) } ath_fill_led_pin(sc); + ath9k_init_buttons(sc); - if (pdata && pdata->leds && pdata->num_leds) - for (i = 0; i < pdata->num_leds; i++) { + snprintf(led_name, sizeof(led_name), "ath9k-%s", + wiphy_name(sc->hw->wiphy)); diff --git a/target/linux/generic/files/include/linux/ath9k_platform.h b/target/linux/generic/files/include/linux/ath9k_platform.h index e210108568..c4389b7e6c 100644 --- a/target/linux/generic/files/include/linux/ath9k_platform.h +++ b/target/linux/generic/files/include/linux/ath9k_platform.h @@ -47,9 +47,6 @@ struct ath9k_platform_data { bool use_eeprom; - int num_leds; - const struct gpio_led *leds; - unsigned num_btns; const struct gpio_keys_button *btns; unsigned btn_poll_interval; From d70f8dea1ec5d5de34cf294d42520747247de387 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 31 Dec 2024 14:37:45 -0800 Subject: [PATCH 10/14] mac80211: ath9k: remove gpio buttons support This is only used by mach files, which are no longer used in OpenWrt. Allows removing a custon ath9k_platform.h file. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/17445 Signed-off-by: Robert Marko --- .../ath9k/549-ath9k_enable_gpio_buttons.patch | 131 ------------------ .../files/include/linux/ath9k_platform.h | 55 -------- 2 files changed, 186 deletions(-) delete mode 100644 package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch delete mode 100644 target/linux/generic/files/include/linux/ath9k_platform.h diff --git a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch deleted file mode 100644 index 5a8c057b31..0000000000 --- a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch +++ /dev/null @@ -1,131 +0,0 @@ -From: Michal Cieslakiewicz -Subject: [PATCH v5 5/8] mac80211: ath9k: enable GPIO buttons - -Enable platform-defined GPIO button support for ath9k device. -Key poller is activated for attached platform buttons. -Requires ath9k GPIO chip access. - -Signed-off-by: Michal Cieslakiewicz -Signed-off-by: Felix Fietkau ---- ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -1051,6 +1051,7 @@ struct ath_softc { - #ifdef CONFIG_GPIOLIB - struct gpio_chip *gpiochip; - struct gpio_desc *gpiodesc; -+ struct platform_device *btnpdev; /* gpio-keys-polled */ - #endif - #endif - ---- a/drivers/net/wireless/ath/ath9k/gpio.c -+++ b/drivers/net/wireless/ath/ath9k/gpio.c -@@ -15,6 +15,9 @@ - */ - - #include "ath9k.h" -+#include -+#include -+#include - - #ifdef CPTCFG_MAC80211_LEDS - -@@ -114,6 +117,67 @@ static void ath9k_unregister_gpio_chip(s - kfree(gc); - } - -+/******************/ -+/* GPIO Buttons */ -+/******************/ -+ -+/* add GPIO buttons */ -+static void ath9k_init_buttons(struct ath_softc *sc) -+{ -+ struct ath9k_platform_data *pdata = sc->dev->platform_data; -+ struct platform_device *pdev; -+ struct gpio_keys_platform_data gkpdata; -+ struct gpio_keys_button *bt; -+ int i; -+ -+ if (!sc->gpiochip) -+ return; -+ -+ if (!pdata || !pdata->btns || !pdata->num_btns) -+ return; -+ -+ bt = devm_kmemdup(sc->dev, pdata->btns, -+ pdata->num_btns * sizeof(struct gpio_keys_button), -+ GFP_KERNEL); -+ if (!bt) -+ return; -+ -+ for (i = 0; i < pdata->num_btns; i++) { -+ if (pdata->btns[i].gpio == sc->sc_ah->led_pin) -+ sc->sc_ah->led_pin = -1; -+ -+ ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio, -+ "ath9k-gpio"); -+ bt[i].gpio = sc->gpiochip->base + pdata->btns[i].gpio; -+ } -+ -+ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); -+ gkpdata.buttons = bt; -+ gkpdata.nbuttons = pdata->num_btns; -+ gkpdata.poll_interval = pdata->btn_poll_interval; -+ -+ pdev = platform_device_register_data(sc->dev, "gpio-keys-polled", -+ PLATFORM_DEVID_AUTO, &gkpdata, -+ sizeof(gkpdata)); -+ if (!IS_ERR_OR_NULL(pdev)) -+ sc->btnpdev = pdev; -+ else { -+ sc->btnpdev = NULL; -+ devm_kfree(sc->dev, bt); -+ } -+} -+ -+/* remove GPIO buttons */ -+static void ath9k_deinit_buttons(struct ath_softc *sc) -+{ -+ if (!sc->gpiochip || !sc->btnpdev) -+ return; -+ -+ platform_device_unregister(sc->btnpdev); -+ -+ sc->btnpdev = NULL; -+} -+ - #else /* CONFIG_GPIOLIB */ - - static inline void ath9k_register_gpio_chip(struct ath_softc *sc) -@@ -124,6 +188,14 @@ static inline void ath9k_unregister_gpio - { - } - -+static inline void ath9k_init_buttons(struct ath_softc *sc) -+{ -+} -+ -+static inline void ath9k_deinit_buttons(struct ath_softc *sc) -+{ -+} -+ - #endif /* CONFIG_GPIOLIB */ - - /********************************/ -@@ -229,6 +301,7 @@ void ath_deinit_leds(struct ath_softc *s - { - struct ath_led *led; - -+ ath9k_deinit_buttons(sc); - while (!list_empty(&sc->leds)) { - led = list_first_entry(&sc->leds, struct ath_led, list); - #ifdef CONFIG_GPIOLIB -@@ -266,6 +339,7 @@ void ath_init_leds(struct ath_softc *sc) - } - - ath_fill_led_pin(sc); -+ ath9k_init_buttons(sc); - - snprintf(led_name, sizeof(led_name), "ath9k-%s", - wiphy_name(sc->hw->wiphy)); diff --git a/target/linux/generic/files/include/linux/ath9k_platform.h b/target/linux/generic/files/include/linux/ath9k_platform.h deleted file mode 100644 index c4389b7e6c..0000000000 --- a/target/linux/generic/files/include/linux/ath9k_platform.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2008 Atheros Communications Inc. - * Copyright (c) 2009 Gabor Juhos - * Copyright (c) 2009 Imre Kaloz - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _LINUX_ATH9K_PLATFORM_H -#define _LINUX_ATH9K_PLATFORM_H - -#define ATH9K_PLAT_EEP_MAX_WORDS 2048 - -struct ath9k_platform_data { - const char *eeprom_name; - - u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS]; - u8 *macaddr; - - int led_pin; - u32 gpio_mask; - u32 gpio_val; - - u32 bt_active_pin; - u32 bt_priority_pin; - u32 wlan_active_pin; - - bool endian_check; - bool is_clk_25mhz; - bool tx_gain_buffalo; - bool disable_2ghz; - bool disable_5ghz; - bool led_active_high; - - int (*get_mac_revision)(void); - int (*external_reset)(void); - - bool use_eeprom; - - unsigned num_btns; - const struct gpio_keys_button *btns; - unsigned btn_poll_interval; -}; - -#endif /* _LINUX_ATH9K_PLATFORM_H */ From 0ac79009dd3433d5e92a8311beae1041f39c3b79 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Wed, 1 Jan 2025 11:21:49 -0800 Subject: [PATCH 11/14] ath79: fix GPIO numbering with ath9k ath9k base starts at 512. This is a problem as it uses gpio_request_one to request the GPIO, which is legacy API. This upstream pending patch needs to also be ported to mac80211. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/17445 Signed-off-by: Robert Marko --- .../341-wifi-ath9k-obtain-system-gpios.patch | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 target/linux/ath79/patches-6.6/341-wifi-ath9k-obtain-system-gpios.patch diff --git a/target/linux/ath79/patches-6.6/341-wifi-ath9k-obtain-system-gpios.patch b/target/linux/ath79/patches-6.6/341-wifi-ath9k-obtain-system-gpios.patch new file mode 100644 index 0000000000..a43e3537e6 --- /dev/null +++ b/target/linux/ath79/patches-6.6/341-wifi-ath9k-obtain-system-gpios.patch @@ -0,0 +1,233 @@ +From patchwork Tue Apr 23 12:12:33 2024 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Linus Walleij +X-Patchwork-Id: 1926515 +Return-Path: + +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@legolas.ozlabs.org +Authentication-Results: legolas.ozlabs.org; + dkim=pass (2048-bit key; + unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 + header.s=google header.b=qX99TQMM; + dkim-atps=neutral +Authentication-Results: legolas.ozlabs.org; + spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org + (client-ip=2604:1380:45e3:2400::1; helo=sv.mirrors.kernel.org; + envelope-from=linux-gpio+bounces-5755-incoming=patchwork.ozlabs.org@vger.kernel.org; + receiver=patchwork.ozlabs.org) +Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org + [IPv6:2604:1380:45e3:2400::1]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature ECDSA (secp384r1)) + (No client certificate requested) + by legolas.ozlabs.org (Postfix) with ESMTPS id 4VP1Gc6RZKz1yZP + for ; Tue, 23 Apr 2024 22:12:56 +1000 (AEST) +Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org + [52.25.139.140]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by sv.mirrors.kernel.org (Postfix) with ESMTPS id 5BB9C28522A + for ; Tue, 23 Apr 2024 12:12:55 +0000 (UTC) +Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) + by smtp.subspace.kernel.org (Postfix) with ESMTP id 2F83B8563D; + Tue, 23 Apr 2024 12:12:41 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org + header.b="qX99TQMM" +X-Original-To: linux-gpio@vger.kernel.org +Received: from mail-lj1-f179.google.com (mail-lj1-f179.google.com + [209.85.208.179]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8F3C82865 + for ; Tue, 23 Apr 2024 12:12:37 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; + arc=none smtp.client-ip=209.85.208.179 +ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1713874361; cv=none; + b=d6RcvcAu8hBYAK8Io489ZHQpJVXPwuokP6iMcAkbvElCerbXD6jAdqdi+RjDlo5C49GHGO4FQ19UwQn/VE//qSwiK1ulTSBp3OkvAmyb7yYAFnDs9AVNWRw+5/NxeFNn3fj5PyvqVymIbaJKabfrOVNwkz/5JMHxEIJtr6Crmog= +ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1713874361; c=relaxed/simple; + bh=0eXJ5AIjzz1TBGZ8SlshIPrEHZaZwZfYEdof+dSpu4Y=; + h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; + b=EfFtruUxRIGy+jylEiJ2rPEyPCjGCc8ptT9FVxe6s0O/kW38Y6196xVQeiSV2tSKVCEOIO+9HoqmpgdKsJE7gU9++EcrasP96MYpsklYpc2zsWW3b8QEhfxfZ9Ai/idyYihE2u9dQ7a143P/Ij/twDrZTt24wO/mtHDrE5XcCFI= +ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; + dmarc=pass (p=none dis=none) header.from=linaro.org; + spf=pass smtp.mailfrom=linaro.org; + dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org + header.b=qX99TQMM; arc=none smtp.client-ip=209.85.208.179 +Authentication-Results: smtp.subspace.kernel.org; + dmarc=pass (p=none dis=none) header.from=linaro.org +Authentication-Results: smtp.subspace.kernel.org; + spf=pass smtp.mailfrom=linaro.org +Received: by mail-lj1-f179.google.com with SMTP id + 38308e7fff4ca-2dd041acff1so40839131fa.1 + for ; + Tue, 23 Apr 2024 05:12:37 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=linaro.org; s=google; t=1713874356; x=1714479156; + darn=vger.kernel.org; + h=cc:to:message-id:content-transfer-encoding:mime-version:subject + :date:from:from:to:cc:subject:date:message-id:reply-to; + bh=vysJsMiH5IVqdTs4yMwZxZ7nUmt2aG7eBhkn8qm8hvI=; + b=qX99TQMMdHbskFYUaw8c93sIJsUhKmj/WPdyahHcupUhwn5wol4aVoPczkOKYwJZhE + eoInxzjAHIl3UNKyvPPrD4MrbLcSoFT6mTFMsgRQYUghsLattmGcqIebu9XT556dBhsf + DydmpqGgnTOIa+IEknFxg24mo8Xn2LVmDC7LSGEYykUy1xLHd1NSq56YEaYXC7641xeZ + 9TOL0rZszeGld5cCS3013EmEeXQGCC3lAP83Eb48vbFXjPojkN0s40rZ2s8YpVsGT0iP + LeLVtP/E8XJqi4YipKryKSgbgOvQ1Bclle5+s+2qcJQNnSEjekMwR59BIRs3OZH2SRfN + gQdQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1713874356; x=1714479156; + h=cc:to:message-id:content-transfer-encoding:mime-version:subject + :date:from:x-gm-message-state:from:to:cc:subject:date:message-id + :reply-to; + bh=vysJsMiH5IVqdTs4yMwZxZ7nUmt2aG7eBhkn8qm8hvI=; + b=jEBH4NQ7SzFi2tnb1lgL06IchnBJoscNgKesjlorvou6X/9wDE/VbgxNFKR0zWwdTk + BEjG/ifFJxLmM9jdaCKu5cJc4yiDNXp7yZd48D71V34zJ4aINAGAx4hcOKqf95neFknx + nsFPpBFnTYFEpCLF0TebVoL6h6ehPzSojmkArzsrMppNvW2cwJ5gDlkqy2y4SezLanmM + 6iU0ksnwE0bb2iLkahhgo00Ejt33yqxwa+3xBfhOe9oYKSSZYnY7qVq055SSwt9IAq+H + REGyJN+GrvupTHagiioYe3LPXDPdOui9ZixXXDllw1t1yGUy+TkJu8xSqtvHEfg81FHP + AxtA== +X-Forwarded-Encrypted: i=1; + AJvYcCUbxzPklfPYrLgyY1I0ycuj7Dh04dcGVonYocA2mzxzlAEV107o0ELlFqr3O9Td+tV/t0eV9ly9YAbTY6n1XPnFXS5dsYYAZw6RHw== +X-Gm-Message-State: AOJu0YxsC7zdakTzntbiRFnN2A7yTrR0x+IpR6ce6eGn5kHeqIBi1km+ + zTVpRulbch3JsmzVDbCbbAAYoBkNgEA568YL6zdjVARnvFwNz1cqatOrR1AXUm0= +X-Google-Smtp-Source: + AGHT+IHBRMGvaJM98f86Z6m/RfVhK2XejjNGF3EvcRq/4x3oGM0DKpd2PbeCJdgmzHjLPVVbdsNzJg== +X-Received: by 2002:a2e:9852:0:b0:2d8:a98d:18e with SMTP id + e18-20020a2e9852000000b002d8a98d018emr7955886ljj.8.1713874355700; + Tue, 23 Apr 2024 05:12:35 -0700 (PDT) +Received: from [192.168.1.140] ([85.235.12.238]) + by smtp.gmail.com with ESMTPSA id + x6-20020a2e7c06000000b002da179d8d25sm1628982ljc.64.2024.04.23.05.12.33 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Tue, 23 Apr 2024 05:12:35 -0700 (PDT) +From: Linus Walleij +Date: Tue, 23 Apr 2024 14:12:33 +0200 +Subject: [PATCH v2] wifi: ath9k: Obtain system GPIOS from descriptors +Precedence: bulk +X-Mailing-List: linux-gpio@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +Message-Id: <20240423-descriptors-wireless-v2-1-6d1d03b30bfa@linaro.org> +X-B4-Tracking: v=1; b=H4sIALClJ2YC/22Nyw6CMBBFf4XM2hpanrLyPwyL0o4wCaFkxqCG9 + N+txKXLc5Nz7g6CTCjQZTswbiQUlgTmlIGb7DKiIp8YTG7KXBujPIpjWh+BRT2JcUYRNbTeXir + v7FBUkNSV8U6vI3vrE08kSXgfL5v+rr9gof8HN61yhdo1rvJ125T1dabFcjgHHqGPMX4Ao4iiN + LkAAAA= +To: Kalle Valo , + Andy Shevchenko , + Arnd Bergmann , Alban Bedel , + Bartosz Golaszewski , =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rg?= + =?utf-8?q?ensen?= +Cc: linux-wireless@vger.kernel.org, brcm80211-dev-list.pdl@broadcom.com, + linux-gpio@vger.kernel.org, Linus Walleij +X-Mailer: b4 0.13.0 + +The ath9k has an odd use of system-wide GPIOs: if the chip +does not have internal GPIO capability, it will try to obtain a +GPIO line from the system GPIO controller: + + if (BIT(gpio) & ah->caps.gpio_mask) + ath9k_hw_gpio_cfg_wmac(...); + else if (AR_SREV_SOC(ah)) + ath9k_hw_gpio_cfg_soc(ah, gpio, out, label); + +Where ath9k_hw_gpio_cfg_soc() will attempt to issue +gpio_request_one() passing the local GPIO number of the controller +(0..31) to gpio_request_one(). + +This is somewhat peculiar and possibly even dangerous: there is +nowadays no guarantee of the numbering of these system-wide +GPIOs, and assuming that GPIO 0..31 as used by ath9k would +correspond to GPIOs 0..31 on the system as a whole seems a bit +wild. + +Register all 32 GPIOs at index 0..31 directly in the ATH79K +GPIO driver and associate with WIFI if and only if we are probing +ATH79K wifi from the AHB bus (used for SoCs). + +Signed-off-by: Linus Walleij +--- +Changes in v2: +- Define all the descriptors directly in the ATH79K + GPIO driver in case the driver want to request them directly. +- Link to v1: https://lore.kernel.org/r/20240131-descriptors-wireless-v1-0-e1c7c5d68746@linaro.org +--- + drivers/gpio/gpio-ath79.c | 47 ++++++++++++++++++++++++++++++++++++- + drivers/net/wireless/ath/ath9k/hw.c | 29 ++++++++++++----------- + drivers/net/wireless/ath/ath9k/hw.h | 3 ++- + 3 files changed, 63 insertions(+), 16 deletions(-) + + +--- +base-commit: 4cece764965020c22cff7665b18a012006359095 +change-id: 20240122-descriptors-wireless-b8da95dcab35 + +Best regards, + +--- a/drivers/gpio/gpio-ath79.c ++++ b/drivers/gpio/gpio-ath79.c +@@ -9,6 +9,7 @@ + */ + + #include ++#include /* For WLAN GPIOs */ + #include + #include + #include +@@ -222,6 +223,37 @@ static const struct of_device_id ath79_g + }; + MODULE_DEVICE_TABLE(of, ath79_gpio_of_match); + ++/* ++ * This registers all of the ath79k GPIOs as descriptors to be picked ++ * directly from the ATH79K wifi driver if the two are jitted together ++ * in the same SoC. ++ */ ++#define ATH79K_WIFI_DESCS 32 ++static int ath79_gpio_register_wifi_descriptors(struct device *dev, ++ const char *label) ++{ ++ struct gpiod_lookup_table *lookup; ++ int i; ++ ++ /* Create a gpiod lookup using gpiochip-local offsets + 1 for NULL */ ++ lookup = devm_kzalloc(dev, ++ struct_size(lookup, table, ATH79K_WIFI_DESCS + 1), ++ GFP_KERNEL); ++ ++ if (!lookup) ++ return -ENOMEM; ++ ++ for (i = 0; i < ATH79K_WIFI_DESCS; i++) { ++ lookup->table[i] = (struct gpiod_lookup) ++ GPIO_LOOKUP_IDX(label, i, "ath9k", i, ++ GPIO_ACTIVE_HIGH); ++ } ++ ++ gpiod_add_lookup_table(lookup); ++ ++ return 0; ++} ++ + static int ath79_gpio_probe(struct platform_device *pdev) + { + struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); +@@ -289,7 +321,11 @@ static int ath79_gpio_probe(struct platf + girq->handler = handle_simple_irq; + } + +- return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); ++ err = devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); ++ if (err) ++ return err; ++ ++ return ath79_gpio_register_wifi_descriptors(dev, ctrl->gc.label); + } + + static struct platform_driver ath79_gpio_driver = { From 8534844847d47d1f883012c0297422d5611c7e83 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Wed, 1 Jan 2025 11:26:16 -0800 Subject: [PATCH 12/14] mac80211: fix led-pin usage ath9k uses a deprecated GPIO API that assumes a starting base of 0. This is no longer the case and so must be fixed. Upstream pending patch. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/17445 Signed-off-by: Robert Marko --- .../341-wifi-ath9k-obtain-system-gpios.patch | 273 ++++++++++++++++++ ...erpret-requested-txpower-in-EIRP-dom.patch | 4 +- ...power-reduction-for-US-regulatory-do.patch | 2 +- .../patches/ath9k/513-ath9k_add_pci_ids.patch | 2 +- .../ath9k/542-ath9k_debugfs_diag.patch | 4 +- 5 files changed, 279 insertions(+), 6 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath9k/341-wifi-ath9k-obtain-system-gpios.patch diff --git a/package/kernel/mac80211/patches/ath9k/341-wifi-ath9k-obtain-system-gpios.patch b/package/kernel/mac80211/patches/ath9k/341-wifi-ath9k-obtain-system-gpios.patch new file mode 100644 index 0000000000..4feb748229 --- /dev/null +++ b/package/kernel/mac80211/patches/ath9k/341-wifi-ath9k-obtain-system-gpios.patch @@ -0,0 +1,273 @@ +From patchwork Tue Apr 23 12:12:33 2024 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Linus Walleij +X-Patchwork-Id: 1926515 +Return-Path: + +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@legolas.ozlabs.org +Authentication-Results: legolas.ozlabs.org; + dkim=pass (2048-bit key; + unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 + header.s=google header.b=qX99TQMM; + dkim-atps=neutral +Authentication-Results: legolas.ozlabs.org; + spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org + (client-ip=2604:1380:45e3:2400::1; helo=sv.mirrors.kernel.org; + envelope-from=linux-gpio+bounces-5755-incoming=patchwork.ozlabs.org@vger.kernel.org; + receiver=patchwork.ozlabs.org) +Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org + [IPv6:2604:1380:45e3:2400::1]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature ECDSA (secp384r1)) + (No client certificate requested) + by legolas.ozlabs.org (Postfix) with ESMTPS id 4VP1Gc6RZKz1yZP + for ; Tue, 23 Apr 2024 22:12:56 +1000 (AEST) +Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org + [52.25.139.140]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by sv.mirrors.kernel.org (Postfix) with ESMTPS id 5BB9C28522A + for ; Tue, 23 Apr 2024 12:12:55 +0000 (UTC) +Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) + by smtp.subspace.kernel.org (Postfix) with ESMTP id 2F83B8563D; + Tue, 23 Apr 2024 12:12:41 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org + header.b="qX99TQMM" +X-Original-To: linux-gpio@vger.kernel.org +Received: from mail-lj1-f179.google.com (mail-lj1-f179.google.com + [209.85.208.179]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8F3C82865 + for ; Tue, 23 Apr 2024 12:12:37 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; + arc=none smtp.client-ip=209.85.208.179 +ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1713874361; cv=none; + b=d6RcvcAu8hBYAK8Io489ZHQpJVXPwuokP6iMcAkbvElCerbXD6jAdqdi+RjDlo5C49GHGO4FQ19UwQn/VE//qSwiK1ulTSBp3OkvAmyb7yYAFnDs9AVNWRw+5/NxeFNn3fj5PyvqVymIbaJKabfrOVNwkz/5JMHxEIJtr6Crmog= +ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1713874361; c=relaxed/simple; + bh=0eXJ5AIjzz1TBGZ8SlshIPrEHZaZwZfYEdof+dSpu4Y=; + h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; + b=EfFtruUxRIGy+jylEiJ2rPEyPCjGCc8ptT9FVxe6s0O/kW38Y6196xVQeiSV2tSKVCEOIO+9HoqmpgdKsJE7gU9++EcrasP96MYpsklYpc2zsWW3b8QEhfxfZ9Ai/idyYihE2u9dQ7a143P/Ij/twDrZTt24wO/mtHDrE5XcCFI= +ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; + dmarc=pass (p=none dis=none) header.from=linaro.org; + spf=pass smtp.mailfrom=linaro.org; + dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org + header.b=qX99TQMM; arc=none smtp.client-ip=209.85.208.179 +Authentication-Results: smtp.subspace.kernel.org; + dmarc=pass (p=none dis=none) header.from=linaro.org +Authentication-Results: smtp.subspace.kernel.org; + spf=pass smtp.mailfrom=linaro.org +Received: by mail-lj1-f179.google.com with SMTP id + 38308e7fff4ca-2dd041acff1so40839131fa.1 + for ; + Tue, 23 Apr 2024 05:12:37 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=linaro.org; s=google; t=1713874356; x=1714479156; + darn=vger.kernel.org; + h=cc:to:message-id:content-transfer-encoding:mime-version:subject + :date:from:from:to:cc:subject:date:message-id:reply-to; + bh=vysJsMiH5IVqdTs4yMwZxZ7nUmt2aG7eBhkn8qm8hvI=; + b=qX99TQMMdHbskFYUaw8c93sIJsUhKmj/WPdyahHcupUhwn5wol4aVoPczkOKYwJZhE + eoInxzjAHIl3UNKyvPPrD4MrbLcSoFT6mTFMsgRQYUghsLattmGcqIebu9XT556dBhsf + DydmpqGgnTOIa+IEknFxg24mo8Xn2LVmDC7LSGEYykUy1xLHd1NSq56YEaYXC7641xeZ + 9TOL0rZszeGld5cCS3013EmEeXQGCC3lAP83Eb48vbFXjPojkN0s40rZ2s8YpVsGT0iP + LeLVtP/E8XJqi4YipKryKSgbgOvQ1Bclle5+s+2qcJQNnSEjekMwR59BIRs3OZH2SRfN + gQdQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1713874356; x=1714479156; + h=cc:to:message-id:content-transfer-encoding:mime-version:subject + :date:from:x-gm-message-state:from:to:cc:subject:date:message-id + :reply-to; + bh=vysJsMiH5IVqdTs4yMwZxZ7nUmt2aG7eBhkn8qm8hvI=; + b=jEBH4NQ7SzFi2tnb1lgL06IchnBJoscNgKesjlorvou6X/9wDE/VbgxNFKR0zWwdTk + BEjG/ifFJxLmM9jdaCKu5cJc4yiDNXp7yZd48D71V34zJ4aINAGAx4hcOKqf95neFknx + nsFPpBFnTYFEpCLF0TebVoL6h6ehPzSojmkArzsrMppNvW2cwJ5gDlkqy2y4SezLanmM + 6iU0ksnwE0bb2iLkahhgo00Ejt33yqxwa+3xBfhOe9oYKSSZYnY7qVq055SSwt9IAq+H + REGyJN+GrvupTHagiioYe3LPXDPdOui9ZixXXDllw1t1yGUy+TkJu8xSqtvHEfg81FHP + AxtA== +X-Forwarded-Encrypted: i=1; + AJvYcCUbxzPklfPYrLgyY1I0ycuj7Dh04dcGVonYocA2mzxzlAEV107o0ELlFqr3O9Td+tV/t0eV9ly9YAbTY6n1XPnFXS5dsYYAZw6RHw== +X-Gm-Message-State: AOJu0YxsC7zdakTzntbiRFnN2A7yTrR0x+IpR6ce6eGn5kHeqIBi1km+ + zTVpRulbch3JsmzVDbCbbAAYoBkNgEA568YL6zdjVARnvFwNz1cqatOrR1AXUm0= +X-Google-Smtp-Source: + AGHT+IHBRMGvaJM98f86Z6m/RfVhK2XejjNGF3EvcRq/4x3oGM0DKpd2PbeCJdgmzHjLPVVbdsNzJg== +X-Received: by 2002:a2e:9852:0:b0:2d8:a98d:18e with SMTP id + e18-20020a2e9852000000b002d8a98d018emr7955886ljj.8.1713874355700; + Tue, 23 Apr 2024 05:12:35 -0700 (PDT) +Received: from [192.168.1.140] ([85.235.12.238]) + by smtp.gmail.com with ESMTPSA id + x6-20020a2e7c06000000b002da179d8d25sm1628982ljc.64.2024.04.23.05.12.33 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Tue, 23 Apr 2024 05:12:35 -0700 (PDT) +From: Linus Walleij +Date: Tue, 23 Apr 2024 14:12:33 +0200 +Subject: [PATCH v2] wifi: ath9k: Obtain system GPIOS from descriptors +Precedence: bulk +X-Mailing-List: linux-gpio@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +Message-Id: <20240423-descriptors-wireless-v2-1-6d1d03b30bfa@linaro.org> +X-B4-Tracking: v=1; b=H4sIALClJ2YC/22Nyw6CMBBFf4XM2hpanrLyPwyL0o4wCaFkxqCG9 + N+txKXLc5Nz7g6CTCjQZTswbiQUlgTmlIGb7DKiIp8YTG7KXBujPIpjWh+BRT2JcUYRNbTeXir + v7FBUkNSV8U6vI3vrE08kSXgfL5v+rr9gof8HN61yhdo1rvJ125T1dabFcjgHHqGPMX4Ao4iiN + LkAAAA= +To: Kalle Valo , + Andy Shevchenko , + Arnd Bergmann , Alban Bedel , + Bartosz Golaszewski , =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rg?= + =?utf-8?q?ensen?= +Cc: linux-wireless@vger.kernel.org, brcm80211-dev-list.pdl@broadcom.com, + linux-gpio@vger.kernel.org, Linus Walleij +X-Mailer: b4 0.13.0 + +The ath9k has an odd use of system-wide GPIOs: if the chip +does not have internal GPIO capability, it will try to obtain a +GPIO line from the system GPIO controller: + + if (BIT(gpio) & ah->caps.gpio_mask) + ath9k_hw_gpio_cfg_wmac(...); + else if (AR_SREV_SOC(ah)) + ath9k_hw_gpio_cfg_soc(ah, gpio, out, label); + +Where ath9k_hw_gpio_cfg_soc() will attempt to issue +gpio_request_one() passing the local GPIO number of the controller +(0..31) to gpio_request_one(). + +This is somewhat peculiar and possibly even dangerous: there is +nowadays no guarantee of the numbering of these system-wide +GPIOs, and assuming that GPIO 0..31 as used by ath9k would +correspond to GPIOs 0..31 on the system as a whole seems a bit +wild. + +Register all 32 GPIOs at index 0..31 directly in the ATH79K +GPIO driver and associate with WIFI if and only if we are probing +ATH79K wifi from the AHB bus (used for SoCs). + +Signed-off-by: Linus Walleij +--- +Changes in v2: +- Define all the descriptors directly in the ATH79K + GPIO driver in case the driver want to request them directly. +- Link to v1: https://lore.kernel.org/r/20240131-descriptors-wireless-v1-0-e1c7c5d68746@linaro.org +--- + drivers/net/wireless/ath/ath9k/hw.c | 29 ++++++++++++----------- + drivers/net/wireless/ath/ath9k/hw.h | 3 ++- + 2 files changed, 32 insertions(+), 15 deletions(-) + + +--- +base-commit: 4cece764965020c22cff7665b18a012006359095 +change-id: 20240122-descriptors-wireless-b8da95dcab35 + +Best regards, + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include + #include + + #include "hw.h" +@@ -2727,19 +2727,25 @@ static void ath9k_hw_gpio_cfg_output_mux + static void ath9k_hw_gpio_cfg_soc(struct ath_hw *ah, u32 gpio, bool out, + const char *label) + { ++ enum gpiod_flags flags = out ? GPIOD_OUT_LOW : GPIOD_IN; ++ struct gpio_desc *gpiod; + int err; + +- if (ah->caps.gpio_requested & BIT(gpio)) ++ if (ah->gpiods[gpio]) + return; + +- err = devm_gpio_request_one(ah->dev, gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label); +- if (err) { ++ /* Obtains a system specific GPIO descriptor from another GPIO controller */ ++ gpiod = gpiod_get_index(NULL, "ath9k", gpio, flags); ++ ++ if (IS_ERR(gpiod)) { ++ err = PTR_ERR(gpiod); + ath_err(ath9k_hw_common(ah), "request GPIO%d failed:%d\n", + gpio, err); + return; + } + +- ah->caps.gpio_requested |= BIT(gpio); ++ gpiod_set_consumer_name(gpiod, label); ++ ah->gpiods[gpio] = gpiod; + } + + static void ath9k_hw_gpio_cfg_wmac(struct ath_hw *ah, u32 gpio, bool out, +@@ -2801,8 +2807,10 @@ void ath9k_hw_gpio_free(struct ath_hw *a + + WARN_ON(gpio >= ah->caps.num_gpio_pins); + +- if (ah->caps.gpio_requested & BIT(gpio)) +- ah->caps.gpio_requested &= ~BIT(gpio); ++ if (ah->gpiods[gpio]) { ++ gpiod_put(ah->gpiods[gpio]); ++ ah->gpiods[gpio] = NULL; ++ } + } + EXPORT_SYMBOL(ath9k_hw_gpio_free); + +@@ -2830,8 +2838,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, + val = REG_READ(ah, AR_GPIO_IN(ah)) & BIT(gpio); + else + val = MS_REG_READ(AR, gpio); +- } else if (BIT(gpio) & ah->caps.gpio_requested) { +- val = gpio_get_value(gpio) & BIT(gpio); ++ } else if (ah->gpiods[gpio]) { ++ val = gpiod_get_value(ah->gpiods[gpio]); + } else { + WARN_ON(1); + } +@@ -2854,8 +2862,8 @@ void ath9k_hw_set_gpio(struct ath_hw *ah + AR7010_GPIO_OUT : AR_GPIO_IN_OUT(ah); + + REG_RMW(ah, out_addr, val << gpio, BIT(gpio)); +- } else if (BIT(gpio) & ah->caps.gpio_requested) { +- gpio_set_value(gpio, val); ++ } else if (ah->gpiods[gpio]) { ++ gpiod_set_value(ah->gpiods[gpio], val); + } else { + WARN_ON(1); + } +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -19,6 +19,7 @@ + + #include + #include ++#include + #include + #include + +@@ -302,7 +303,6 @@ struct ath9k_hw_capabilities { + u8 max_rxchains; + u8 num_gpio_pins; + u32 gpio_mask; +- u32 gpio_requested; + u8 rx_hp_qdepth; + u8 rx_lp_qdepth; + u8 rx_status_len; +@@ -783,6 +783,7 @@ struct ath_hw { + struct ath9k_hw_capabilities caps; + struct ath9k_channel channels[ATH9K_NUM_CHANNELS]; + struct ath9k_channel *curchan; ++ struct gpio_desc *gpiods[32]; + + union { + struct ar5416_eeprom_def def; diff --git a/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch index 9016da963b..78ad7623b2 100644 --- a/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +++ b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch @@ -8,7 +8,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2975,7 +2975,8 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2983,7 +2983,8 @@ void ath9k_hw_apply_txpower(struct ath_h { struct ath_regulatory *reg = ath9k_hw_regulatory(ah); struct ieee80211_channel *channel; @@ -18,7 +18,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. u16 ctl = NO_CTL; if (!chan) -@@ -2987,9 +2988,14 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2995,9 +2996,14 @@ void ath9k_hw_apply_txpower(struct ath_h channel = chan->chan; chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER); new_pwr = min_t(int, chan_pwr, reg->power_limit); diff --git a/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch index 5e5f3e4f10..21563bdaf5 100644 --- a/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch +++ b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2994,6 +2994,10 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -3002,6 +3002,10 @@ void ath9k_hw_apply_txpower(struct ath_h if (ant_gain > max_gain) ant_reduction = ant_gain - max_gain; diff --git a/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch index 6b60d3c089..9e3f867344 100644 --- a/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch +++ b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch @@ -10,7 +10,7 @@ case AR5416_AR9100_DEVID: --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -36,6 +36,7 @@ +@@ -37,6 +37,7 @@ #define ATHEROS_VENDOR_ID 0x168c diff --git a/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch index f08301c7f4..35d39a05c7 100644 --- a/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch +++ b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch @@ -75,7 +75,7 @@ struct ath9k_hw_version { u32 magic; u16 devid; -@@ -810,6 +816,8 @@ struct ath_hw { +@@ -811,6 +817,8 @@ struct ath_hw { u32 ah_flags; s16 nf_override; @@ -84,7 +84,7 @@ bool reset_power_on; bool htc_reset_init; -@@ -1079,6 +1087,7 @@ void ath9k_hw_check_nav(struct ath_hw *a +@@ -1080,6 +1088,7 @@ void ath9k_hw_check_nav(struct ath_hw *a bool ath9k_hw_check_alive(struct ath_hw *ah); bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); From 4e18d224c84c625248be2528fd3c7d2103f83ebf Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 4 Jan 2025 14:31:07 -0800 Subject: [PATCH 13/14] mac80211: ath9k: simplify probe with devm Upstream backport. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/17445 Signed-off-by: Robert Marko --- ...se-devm-for-irq-and-ioremap-resource.patch | 127 ++++++++++++++++++ .../patches/ath9k/552-ath9k-ahb_of.patch | 12 +- 2 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath9k/509-ath9k-use-devm-for-irq-and-ioremap-resource.patch diff --git a/package/kernel/mac80211/patches/ath9k/509-ath9k-use-devm-for-irq-and-ioremap-resource.patch b/package/kernel/mac80211/patches/ath9k/509-ath9k-use-devm-for-irq-and-ioremap-resource.patch new file mode 100644 index 0000000000..8c9477946e --- /dev/null +++ b/package/kernel/mac80211/patches/ath9k/509-ath9k-use-devm-for-irq-and-ioremap-resource.patch @@ -0,0 +1,127 @@ +From da57e63c91ce11a640b1d38412be8c0d8655b8d9 Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Sat, 4 Jan 2025 14:24:46 -0800 +Subject: [PATCH] ath9k: use devm for irq and ioremap resource + +Avoids having to manually free. Both of these get called and removed in +probe only and are safe to convert. + +devm_platform_ioremap_resource is different as it also calls +devm_request_memory_region, which requires non overlapping memory +regions. Luckily, that seems to be the case. + +Tested on a TP-Link Archer C7v2. + +Signed-off-by: Rosen Penev +--- + drivers/net/wireless/ath/ath9k/ahb.c | 22 ++++++---------------- + drivers/net/wireless/ath/ath9k/pci.c | 9 +++------ + 2 files changed, 9 insertions(+), 22 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/ahb.c ++++ b/drivers/net/wireless/ath/ath9k/ahb.c +@@ -74,7 +74,6 @@ static int ath_ahb_probe(struct platform + void __iomem *mem; + struct ath_softc *sc; + struct ieee80211_hw *hw; +- struct resource *res; + const struct platform_device_id *id = platform_get_device_id(pdev); + int irq; + int ret = 0; +@@ -86,16 +85,10 @@ static int ath_ahb_probe(struct platform + return -EINVAL; + } + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (res == NULL) { +- dev_err(&pdev->dev, "no memory resource found\n"); +- return -ENXIO; +- } +- +- mem = devm_ioremap(&pdev->dev, res->start, resource_size(res)); +- if (mem == NULL) { ++ mem = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(mem)) { + dev_err(&pdev->dev, "ioremap failed\n"); +- return -ENOMEM; ++ return PTR_ERR(mem); + } + + irq = platform_get_irq(pdev, 0); +@@ -118,16 +111,16 @@ static int ath_ahb_probe(struct platform + sc->mem = mem; + sc->irq = irq; + +- ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); ++ ret = devm_request_irq(&pdev->dev, irq, ath_isr, IRQF_SHARED, "ath9k", sc); + if (ret) { + dev_err(&pdev->dev, "request_irq failed\n"); +- goto err_free_hw; ++ return ret; + } + + ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops); + if (ret) { + dev_err(&pdev->dev, "failed to initialize device\n"); +- goto err_irq; ++ goto err_free_hw; + } + + ah = sc->sc_ah; +@@ -137,8 +130,6 @@ static int ath_ahb_probe(struct platform + + return 0; + +- err_irq: +- free_irq(irq, sc); + err_free_hw: + ieee80211_free_hw(hw); + return ret; +@@ -152,7 +143,6 @@ static void ath_ahb_remove(struct platfo + struct ath_softc *sc = hw->priv; + + ath9k_deinit_device(sc); +- free_irq(sc->irq, sc); + ieee80211_free_hw(sc->hw); + } + } +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -965,9 +965,9 @@ static int ath_pci_probe(struct pci_dev + } + + if (!msi_enabled) +- ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); ++ ret = devm_request_irq(&pdev->dev, pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); + else +- ret = request_irq(pdev->irq, ath_isr, 0, "ath9k", sc); ++ ret = devm_request_irq(&pdev->dev, pdev->irq, ath_isr, 0, "ath9k", sc); + + if (ret) { + dev_err(&pdev->dev, "request_irq failed\n"); +@@ -979,7 +979,7 @@ static int ath_pci_probe(struct pci_dev + ret = ath9k_init_device(id->device, sc, &ath_pci_bus_ops); + if (ret) { + dev_err(&pdev->dev, "Failed to initialize device\n"); +- goto err_init; ++ goto err_irq; + } + + sc->sc_ah->msi_enabled = msi_enabled; +@@ -991,8 +991,6 @@ static int ath_pci_probe(struct pci_dev + + return 0; + +-err_init: +- free_irq(sc->irq, sc); + err_irq: + ieee80211_free_hw(hw); + return ret; +@@ -1006,7 +1004,6 @@ static void ath_pci_remove(struct pci_de + if (!is_ath9k_unloaded) + sc->sc_ah->ah_flags |= AH_UNPLUGGED; + ath9k_deinit_device(sc); +- free_irq(sc->irq, sc); + ieee80211_free_hw(sc->hw); + } + diff --git a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch index 0e4407b439..f1192bef8f 100644 --- a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch +++ b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch @@ -209,7 +209,7 @@ static int ath_ahb_probe(struct platform_device *pdev) { void __iomem *mem; -@@ -80,6 +274,17 @@ static int ath_ahb_probe(struct platform +@@ -79,6 +273,17 @@ static int ath_ahb_probe(struct platform int ret = 0; struct ath_hw *ah; char hw_name[64]; @@ -227,24 +227,24 @@ if (!dev_get_platdata(&pdev->dev)) { dev_err(&pdev->dev, "no platform data specified\n"); -@@ -118,17 +323,23 @@ static int ath_ahb_probe(struct platform +@@ -111,17 +316,23 @@ static int ath_ahb_probe(struct platform sc->mem = mem; sc->irq = irq; +#ifdef CONFIG_OF + dev_id = of_ath_ahb_probe(pdev); +#endif - ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); + ret = devm_request_irq(&pdev->dev, irq, ath_isr, IRQF_SHARED, "ath9k", sc); if (ret) { dev_err(&pdev->dev, "request_irq failed\n"); - goto err_free_hw; + return ret; } - ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops); + ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops); if (ret) { dev_err(&pdev->dev, "failed to initialize device\n"); - goto err_irq; + goto err_free_hw; } +#ifdef CONFIG_OF + pdev->dev.platform_data = NULL; @@ -252,7 +252,7 @@ ah = sc->sc_ah; ath9k_hw_name(ah, hw_name, sizeof(hw_name)); -@@ -162,6 +373,9 @@ static struct platform_driver ath_ahb_dr +@@ -152,6 +363,9 @@ static struct platform_driver ath_ahb_dr .remove_new = ath_ahb_remove, .driver = { .name = "ath9k", From eec11fbbb6eb70cfcae27ac6c055d2c1bd5d20d9 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Wed, 2 Apr 2025 23:36:28 +0800 Subject: [PATCH 14/14] generic: crypto: fix jitterentropy initialization failed issue Sync jitterentropy source code with linux-6.12 to solve the issue of jitterentropy initialization failed: [ 9.523489] jitterentropy: Initialization failed with host not compliant with requirements: 9 [ 9.661916] kmodloader: 1 module could not be probed [ 9.662377] kmodloader: - jitterentropy_rng - 0 In linux upstream commit cf27d9475f37 ("crypto: jitter - use permanent health test storage"), when FIPS crypto is disabled, the health test results are always explicitly skipped. That means it will never return error code 9 (health test failed) again. Fixes: https://github.com/openwrt/openwrt/issues/16684 Signed-off-by: Shiji Yang Link: https://github.com/openwrt/openwrt/pull/18399 Signed-off-by: Robert Marko --- ...dd-RCTAPT-support-for-different-OSRs.patch | 445 ++++++++++++++++++ ...r-Allow-configuration-of-memory-size.patch | 159 +++++++ ...w-configuration-of-oversampling-rate.patch | 75 +++ ...er-reuse-allocated-entropy-collector.patch | 117 +++++ ...er-use-permanent-health-test-storage.patch | 242 ++++++++++ ...-Hide-esoteric-Kconfig-options-under.patch | 80 ++++ ...e-kvfree_sensitive-to-fix-Coccinelle.patch | 30 ++ ...2-crypto-jitter-set-default-OSR-to-3.patch | 36 ++ 8 files changed, 1184 insertions(+) create mode 100644 target/linux/generic/backport-6.6/906-01-v6.7-crypto-jitter-add-RCTAPT-support-for-different-OSRs.patch create mode 100644 target/linux/generic/backport-6.6/906-02-v6.7-crypto-jitter-Allow-configuration-of-memory-size.patch create mode 100644 target/linux/generic/backport-6.6/906-03-v6.7-crypto-jitter-Allow-configuration-of-oversampling-rate.patch create mode 100644 target/linux/generic/backport-6.6/906-04-v6.7-crypto-jitter-reuse-allocated-entropy-collector.patch create mode 100644 target/linux/generic/backport-6.6/906-05-v6.7-crypto-jitter-use-permanent-health-test-storage.patch create mode 100644 target/linux/generic/backport-6.6/906-06-v6.7-crypto-jitterentropy-Hide-esoteric-Kconfig-options-under.patch create mode 100644 target/linux/generic/backport-6.6/906-07-v6.10-crypto-jitter-Use-kvfree_sensitive-to-fix-Coccinelle.patch create mode 100644 target/linux/generic/backport-6.6/906-08-v6.12-crypto-jitter-set-default-OSR-to-3.patch diff --git a/target/linux/generic/backport-6.6/906-01-v6.7-crypto-jitter-add-RCTAPT-support-for-different-OSRs.patch b/target/linux/generic/backport-6.6/906-01-v6.7-crypto-jitter-add-RCTAPT-support-for-different-OSRs.patch new file mode 100644 index 0000000000..d0ae1258f8 --- /dev/null +++ b/target/linux/generic/backport-6.6/906-01-v6.7-crypto-jitter-add-RCTAPT-support-for-different-OSRs.patch @@ -0,0 +1,445 @@ +From 04597c8dd6c4b55e946fec50dc3b14a5d9d54501 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Thu, 21 Sep 2023 13:48:11 +0200 +Subject: [PATCH] crypto: jitter - add RCT/APT support for different OSRs + +The oversampling rate (OSR) value specifies the heuristically implied +entropy in the recorded data - H_submitter = 1/osr. A different entropy +estimate implies a different APT/RCT cutoff value. This change adds +support for OSRs 1 through 15. This OSR can be selected by the caller +of the Jitter RNG. + +For this patch, the caller still uses one hard-coded OSR. A subsequent +patch allows this value to be configured. + +In addition, the power-up self test is adjusted as follows: + +* It allows the caller to provide an oversampling rate that should be +tested with - commonly it should be the same as used for the actual +runtime operation. This makes the power-up testing therefore consistent +with the runtime operation. + +* It calls now jent_measure_jitter (i.e. collects the full entropy +that can possibly be harvested by the Jitter RNG) instead of only +jent_condition_data (which only returns the entropy harvested from +the conditioning component). This should now alleviate reports where +the Jitter RNG initialization thinks there is too little entropy. + +* The power-up test now solely relies on the (enhanced) APT and RCT +test that is used as a health test at runtime. + +The code allowing the different OSRs as well as the power-up test +changes are present in the user space version of the Jitter RNG 3.4.1 +and thus was already in production use for some time. + +Reported-by "Ospan, Abylay" +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +--- + crypto/jitterentropy-kcapi.c | 4 +- + crypto/jitterentropy.c | 233 ++++++++++++++++++----------------- + crypto/jitterentropy.h | 3 +- + 3 files changed, 123 insertions(+), 117 deletions(-) + +--- a/crypto/jitterentropy-kcapi.c ++++ b/crypto/jitterentropy-kcapi.c +@@ -245,7 +245,7 @@ static int jent_kcapi_init(struct crypto + crypto_shash_init(sdesc); + rng->sdesc = sdesc; + +- rng->entropy_collector = jent_entropy_collector_alloc(1, 0, sdesc); ++ rng->entropy_collector = jent_entropy_collector_alloc(0, 0, sdesc); + if (!rng->entropy_collector) { + ret = -ENOMEM; + goto err; +@@ -334,7 +334,7 @@ static int __init jent_mod_init(void) + + desc->tfm = tfm; + crypto_shash_init(desc); +- ret = jent_entropy_init(desc); ++ ret = jent_entropy_init(0, 0, desc); + shash_desc_zero(desc); + crypto_free_shash(tfm); + if (ret) { +--- a/crypto/jitterentropy.c ++++ b/crypto/jitterentropy.c +@@ -72,6 +72,8 @@ struct rand_data { + __u64 prev_time; /* SENSITIVE Previous time stamp */ + __u64 last_delta; /* SENSITIVE stuck test */ + __s64 last_delta2; /* SENSITIVE stuck test */ ++ ++ unsigned int flags; /* Flags used to initialize */ + unsigned int osr; /* Oversample rate */ + #define JENT_MEMORY_BLOCKS 64 + #define JENT_MEMORY_BLOCKSIZE 32 +@@ -88,16 +90,9 @@ struct rand_data { + /* Repetition Count Test */ + unsigned int rct_count; /* Number of stuck values */ + +- /* Intermittent health test failure threshold of 2^-30 */ +- /* From an SP800-90B perspective, this RCT cutoff value is equal to 31. */ +- /* However, our RCT implementation starts at 1, so we subtract 1 here. */ +-#define JENT_RCT_CUTOFF (31 - 1) /* Taken from SP800-90B sec 4.4.1 */ +-#define JENT_APT_CUTOFF 325 /* Taken from SP800-90B sec 4.4.2 */ +- /* Permanent health test failure threshold of 2^-60 */ +- /* From an SP800-90B perspective, this RCT cutoff value is equal to 61. */ +- /* However, our RCT implementation starts at 1, so we subtract 1 here. */ +-#define JENT_RCT_CUTOFF_PERMANENT (61 - 1) +-#define JENT_APT_CUTOFF_PERMANENT 355 ++ /* Adaptive Proportion Test cutoff values */ ++ unsigned int apt_cutoff; /* Intermittent health test failure */ ++ unsigned int apt_cutoff_permanent; /* Permanent health test failure */ + #define JENT_APT_WINDOW_SIZE 512 /* Data window size */ + /* LSB of time stamp to process */ + #define JENT_APT_LSB 16 +@@ -122,6 +117,9 @@ struct rand_data { + * zero). */ + #define JENT_ESTUCK 8 /* Too many stuck results during init. */ + #define JENT_EHEALTH 9 /* Health test failed during initialization */ ++#define JENT_ERCT 10 /* RCT failed during initialization */ ++#define JENT_EHASH 11 /* Hash self test failed */ ++#define JENT_EMEM 12 /* Can't allocate memory for initialization */ + + /* + * The output n bits can receive more than n bits of min entropy, of course, +@@ -148,6 +146,48 @@ struct rand_data { + ***************************************************************************/ + + /* ++ * See the SP 800-90B comment #10b for the corrected cutoff for the SP 800-90B ++ * APT. ++ * http://www.untruth.org/~josh/sp80090b/UL%20SP800-90B-final%20comments%20v1.9%2020191212.pdf ++ * In in the syntax of R, this is C = 2 + qbinom(1 − 2^(−30), 511, 2^(-1/osr)). ++ * (The original formula wasn't correct because the first symbol must ++ * necessarily have been observed, so there is no chance of observing 0 of these ++ * symbols.) ++ * ++ * For the alpha < 2^-53, R cannot be used as it uses a float data type without ++ * arbitrary precision. A SageMath script is used to calculate those cutoff ++ * values. ++ * ++ * For any value above 14, this yields the maximal allowable value of 512 ++ * (by FIPS 140-2 IG 7.19 Resolution # 16, we cannot choose a cutoff value that ++ * renders the test unable to fail). ++ */ ++static const unsigned int jent_apt_cutoff_lookup[15] = { ++ 325, 422, 459, 477, 488, 494, 499, 502, ++ 505, 507, 508, 509, 510, 511, 512 }; ++static const unsigned int jent_apt_cutoff_permanent_lookup[15] = { ++ 355, 447, 479, 494, 502, 507, 510, 512, ++ 512, 512, 512, 512, 512, 512, 512 }; ++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++ ++static void jent_apt_init(struct rand_data *ec, unsigned int osr) ++{ ++ /* ++ * Establish the apt_cutoff based on the presumed entropy rate of ++ * 1/osr. ++ */ ++ if (osr >= ARRAY_SIZE(jent_apt_cutoff_lookup)) { ++ ec->apt_cutoff = jent_apt_cutoff_lookup[ ++ ARRAY_SIZE(jent_apt_cutoff_lookup) - 1]; ++ ec->apt_cutoff_permanent = jent_apt_cutoff_permanent_lookup[ ++ ARRAY_SIZE(jent_apt_cutoff_permanent_lookup) - 1]; ++ } else { ++ ec->apt_cutoff = jent_apt_cutoff_lookup[osr - 1]; ++ ec->apt_cutoff_permanent = ++ jent_apt_cutoff_permanent_lookup[osr - 1]; ++ } ++} ++/* + * Reset the APT counter + * + * @ec [in] Reference to entropy collector +@@ -187,12 +227,12 @@ static void jent_apt_insert(struct rand_ + /* APT health test failure detection */ + static int jent_apt_permanent_failure(struct rand_data *ec) + { +- return (ec->apt_count >= JENT_APT_CUTOFF_PERMANENT) ? 1 : 0; ++ return (ec->apt_count >= ec->apt_cutoff_permanent) ? 1 : 0; + } + + static int jent_apt_failure(struct rand_data *ec) + { +- return (ec->apt_count >= JENT_APT_CUTOFF) ? 1 : 0; ++ return (ec->apt_count >= ec->apt_cutoff) ? 1 : 0; + } + + /*************************************************************************** +@@ -275,15 +315,28 @@ static int jent_stuck(struct rand_data * + return 0; + } + +-/* RCT health test failure detection */ ++/* ++ * The cutoff value is based on the following consideration: ++ * alpha = 2^-30 or 2^-60 as recommended in SP800-90B. ++ * In addition, we require an entropy value H of 1/osr as this is the minimum ++ * entropy required to provide full entropy. ++ * Note, we collect (DATA_SIZE_BITS + ENTROPY_SAFETY_FACTOR)*osr deltas for ++ * inserting them into the entropy pool which should then have (close to) ++ * DATA_SIZE_BITS bits of entropy in the conditioned output. ++ * ++ * Note, ec->rct_count (which equals to value B in the pseudo code of SP800-90B ++ * section 4.4.1) starts with zero. Hence we need to subtract one from the ++ * cutoff value as calculated following SP800-90B. Thus ++ * C = ceil(-log_2(alpha)/H) = 30*osr or 60*osr. ++ */ + static int jent_rct_permanent_failure(struct rand_data *ec) + { +- return (ec->rct_count >= JENT_RCT_CUTOFF_PERMANENT) ? 1 : 0; ++ return (ec->rct_count >= (60 * ec->osr)) ? 1 : 0; + } + + static int jent_rct_failure(struct rand_data *ec) + { +- return (ec->rct_count >= JENT_RCT_CUTOFF) ? 1 : 0; ++ return (ec->rct_count >= (30 * ec->osr)) ? 1 : 0; + } + + /* Report of health test failures */ +@@ -448,7 +501,7 @@ static void jent_memaccess(struct rand_d + * + * @return result of stuck test + */ +-static int jent_measure_jitter(struct rand_data *ec) ++static int jent_measure_jitter(struct rand_data *ec, __u64 *ret_current_delta) + { + __u64 time = 0; + __u64 current_delta = 0; +@@ -472,6 +525,10 @@ static int jent_measure_jitter(struct ra + if (jent_condition_data(ec, current_delta, stuck)) + stuck = 1; + ++ /* return the raw entropy value */ ++ if (ret_current_delta) ++ *ret_current_delta = current_delta; ++ + return stuck; + } + +@@ -489,11 +546,11 @@ static void jent_gen_entropy(struct rand + safety_factor = JENT_ENTROPY_SAFETY_FACTOR; + + /* priming of the ->prev_time value */ +- jent_measure_jitter(ec); ++ jent_measure_jitter(ec, NULL); + + while (!jent_health_failure(ec)) { + /* If a stuck measurement is received, repeat measurement */ +- if (jent_measure_jitter(ec)) ++ if (jent_measure_jitter(ec, NULL)) + continue; + + /* +@@ -554,7 +611,8 @@ int jent_read_entropy(struct rand_data * + * Perform startup health tests and return permanent + * error if it fails. + */ +- if (jent_entropy_init(ec->hash_state)) ++ if (jent_entropy_init(ec->osr, ec->flags, ++ ec->hash_state)) + return -3; + + return -2; +@@ -604,11 +662,15 @@ struct rand_data *jent_entropy_collector + + /* verify and set the oversampling rate */ + if (osr == 0) +- osr = 1; /* minimum sampling rate is 1 */ ++ osr = 1; /* H_submitter = 1 / osr */ + entropy_collector->osr = osr; ++ entropy_collector->flags = flags; + + entropy_collector->hash_state = hash_state; + ++ /* Initialize the APT */ ++ jent_apt_init(entropy_collector, osr); ++ + /* fill the data pad with non-zero values */ + jent_gen_entropy(entropy_collector); + +@@ -622,20 +684,14 @@ void jent_entropy_collector_free(struct + jent_zfree(entropy_collector); + } + +-int jent_entropy_init(void *hash_state) ++int jent_entropy_init(unsigned int osr, unsigned int flags, void *hash_state) + { +- int i; +- __u64 delta_sum = 0; +- __u64 old_delta = 0; +- unsigned int nonstuck = 0; +- int time_backwards = 0; +- int count_mod = 0; +- int count_stuck = 0; +- struct rand_data ec = { 0 }; +- +- /* Required for RCT */ +- ec.osr = 1; +- ec.hash_state = hash_state; ++ struct rand_data *ec; ++ int i, time_backwards = 0, ret = 0; ++ ++ ec = jent_entropy_collector_alloc(osr, flags, hash_state); ++ if (!ec) ++ return JENT_EMEM; + + /* We could perform statistical tests here, but the problem is + * that we only have a few loop counts to do testing. These +@@ -664,31 +720,28 @@ int jent_entropy_init(void *hash_state) + #define TESTLOOPCOUNT 1024 + #define CLEARCACHE 100 + for (i = 0; (TESTLOOPCOUNT + CLEARCACHE) > i; i++) { +- __u64 time = 0; +- __u64 time2 = 0; +- __u64 delta = 0; +- unsigned int lowdelta = 0; +- int stuck; ++ __u64 start_time = 0, end_time = 0, delta = 0; + + /* Invoke core entropy collection logic */ +- jent_get_nstime(&time); +- ec.prev_time = time; +- jent_condition_data(&ec, time, 0); +- jent_get_nstime(&time2); ++ jent_measure_jitter(ec, &delta); ++ end_time = ec->prev_time; ++ start_time = ec->prev_time - delta; + + /* test whether timer works */ +- if (!time || !time2) +- return JENT_ENOTIME; +- delta = jent_delta(time, time2); ++ if (!start_time || !end_time) { ++ ret = JENT_ENOTIME; ++ goto out; ++ } ++ + /* + * test whether timer is fine grained enough to provide + * delta even when called shortly after each other -- this + * implies that we also have a high resolution timer + */ +- if (!delta) +- return JENT_ECOARSETIME; +- +- stuck = jent_stuck(&ec, delta); ++ if (!delta || (end_time == start_time)) { ++ ret = JENT_ECOARSETIME; ++ goto out; ++ } + + /* + * up to here we did not modify any variable that will be +@@ -700,49 +753,9 @@ int jent_entropy_init(void *hash_state) + if (i < CLEARCACHE) + continue; + +- if (stuck) +- count_stuck++; +- else { +- nonstuck++; +- +- /* +- * Ensure that the APT succeeded. +- * +- * With the check below that count_stuck must be less +- * than 10% of the overall generated raw entropy values +- * it is guaranteed that the APT is invoked at +- * floor((TESTLOOPCOUNT * 0.9) / 64) == 14 times. +- */ +- if ((nonstuck % JENT_APT_WINDOW_SIZE) == 0) { +- jent_apt_reset(&ec, +- delta & JENT_APT_WORD_MASK); +- } +- } +- +- /* Validate health test result */ +- if (jent_health_failure(&ec)) +- return JENT_EHEALTH; +- + /* test whether we have an increasing timer */ +- if (!(time2 > time)) ++ if (!(end_time > start_time)) + time_backwards++; +- +- /* use 32 bit value to ensure compilation on 32 bit arches */ +- lowdelta = time2 - time; +- if (!(lowdelta % 100)) +- count_mod++; +- +- /* +- * ensure that we have a varying delta timer which is necessary +- * for the calculation of entropy -- perform this check +- * only after the first loop is executed as we need to prime +- * the old_data value +- */ +- if (delta > old_delta) +- delta_sum += (delta - old_delta); +- else +- delta_sum += (old_delta - delta); +- old_delta = delta; + } + + /* +@@ -752,31 +765,23 @@ int jent_entropy_init(void *hash_state) + * should not fail. The value of 3 should cover the NTP case being + * performed during our test run. + */ +- if (time_backwards > 3) +- return JENT_ENOMONOTONIC; +- +- /* +- * Variations of deltas of time must on average be larger +- * than 1 to ensure the entropy estimation +- * implied with 1 is preserved +- */ +- if ((delta_sum) <= 1) +- return JENT_EVARVAR; ++ if (time_backwards > 3) { ++ ret = JENT_ENOMONOTONIC; ++ goto out; ++ } + +- /* +- * Ensure that we have variations in the time stamp below 10 for at +- * least 10% of all checks -- on some platforms, the counter increments +- * in multiples of 100, but not always +- */ +- if ((TESTLOOPCOUNT/10 * 9) < count_mod) +- return JENT_ECOARSETIME; ++ /* Did we encounter a health test failure? */ ++ if (jent_rct_failure(ec)) { ++ ret = JENT_ERCT; ++ goto out; ++ } ++ if (jent_apt_failure(ec)) { ++ ret = JENT_EHEALTH; ++ goto out; ++ } + +- /* +- * If we have more than 90% stuck results, then this Jitter RNG is +- * likely to not work well. +- */ +- if ((TESTLOOPCOUNT/10 * 9) < count_stuck) +- return JENT_ESTUCK; ++out: ++ jent_entropy_collector_free(ec); + +- return 0; ++ return ret; + } +--- a/crypto/jitterentropy.h ++++ b/crypto/jitterentropy.h +@@ -9,7 +9,8 @@ extern int jent_hash_time(void *hash_sta + int jent_read_random_block(void *hash_state, char *dst, unsigned int dst_len); + + struct rand_data; +-extern int jent_entropy_init(void *hash_state); ++extern int jent_entropy_init(unsigned int osr, unsigned int flags, ++ void *hash_state); + extern int jent_read_entropy(struct rand_data *ec, unsigned char *data, + unsigned int len); + diff --git a/target/linux/generic/backport-6.6/906-02-v6.7-crypto-jitter-Allow-configuration-of-memory-size.patch b/target/linux/generic/backport-6.6/906-02-v6.7-crypto-jitter-Allow-configuration-of-memory-size.patch new file mode 100644 index 0000000000..b13fc86701 --- /dev/null +++ b/target/linux/generic/backport-6.6/906-02-v6.7-crypto-jitter-Allow-configuration-of-memory-size.patch @@ -0,0 +1,159 @@ +From 59bcfd788552504606e3eb774ae68052379396b6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Thu, 21 Sep 2023 13:48:33 +0200 +Subject: [PATCH] crypto: jitter - Allow configuration of memory size + +The memory size consumed by the Jitter RNG is one contributing factor in +the amount of entropy that is gathered. As the amount of entropy +directly correlates with the distance of the memory from the CPU, the +caches that are possibly present on a given system have an impact on the +collected entropy. + +Thus, the kernel compile time should offer a means to configure the +amount of memory used by the Jitter RNG. Although this option could be +turned into a runtime option (e.g. a kernel command line option), it +should remain a compile time option as otherwise adminsitrators who may +not have performed an entropy assessment may select a value that is +inappropriate. + +The default value selected by the configuration is identical to the +current Jitter RNG value. Thus, the patch should not lead to any change +in the Jitter RNG behavior. + +To accommodate larger memory buffers, kvzalloc / kvfree is used. + +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +--- + crypto/Kconfig | 43 ++++++++++++++++++++++++++++++++++++ + crypto/jitterentropy-kcapi.c | 11 +++++++++ + crypto/jitterentropy.c | 16 ++++++++------ + crypto/jitterentropy.h | 2 ++ + 4 files changed, 65 insertions(+), 7 deletions(-) + +--- a/crypto/Kconfig ++++ b/crypto/Kconfig +@@ -1297,6 +1297,49 @@ config CRYPTO_JITTERENTROPY + + See https://www.chronox.de/jent/ + ++choice ++ prompt "CPU Jitter RNG Memory Size" ++ default CRYPTO_JITTERENTROPY_MEMSIZE_2 ++ depends on CRYPTO_JITTERENTROPY ++ help ++ The Jitter RNG measures the execution time of memory accesses. ++ Multiple consecutive memory accesses are performed. If the memory ++ size fits into a cache (e.g. L1), only the memory access timing ++ to that cache is measured. The closer the cache is to the CPU ++ the less variations are measured and thus the less entropy is ++ obtained. Thus, if the memory size fits into the L1 cache, the ++ obtained entropy is less than if the memory size fits within ++ L1 + L2, which in turn is less if the memory fits into ++ L1 + L2 + L3. Thus, by selecting a different memory size, ++ the entropy rate produced by the Jitter RNG can be modified. ++ ++ config CRYPTO_JITTERENTROPY_MEMSIZE_2 ++ bool "2048 Bytes (default)" ++ ++ config CRYPTO_JITTERENTROPY_MEMSIZE_128 ++ bool "128 kBytes" ++ ++ config CRYPTO_JITTERENTROPY_MEMSIZE_1024 ++ bool "1024 kBytes" ++ ++ config CRYPTO_JITTERENTROPY_MEMSIZE_8192 ++ bool "8192 kBytes" ++endchoice ++ ++config CRYPTO_JITTERENTROPY_MEMORY_BLOCKS ++ int ++ default 64 if CRYPTO_JITTERENTROPY_MEMSIZE_2 ++ default 512 if CRYPTO_JITTERENTROPY_MEMSIZE_128 ++ default 1024 if CRYPTO_JITTERENTROPY_MEMSIZE_1024 ++ default 4096 if CRYPTO_JITTERENTROPY_MEMSIZE_8192 ++ ++config CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE ++ int ++ default 32 if CRYPTO_JITTERENTROPY_MEMSIZE_2 ++ default 256 if CRYPTO_JITTERENTROPY_MEMSIZE_128 ++ default 1024 if CRYPTO_JITTERENTROPY_MEMSIZE_1024 ++ default 2048 if CRYPTO_JITTERENTROPY_MEMSIZE_8192 ++ + config CRYPTO_JITTERENTROPY_TESTINTERFACE + bool "CPU Jitter RNG Test Interface" + depends on CRYPTO_JITTERENTROPY +--- a/crypto/jitterentropy-kcapi.c ++++ b/crypto/jitterentropy-kcapi.c +@@ -54,6 +54,17 @@ + * Helper function + ***************************************************************************/ + ++void *jent_kvzalloc(unsigned int len) ++{ ++ return kvzalloc(len, GFP_KERNEL); ++} ++ ++void jent_kvzfree(void *ptr, unsigned int len) ++{ ++ memzero_explicit(ptr, len); ++ kvfree(ptr); ++} ++ + void *jent_zalloc(unsigned int len) + { + return kzalloc(len, GFP_KERNEL); +--- a/crypto/jitterentropy.c ++++ b/crypto/jitterentropy.c +@@ -75,10 +75,10 @@ struct rand_data { + + unsigned int flags; /* Flags used to initialize */ + unsigned int osr; /* Oversample rate */ +-#define JENT_MEMORY_BLOCKS 64 +-#define JENT_MEMORY_BLOCKSIZE 32 + #define JENT_MEMORY_ACCESSLOOPS 128 +-#define JENT_MEMORY_SIZE (JENT_MEMORY_BLOCKS*JENT_MEMORY_BLOCKSIZE) ++#define JENT_MEMORY_SIZE \ ++ (CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS * \ ++ CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE) + unsigned char *mem; /* Memory access location with size of + * memblocks * memblocksize */ + unsigned int memlocation; /* Pointer to byte in *mem */ +@@ -650,13 +650,15 @@ struct rand_data *jent_entropy_collector + /* Allocate memory for adding variations based on memory + * access + */ +- entropy_collector->mem = jent_zalloc(JENT_MEMORY_SIZE); ++ entropy_collector->mem = jent_kvzalloc(JENT_MEMORY_SIZE); + if (!entropy_collector->mem) { + jent_zfree(entropy_collector); + return NULL; + } +- entropy_collector->memblocksize = JENT_MEMORY_BLOCKSIZE; +- entropy_collector->memblocks = JENT_MEMORY_BLOCKS; ++ entropy_collector->memblocksize = ++ CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE; ++ entropy_collector->memblocks = ++ CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS; + entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS; + } + +@@ -679,7 +681,7 @@ struct rand_data *jent_entropy_collector + + void jent_entropy_collector_free(struct rand_data *entropy_collector) + { +- jent_zfree(entropy_collector->mem); ++ jent_kvzfree(entropy_collector->mem, JENT_MEMORY_SIZE); + entropy_collector->mem = NULL; + jent_zfree(entropy_collector); + } +--- a/crypto/jitterentropy.h ++++ b/crypto/jitterentropy.h +@@ -1,5 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-or-later + ++extern void *jent_kvzalloc(unsigned int len); ++extern void jent_kvzfree(void *ptr, unsigned int len); + extern void *jent_zalloc(unsigned int len); + extern void jent_zfree(void *ptr); + extern void jent_get_nstime(__u64 *out); diff --git a/target/linux/generic/backport-6.6/906-03-v6.7-crypto-jitter-Allow-configuration-of-oversampling-rate.patch b/target/linux/generic/backport-6.6/906-03-v6.7-crypto-jitter-Allow-configuration-of-oversampling-rate.patch new file mode 100644 index 0000000000..856400fce9 --- /dev/null +++ b/target/linux/generic/backport-6.6/906-03-v6.7-crypto-jitter-Allow-configuration-of-oversampling-rate.patch @@ -0,0 +1,75 @@ +From 0baa8fab334a4d7017235b72fa8a547433572109 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Thu, 21 Sep 2023 13:48:59 +0200 +Subject: [PATCH] crypto: jitter - Allow configuration of oversampling rate + +The oversampling rate used by the Jitter RNG allows the configuration of +the heuristically implied entropy in one timing measurement. This +entropy rate is (1 / OSR) bits of entropy per time stamp. + +Considering that the Jitter RNG now support APT/RCT health tests for +different OSRs, allow this value to be configured at compile time to +support systems with limited amount of entropy in their timer. + +The allowed range of OSR values complies with the APT/RCT cutoff health +test values which range from 1 through 15. + +The default value of the OSR selection support is left at 1 which is the +current default. Thus, the addition of the configuration support does +not alter the default Jitter RNG behavior. + +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +--- + crypto/Kconfig | 17 +++++++++++++++++ + crypto/jitterentropy-kcapi.c | 6 ++++-- + 2 files changed, 21 insertions(+), 2 deletions(-) + +--- a/crypto/Kconfig ++++ b/crypto/Kconfig +@@ -1340,6 +1340,23 @@ config CRYPTO_JITTERENTROPY_MEMORY_BLOCK + default 1024 if CRYPTO_JITTERENTROPY_MEMSIZE_1024 + default 2048 if CRYPTO_JITTERENTROPY_MEMSIZE_8192 + ++config CRYPTO_JITTERENTROPY_OSR ++ int "CPU Jitter RNG Oversampling Rate" ++ range 1 15 ++ default 1 ++ depends on CRYPTO_JITTERENTROPY ++ help ++ The Jitter RNG allows the specification of an oversampling rate (OSR). ++ The Jitter RNG operation requires a fixed amount of timing ++ measurements to produce one output block of random numbers. The ++ OSR value is multiplied with the amount of timing measurements to ++ generate one output block. Thus, the timing measurement is oversampled ++ by the OSR factor. The oversampling allows the Jitter RNG to operate ++ on hardware whose timers deliver limited amount of entropy (e.g. ++ the timer is coarse) by setting the OSR to a higher value. The ++ trade-off, however, is that the Jitter RNG now requires more time ++ to generate random numbers. ++ + config CRYPTO_JITTERENTROPY_TESTINTERFACE + bool "CPU Jitter RNG Test Interface" + depends on CRYPTO_JITTERENTROPY +--- a/crypto/jitterentropy-kcapi.c ++++ b/crypto/jitterentropy-kcapi.c +@@ -256,7 +256,9 @@ static int jent_kcapi_init(struct crypto + crypto_shash_init(sdesc); + rng->sdesc = sdesc; + +- rng->entropy_collector = jent_entropy_collector_alloc(0, 0, sdesc); ++ rng->entropy_collector = ++ jent_entropy_collector_alloc(CONFIG_CRYPTO_JITTERENTROPY_OSR, 0, ++ sdesc); + if (!rng->entropy_collector) { + ret = -ENOMEM; + goto err; +@@ -345,7 +347,7 @@ static int __init jent_mod_init(void) + + desc->tfm = tfm; + crypto_shash_init(desc); +- ret = jent_entropy_init(0, 0, desc); ++ ret = jent_entropy_init(CONFIG_CRYPTO_JITTERENTROPY_OSR, 0, desc); + shash_desc_zero(desc); + crypto_free_shash(tfm); + if (ret) { diff --git a/target/linux/generic/backport-6.6/906-04-v6.7-crypto-jitter-reuse-allocated-entropy-collector.patch b/target/linux/generic/backport-6.6/906-04-v6.7-crypto-jitter-reuse-allocated-entropy-collector.patch new file mode 100644 index 0000000000..d56f1f2449 --- /dev/null +++ b/target/linux/generic/backport-6.6/906-04-v6.7-crypto-jitter-reuse-allocated-entropy-collector.patch @@ -0,0 +1,117 @@ +From 8405ec8e3c02df8b3720874c3e2169fef4553868 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Sat, 7 Oct 2023 09:10:43 +0200 +Subject: [PATCH] crypto: jitter - reuse allocated entropy collector + +In case a health test error occurs during runtime, the power-up health +tests are rerun to verify that the noise source is still good and +that the reported health test error was an outlier. For performing this +power-up health test, the already existing entropy collector instance +is used instead of allocating a new one. This change has the following +implications: + +* The noise that is collected as part of the newly run health tests is + inserted into the entropy collector and thus stirs the existing + data present in there further. Thus, the entropy collected during + the health test is not wasted. This is also allowed by SP800-90B. + +* The power-on health test is not affected by the state of the entropy + collector, because it resets the APT / RCT state. The remainder of + the state is unrelated to the health test as it is only applied to + newly obtained time stamps. + +This change also fixes a bug report about an allocation while in an +atomic lock (the lock is taken in jent_kcapi_random, jent_read_entropy +is called and this can call jent_entropy_init). + +Fixes: 04597c8dd6c4 ("jitter - add RCT/APT support for different OSRs") +Reported-by: Dan Carpenter +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +--- + crypto/jitterentropy-kcapi.c | 2 +- + crypto/jitterentropy.c | 36 ++++++++++++++++++++++++++---------- + crypto/jitterentropy.h | 2 +- + 3 files changed, 28 insertions(+), 12 deletions(-) + +--- a/crypto/jitterentropy-kcapi.c ++++ b/crypto/jitterentropy-kcapi.c +@@ -347,7 +347,7 @@ static int __init jent_mod_init(void) + + desc->tfm = tfm; + crypto_shash_init(desc); +- ret = jent_entropy_init(CONFIG_CRYPTO_JITTERENTROPY_OSR, 0, desc); ++ ret = jent_entropy_init(CONFIG_CRYPTO_JITTERENTROPY_OSR, 0, desc, NULL); + shash_desc_zero(desc); + crypto_free_shash(tfm); + if (ret) { +--- a/crypto/jitterentropy.c ++++ b/crypto/jitterentropy.c +@@ -611,8 +611,7 @@ int jent_read_entropy(struct rand_data * + * Perform startup health tests and return permanent + * error if it fails. + */ +- if (jent_entropy_init(ec->osr, ec->flags, +- ec->hash_state)) ++ if (jent_entropy_init(0, 0, NULL, ec)) + return -3; + + return -2; +@@ -686,14 +685,30 @@ void jent_entropy_collector_free(struct + jent_zfree(entropy_collector); + } + +-int jent_entropy_init(unsigned int osr, unsigned int flags, void *hash_state) ++int jent_entropy_init(unsigned int osr, unsigned int flags, void *hash_state, ++ struct rand_data *p_ec) + { +- struct rand_data *ec; +- int i, time_backwards = 0, ret = 0; ++ /* ++ * If caller provides an allocated ec, reuse it which implies that the ++ * health test entropy data is used to further still the available ++ * entropy pool. ++ */ ++ struct rand_data *ec = p_ec; ++ int i, time_backwards = 0, ret = 0, ec_free = 0; + +- ec = jent_entropy_collector_alloc(osr, flags, hash_state); +- if (!ec) +- return JENT_EMEM; ++ if (!ec) { ++ ec = jent_entropy_collector_alloc(osr, flags, hash_state); ++ if (!ec) ++ return JENT_EMEM; ++ ec_free = 1; ++ } else { ++ /* Reset the APT */ ++ jent_apt_reset(ec, 0); ++ /* Ensure that a new APT base is obtained */ ++ ec->apt_base_set = 0; ++ /* Reset the RCT */ ++ ec->rct_count = 0; ++ } + + /* We could perform statistical tests here, but the problem is + * that we only have a few loop counts to do testing. These +@@ -783,7 +798,8 @@ int jent_entropy_init(unsigned int osr, + } + + out: +- jent_entropy_collector_free(ec); ++ if (ec_free) ++ jent_entropy_collector_free(ec); + + return ret; + } +--- a/crypto/jitterentropy.h ++++ b/crypto/jitterentropy.h +@@ -12,7 +12,7 @@ int jent_read_random_block(void *hash_st + + struct rand_data; + extern int jent_entropy_init(unsigned int osr, unsigned int flags, +- void *hash_state); ++ void *hash_state, struct rand_data *p_ec); + extern int jent_read_entropy(struct rand_data *ec, unsigned char *data, + unsigned int len); + diff --git a/target/linux/generic/backport-6.6/906-05-v6.7-crypto-jitter-use-permanent-health-test-storage.patch b/target/linux/generic/backport-6.6/906-05-v6.7-crypto-jitter-use-permanent-health-test-storage.patch new file mode 100644 index 0000000000..7c59169720 --- /dev/null +++ b/target/linux/generic/backport-6.6/906-05-v6.7-crypto-jitter-use-permanent-health-test-storage.patch @@ -0,0 +1,242 @@ +From cf27d9475f37fb69b5bc293e6e6d6c1d03cf7cc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Thu, 19 Oct 2023 09:40:42 +0200 +Subject: [PATCH] crypto: jitter - use permanent health test storage + +The health test result in the current code is only given for the currently +processed raw time stamp. This implies to react on the health test error, +the result must be checked after each raw time stamp being processed. To +avoid this constant checking requirement, any health test error is recorded +and stored to be analyzed at a later time, if needed. + +This change ensures that the power-up test catches any health test error. +Without that patch, the power-up health test result is not enforced. + +The introduced changes are already in use with the user space version of +the Jitter RNG. + +Fixes: 04597c8dd6c4 ("jitter - add RCT/APT support for different OSRs") +Reported-by: Joachim Vandersmissen +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +--- + crypto/jitterentropy.c | 125 ++++++++++++++++++++++++----------------- + 1 file changed, 74 insertions(+), 51 deletions(-) + +--- a/crypto/jitterentropy.c ++++ b/crypto/jitterentropy.c +@@ -100,6 +100,8 @@ struct rand_data { + unsigned int apt_observations; /* Number of collected observations */ + unsigned int apt_count; /* APT counter */ + unsigned int apt_base; /* APT base reference */ ++ unsigned int health_failure; /* Record health failure */ ++ + unsigned int apt_base_set:1; /* APT base reference set? */ + }; + +@@ -121,6 +123,13 @@ struct rand_data { + #define JENT_EHASH 11 /* Hash self test failed */ + #define JENT_EMEM 12 /* Can't allocate memory for initialization */ + ++#define JENT_RCT_FAILURE 1 /* Failure in RCT health test. */ ++#define JENT_APT_FAILURE 2 /* Failure in APT health test. */ ++#define JENT_PERMANENT_FAILURE_SHIFT 16 ++#define JENT_PERMANENT_FAILURE(x) (x << JENT_PERMANENT_FAILURE_SHIFT) ++#define JENT_RCT_FAILURE_PERMANENT JENT_PERMANENT_FAILURE(JENT_RCT_FAILURE) ++#define JENT_APT_FAILURE_PERMANENT JENT_PERMANENT_FAILURE(JENT_APT_FAILURE) ++ + /* + * The output n bits can receive more than n bits of min entropy, of course, + * but the fixed output of the conditioning function can only asymptotically +@@ -215,26 +224,22 @@ static void jent_apt_insert(struct rand_ + return; + } + +- if (delta_masked == ec->apt_base) ++ if (delta_masked == ec->apt_base) { + ec->apt_count++; + ++ /* Note, ec->apt_count starts with one. */ ++ if (ec->apt_count >= ec->apt_cutoff_permanent) ++ ec->health_failure |= JENT_APT_FAILURE_PERMANENT; ++ else if (ec->apt_count >= ec->apt_cutoff) ++ ec->health_failure |= JENT_APT_FAILURE; ++ } ++ + ec->apt_observations++; + + if (ec->apt_observations >= JENT_APT_WINDOW_SIZE) + jent_apt_reset(ec, delta_masked); + } + +-/* APT health test failure detection */ +-static int jent_apt_permanent_failure(struct rand_data *ec) +-{ +- return (ec->apt_count >= ec->apt_cutoff_permanent) ? 1 : 0; +-} +- +-static int jent_apt_failure(struct rand_data *ec) +-{ +- return (ec->apt_count >= ec->apt_cutoff) ? 1 : 0; +-} +- + /*************************************************************************** + * Stuck Test and its use as Repetition Count Test + * +@@ -261,6 +266,30 @@ static void jent_rct_insert(struct rand_ + { + if (stuck) { + ec->rct_count++; ++ ++ /* ++ * The cutoff value is based on the following consideration: ++ * alpha = 2^-30 or 2^-60 as recommended in SP800-90B. ++ * In addition, we require an entropy value H of 1/osr as this ++ * is the minimum entropy required to provide full entropy. ++ * Note, we collect (DATA_SIZE_BITS + ENTROPY_SAFETY_FACTOR)*osr ++ * deltas for inserting them into the entropy pool which should ++ * then have (close to) DATA_SIZE_BITS bits of entropy in the ++ * conditioned output. ++ * ++ * Note, ec->rct_count (which equals to value B in the pseudo ++ * code of SP800-90B section 4.4.1) starts with zero. Hence ++ * we need to subtract one from the cutoff value as calculated ++ * following SP800-90B. Thus C = ceil(-log_2(alpha)/H) = 30*osr ++ * or 60*osr. ++ */ ++ if ((unsigned int)ec->rct_count >= (60 * ec->osr)) { ++ ec->rct_count = -1; ++ ec->health_failure |= JENT_RCT_FAILURE_PERMANENT; ++ } else if ((unsigned int)ec->rct_count >= (30 * ec->osr)) { ++ ec->rct_count = -1; ++ ec->health_failure |= JENT_RCT_FAILURE; ++ } + } else { + /* Reset RCT */ + ec->rct_count = 0; +@@ -316,38 +345,24 @@ static int jent_stuck(struct rand_data * + } + + /* +- * The cutoff value is based on the following consideration: +- * alpha = 2^-30 or 2^-60 as recommended in SP800-90B. +- * In addition, we require an entropy value H of 1/osr as this is the minimum +- * entropy required to provide full entropy. +- * Note, we collect (DATA_SIZE_BITS + ENTROPY_SAFETY_FACTOR)*osr deltas for +- * inserting them into the entropy pool which should then have (close to) +- * DATA_SIZE_BITS bits of entropy in the conditioned output. ++ * Report any health test failures + * +- * Note, ec->rct_count (which equals to value B in the pseudo code of SP800-90B +- * section 4.4.1) starts with zero. Hence we need to subtract one from the +- * cutoff value as calculated following SP800-90B. Thus +- * C = ceil(-log_2(alpha)/H) = 30*osr or 60*osr. +- */ +-static int jent_rct_permanent_failure(struct rand_data *ec) +-{ +- return (ec->rct_count >= (60 * ec->osr)) ? 1 : 0; +-} +- +-static int jent_rct_failure(struct rand_data *ec) +-{ +- return (ec->rct_count >= (30 * ec->osr)) ? 1 : 0; +-} +- +-/* Report of health test failures */ +-static int jent_health_failure(struct rand_data *ec) +-{ +- return jent_rct_failure(ec) | jent_apt_failure(ec); +-} ++ * @ec [in] Reference to entropy collector ++ * ++ * @return a bitmask indicating which tests failed ++ * 0 No health test failure ++ * 1 RCT failure ++ * 2 APT failure ++ * 1<health_failure; + } + + /*************************************************************************** +@@ -594,11 +609,12 @@ int jent_read_entropy(struct rand_data * + return -1; + + while (len > 0) { +- unsigned int tocopy; ++ unsigned int tocopy, health_test_result; + + jent_gen_entropy(ec); + +- if (jent_permanent_health_failure(ec)) { ++ health_test_result = jent_health_failure(ec); ++ if (health_test_result > JENT_PERMANENT_FAILURE_SHIFT) { + /* + * At this point, the Jitter RNG instance is considered + * as a failed instance. There is no rerun of the +@@ -606,13 +622,18 @@ int jent_read_entropy(struct rand_data * + * is assumed to not further use this instance. + */ + return -3; +- } else if (jent_health_failure(ec)) { ++ } else if (health_test_result) { + /* + * Perform startup health tests and return permanent + * error if it fails. + */ +- if (jent_entropy_init(0, 0, NULL, ec)) ++ if (jent_entropy_init(0, 0, NULL, ec)) { ++ /* Mark the permanent error */ ++ ec->health_failure &= ++ JENT_RCT_FAILURE_PERMANENT | ++ JENT_APT_FAILURE_PERMANENT; + return -3; ++ } + + return -2; + } +@@ -695,6 +716,7 @@ int jent_entropy_init(unsigned int osr, + */ + struct rand_data *ec = p_ec; + int i, time_backwards = 0, ret = 0, ec_free = 0; ++ unsigned int health_test_result; + + if (!ec) { + ec = jent_entropy_collector_alloc(osr, flags, hash_state); +@@ -708,6 +730,9 @@ int jent_entropy_init(unsigned int osr, + ec->apt_base_set = 0; + /* Reset the RCT */ + ec->rct_count = 0; ++ /* Reset intermittent, leave permanent health test result */ ++ ec->health_failure &= (~JENT_RCT_FAILURE); ++ ec->health_failure &= (~JENT_APT_FAILURE); + } + + /* We could perform statistical tests here, but the problem is +@@ -788,12 +813,10 @@ int jent_entropy_init(unsigned int osr, + } + + /* Did we encounter a health test failure? */ +- if (jent_rct_failure(ec)) { +- ret = JENT_ERCT; +- goto out; +- } +- if (jent_apt_failure(ec)) { +- ret = JENT_EHEALTH; ++ health_test_result = jent_health_failure(ec); ++ if (health_test_result) { ++ ret = (health_test_result & JENT_RCT_FAILURE) ? JENT_ERCT : ++ JENT_EHEALTH; + goto out; + } + diff --git a/target/linux/generic/backport-6.6/906-06-v6.7-crypto-jitterentropy-Hide-esoteric-Kconfig-options-under.patch b/target/linux/generic/backport-6.6/906-06-v6.7-crypto-jitterentropy-Hide-esoteric-Kconfig-options-under.patch new file mode 100644 index 0000000000..2dc2a01169 --- /dev/null +++ b/target/linux/generic/backport-6.6/906-06-v6.7-crypto-jitterentropy-Hide-esoteric-Kconfig-options-under.patch @@ -0,0 +1,80 @@ +From e7ed6473c2c8c4e45dd861bfa06e96189b11d8db Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Mon, 6 Nov 2023 18:00:08 +0800 +Subject: [PATCH] crypto: jitterentropy - Hide esoteric Kconfig options under + FIPS and EXPERT + +As JITTERENTROPY is selected by default if you enable the CRYPTO +API, any Kconfig options added there will show up for every single +user. Hide the esoteric options under EXPERT as well as FIPS so +that only distro makers will see them. + +Reported-by: Linus Torvalds +Signed-off-by: Herbert Xu +Reviewed-by: Stephan Mueller +Signed-off-by: Herbert Xu +--- + crypto/Kconfig | 28 +++++++++++++++++++++++++--- + 1 file changed, 25 insertions(+), 3 deletions(-) + +--- a/crypto/Kconfig ++++ b/crypto/Kconfig +@@ -1297,10 +1297,12 @@ config CRYPTO_JITTERENTROPY + + See https://www.chronox.de/jent/ + ++if CRYPTO_JITTERENTROPY ++if CRYPTO_FIPS && EXPERT ++ + choice + prompt "CPU Jitter RNG Memory Size" + default CRYPTO_JITTERENTROPY_MEMSIZE_2 +- depends on CRYPTO_JITTERENTROPY + help + The Jitter RNG measures the execution time of memory accesses. + Multiple consecutive memory accesses are performed. If the memory +@@ -1344,7 +1346,6 @@ config CRYPTO_JITTERENTROPY_OSR + int "CPU Jitter RNG Oversampling Rate" + range 1 15 + default 1 +- depends on CRYPTO_JITTERENTROPY + help + The Jitter RNG allows the specification of an oversampling rate (OSR). + The Jitter RNG operation requires a fixed amount of timing +@@ -1359,7 +1360,6 @@ config CRYPTO_JITTERENTROPY_OSR + + config CRYPTO_JITTERENTROPY_TESTINTERFACE + bool "CPU Jitter RNG Test Interface" +- depends on CRYPTO_JITTERENTROPY + help + The test interface allows a privileged process to capture + the raw unconditioned high resolution time stamp noise that +@@ -1377,6 +1377,28 @@ config CRYPTO_JITTERENTROPY_TESTINTERFAC + + If unsure, select N. + ++endif # if CRYPTO_FIPS && EXPERT ++ ++if !(CRYPTO_FIPS && EXPERT) ++ ++config CRYPTO_JITTERENTROPY_MEMORY_BLOCKS ++ int ++ default 64 ++ ++config CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE ++ int ++ default 32 ++ ++config CRYPTO_JITTERENTROPY_OSR ++ int ++ default 1 ++ ++config CRYPTO_JITTERENTROPY_TESTINTERFACE ++ bool ++ ++endif # if !(CRYPTO_FIPS && EXPERT) ++endif # if CRYPTO_JITTERENTROPY ++ + config CRYPTO_KDF800108_CTR + tristate + select CRYPTO_HMAC diff --git a/target/linux/generic/backport-6.6/906-07-v6.10-crypto-jitter-Use-kvfree_sensitive-to-fix-Coccinelle.patch b/target/linux/generic/backport-6.6/906-07-v6.10-crypto-jitter-Use-kvfree_sensitive-to-fix-Coccinelle.patch new file mode 100644 index 0000000000..88a0bd15c0 --- /dev/null +++ b/target/linux/generic/backport-6.6/906-07-v6.10-crypto-jitter-Use-kvfree_sensitive-to-fix-Coccinelle.patch @@ -0,0 +1,30 @@ +From 6e61ee1ca551292d8714c35c92a019c41db79e4e Mon Sep 17 00:00:00 2001 +From: Thorsten Blum +Date: Wed, 27 Mar 2024 23:25:09 +0100 +Subject: [PATCH] crypto: jitter - Use kvfree_sensitive() to fix Coccinelle + warning + +Replace memzero_explicit() and kvfree() with kvfree_sensitive() to fix +the following Coccinelle/coccicheck warning reported by +kfree_sensitive.cocci: + + WARNING opportunity for kfree_sensitive/kvfree_sensitive + +Signed-off-by: Thorsten Blum +Signed-off-by: Herbert Xu +--- + crypto/jitterentropy-kcapi.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/crypto/jitterentropy-kcapi.c ++++ b/crypto/jitterentropy-kcapi.c +@@ -61,8 +61,7 @@ void *jent_kvzalloc(unsigned int len) + + void jent_kvzfree(void *ptr, unsigned int len) + { +- memzero_explicit(ptr, len); +- kvfree(ptr); ++ kvfree_sensitive(ptr, len); + } + + void *jent_zalloc(unsigned int len) diff --git a/target/linux/generic/backport-6.6/906-08-v6.12-crypto-jitter-set-default-OSR-to-3.patch b/target/linux/generic/backport-6.6/906-08-v6.12-crypto-jitter-set-default-OSR-to-3.patch new file mode 100644 index 0000000000..ade8f1005b --- /dev/null +++ b/target/linux/generic/backport-6.6/906-08-v6.12-crypto-jitter-set-default-OSR-to-3.patch @@ -0,0 +1,36 @@ +From 95a798d20060d2b648dd604321e347c85edfd783 Mon Sep 17 00:00:00 2001 +From: Stephan Mueller +Date: Mon, 12 Aug 2024 08:25:42 +0200 +Subject: [PATCH] crypto: jitter - set default OSR to 3 + +The user space Jitter RNG library uses the oversampling rate of 3 which +implies that each time stamp is credited with 1/3 bit of entropy. To +obtain 256 bits of entropy, 768 time stamps need to be sampled. The +increase in OSR is applied based on a report where the Jitter RNG is +used on a system exhibiting a challenging environment to collect +entropy. + +This OSR default value is now applied to the Linux kernel version of +the Jitter RNG as well. + +The increase in the OSR from 1 to 3 also implies that the Jitter RNG is +now slower by default. + +Reported-by: Jeff Barnes +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +--- + crypto/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/crypto/Kconfig ++++ b/crypto/Kconfig +@@ -1345,7 +1345,7 @@ config CRYPTO_JITTERENTROPY_MEMORY_BLOCK + config CRYPTO_JITTERENTROPY_OSR + int "CPU Jitter RNG Oversampling Rate" + range 1 15 +- default 1 ++ default 3 + help + The Jitter RNG allows the specification of an oversampling rate (OSR). + The Jitter RNG operation requires a fixed amount of timing