Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
+2
-2
@@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-6.6 = .137
|
||||
LINUX_KERNEL_HASH-6.6.137 = 92f1e90d8be49f9d7f989e563c97a4f39cd7731025d7b81152814c68b5bd56c4
|
||||
LINUX_VERSION-6.6 = .139
|
||||
LINUX_KERNEL_HASH-6.6.139 = a7cd71371dae38ac94c6c332fe16391b83fe173158020e2ea1b37277f8f3d740
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mbedtls
|
||||
PKG_VERSION:=3.6.5
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=3.6.6
|
||||
PKG_RELEASE:=2
|
||||
PKG_BUILD_FLAGS:=no-mips16 gc-sections no-lto
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL=https://github.com/Mbed-TLS/$(PKG_NAME)/releases/download/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_HASH:=4a11f1777bb95bf4ad96721cac945a26e04bf19f57d905f241fe77ebeddf46d8
|
||||
PKG_HASH:=8fb65fae8dcae5840f793c0a334860a411f884cc537ea290ce1c52bb64ca007a
|
||||
|
||||
PKG_LICENSE:=GPL-2.0-or-later
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
From c4738fab064f018aa251577fae9399040a86bc33 Mon Sep 17 00:00:00 2001
|
||||
From: Viktor Sokolovskiy <maokaman@gmail.com>
|
||||
Date: Sat, 4 Apr 2026 03:57:04 +0300
|
||||
Subject: [PATCH] ssl: accept TLS 1.2 rsa_pss_rsae signature schemes
|
||||
|
||||
Signed-off-by: Viktor Sokolovskiy <maokaman@gmail.com>
|
||||
(cherry picked from commit c064ba0edb86e44f3c1c8dcaf05b1139407eebd4)
|
||||
---
|
||||
ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt | 3 +++
|
||||
library/ssl_misc.h | 19 +++++++++++++++++++
|
||||
tests/suites/test_suite_ssl.data | 12 ++++++++++++
|
||||
tests/suites/test_suite_ssl.function | 8 ++++++++
|
||||
4 files changed, 42 insertions(+)
|
||||
create mode 100644 ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt
|
||||
@@ -0,0 +1,3 @@
|
||||
+Bugfix
|
||||
+ * Fix a TLS 1.2 regression that caused clients to reject valid
|
||||
+ ServerKeyExchange signatures using RSA-PSS signature scheme values.
|
||||
--- a/library/ssl_misc.h
|
||||
+++ b/library/ssl_misc.h
|
||||
@@ -2591,6 +2591,25 @@ static inline int mbedtls_ssl_get_pk_typ
|
||||
static inline int mbedtls_ssl_tls12_sig_alg_is_supported(
|
||||
const uint16_t sig_alg)
|
||||
{
|
||||
+#if defined(PSA_WANT_ALG_RSA_PSS)
|
||||
+ switch (sig_alg) {
|
||||
+#if defined(PSA_WANT_ALG_SHA_256)
|
||||
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
+ return 1;
|
||||
+#endif
|
||||
+#if defined(PSA_WANT_ALG_SHA_384)
|
||||
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
+ return 1;
|
||||
+#endif
|
||||
+#if defined(PSA_WANT_ALG_SHA_512)
|
||||
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
+ return 1;
|
||||
+#endif
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+#endif /* PSA_WANT_ALG_RSA_PSS */
|
||||
+
|
||||
/* High byte is hash */
|
||||
unsigned char hash = MBEDTLS_BYTE_1(sig_alg);
|
||||
unsigned char sig = MBEDTLS_BYTE_0(sig_alg);
|
||||
--- a/tests/suites/test_suite_ssl.data
|
||||
+++ b/tests/suites/test_suite_ssl.data
|
||||
@@ -3546,3 +3546,15 @@ send_invalid_sig_alg:MBEDTLS_SSL_SIG_ECD
|
||||
|
||||
Default verify_result before doing a handshake
|
||||
verify_result_without_handshake
|
||||
+
|
||||
+TLS 1.2 accepts rsa_pss_rsae_sha256 in signature_algorithm
|
||||
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256
|
||||
+ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:1
|
||||
+
|
||||
+TLS 1.2 accepts rsa_pss_rsae_sha384 in signature_algorithm
|
||||
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_384
|
||||
+ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:1
|
||||
+
|
||||
+TLS 1.2 accepts rsa_pss_rsae_sha512 in signature_algorithm
|
||||
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512
|
||||
+ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:1
|
||||
--- a/tests/suites/test_suite_ssl.function
|
||||
+++ b/tests/suites/test_suite_ssl.function
|
||||
@@ -5861,6 +5861,14 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
+void ssl_tls12_sig_alg_supported(int sig_alg, int expected)
|
||||
+{
|
||||
+ TEST_EQUAL(mbedtls_ssl_tls12_sig_alg_is_supported((uint16_t) sig_alg),
|
||||
+ expected);
|
||||
+}
|
||||
+/* END_CASE */
|
||||
+
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */
|
||||
void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int use_context)
|
||||
{
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
From 3833db7c7cb167e8eda2ec5e07da70cd834e88d4 Mon Sep 17 00:00:00 2001
|
||||
From: Viktor Sokolovskiy <maokaman@gmail.com>
|
||||
Date: Fri, 17 Apr 2026 18:52:34 +0300
|
||||
Subject: [PATCH] ssl: narrow TLS 1.2 RSA-PSS handling and add interop coverage
|
||||
|
||||
Narrow TLS 1.2 RSA-PSS handling to the client ServerKeyExchange parse path and add OpenSSL and GnuTLS interoperability tests.
|
||||
|
||||
Signed-off-by: Viktor Sokolovskiy <maokaman@gmail.com>
|
||||
---
|
||||
ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt | 3 +-
|
||||
library/ssl_misc.h | 19 -------
|
||||
library/ssl_tls12_client.c | 63 +++++++++++++++++++----
|
||||
tests/ssl-opt.sh | 38 +++++++++++++-
|
||||
tests/suites/test_suite_ssl.data | 12 -----
|
||||
tests/suites/test_suite_ssl.function | 8 ---
|
||||
6 files changed, 91 insertions(+), 52 deletions(-)
|
||||
|
||||
--- a/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt
|
||||
+++ b/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt
|
||||
@@ -1,3 +1,4 @@
|
||||
Bugfix
|
||||
* Fix a TLS 1.2 regression that caused clients to reject valid
|
||||
- ServerKeyExchange signatures using RSA-PSS signature scheme values.
|
||||
+ ServerKeyExchange signatures using RSA-PSS signature algorithms.
|
||||
+ Fixes #10668.
|
||||
--- a/library/ssl_misc.h
|
||||
+++ b/library/ssl_misc.h
|
||||
@@ -2591,25 +2591,6 @@ static inline int mbedtls_ssl_get_pk_typ
|
||||
static inline int mbedtls_ssl_tls12_sig_alg_is_supported(
|
||||
const uint16_t sig_alg)
|
||||
{
|
||||
-#if defined(PSA_WANT_ALG_RSA_PSS)
|
||||
- switch (sig_alg) {
|
||||
-#if defined(PSA_WANT_ALG_SHA_256)
|
||||
- case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
- return 1;
|
||||
-#endif
|
||||
-#if defined(PSA_WANT_ALG_SHA_384)
|
||||
- case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
- return 1;
|
||||
-#endif
|
||||
-#if defined(PSA_WANT_ALG_SHA_512)
|
||||
- case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
- return 1;
|
||||
-#endif
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
-#endif /* PSA_WANT_ALG_RSA_PSS */
|
||||
-
|
||||
/* High byte is hash */
|
||||
unsigned char hash = MBEDTLS_BYTE_1(sig_alg);
|
||||
unsigned char sig = MBEDTLS_BYTE_0(sig_alg);
|
||||
--- a/library/ssl_tls12_client.c
|
||||
+++ b/library/ssl_tls12_client.c
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ssl_client.h"
|
||||
+#include "ssl_debug_helpers.h"
|
||||
#include "ssl_misc.h"
|
||||
#include "debug_internal.h"
|
||||
#include "mbedtls/error.h"
|
||||
@@ -2087,32 +2088,72 @@ static int ssl_parse_signature_algorithm
|
||||
{
|
||||
if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(sig_alg, pk_alg, md_alg) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
- ("Server used unsupported value in SigAlg extension 0x%04x",
|
||||
- sig_alg));
|
||||
+ ("Server used unsupported %s signature algorithm",
|
||||
+ mbedtls_ssl_sig_alg_to_str(sig_alg)));
|
||||
return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
/*
|
||||
- * mbedtls_ssl_get_pk_sigalg_and_md_alg_from_sig_alg() understands sig_alg code points across
|
||||
- * TLS versions. Make sure that the received sig_alg extension is valid in TLS 1.2.
|
||||
+ * mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg() understands
|
||||
+ * signature algorithm code points from both TLS 1.2 and TLS 1.3. Make sure
|
||||
+ * that the selected signature algorithm is acceptable when TLS 1.2 is
|
||||
+ * negotiated.
|
||||
+ *
|
||||
+ * In TLS 1.2, RSA-PSS signature algorithms (rsa_pss_rsae_*) are not
|
||||
+ * defined by RFC 5246. However, RFC 8446 Section 4.2.3 requires that
|
||||
+ * implementations which advertise support for RSASSA-PSS must be
|
||||
+ * prepared to accept such signatures even when TLS 1.2 is negotiated,
|
||||
+ * provided they were offered in the signature_algorithms extension.
|
||||
+ *
|
||||
+ * Therefore, we allow rsa_pss_rsae_* here if:
|
||||
+ * - the implementation supports them, and
|
||||
+ * - they were offered in the signature_algorithms extension (checked by
|
||||
+ * `mbedtls_ssl_sig_alg_is_offered()` below).
|
||||
+ *
|
||||
+ * If we were to add full support for rsa_pss_rsae_* signature algorithms
|
||||
+ * in TLS 1.2, we should then integrate RSA-PSS into the TLS 1.2 signature
|
||||
+ * algorithm support logic (`mbedtls_ssl_tls12_sig_alg_is_supported()`)
|
||||
+ * instead of handling it as a special case here.
|
||||
*/
|
||||
if (!mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) {
|
||||
- MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
- ("Server used unsupported value in SigAlg extension 0x%04x",
|
||||
- sig_alg));
|
||||
- return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
|
||||
+ switch (sig_alg) {
|
||||
+#if defined(PSA_WANT_ALG_RSA_PSS)
|
||||
+#if defined(PSA_WANT_ALG_SHA_256)
|
||||
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
|
||||
+#endif
|
||||
+#if defined(PSA_WANT_ALG_SHA_384)
|
||||
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
|
||||
+#endif
|
||||
+#if defined(PSA_WANT_ALG_SHA_512)
|
||||
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
|
||||
+#endif
|
||||
+#if defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384) || defined(PSA_WANT_ALG_SHA_512)
|
||||
+ MBEDTLS_SSL_DEBUG_MSG(3,
|
||||
+ ("Accepting TLS 1.2 RSA-PSS signature algorithm %s via compatibility exception",
|
||||
+ mbedtls_ssl_sig_alg_to_str(sig_alg)));
|
||||
+ break;
|
||||
+#endif
|
||||
+#endif /* PSA_WANT_ALG_RSA_PSS */
|
||||
+ default:
|
||||
+ MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
+ ("Server used unsupported %s signature algorithm",
|
||||
+ mbedtls_ssl_sig_alg_to_str(sig_alg)));
|
||||
+ return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the signature algorithm is acceptable
|
||||
*/
|
||||
if (!mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg)) {
|
||||
- MBEDTLS_SSL_DEBUG_MSG(1, ("Server used SigAlg value 0x%04x that was not offered", sig_alg));
|
||||
+ MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
+ ("Server used the signature algorithm %s that was not offered",
|
||||
+ mbedtls_ssl_sig_alg_to_str(sig_alg)));
|
||||
return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
- MBEDTLS_SSL_DEBUG_MSG(2, ("Server used SignatureAlgorithm %d", sig_alg & 0x00FF));
|
||||
- MBEDTLS_SSL_DEBUG_MSG(2, ("Server used HashAlgorithm %d", sig_alg >> 8));
|
||||
+ MBEDTLS_SSL_DEBUG_MSG(2, ("Server used the signature algorithm %s",
|
||||
+ mbedtls_ssl_sig_alg_to_str(sig_alg)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/tests/ssl-opt.sh
|
||||
+++ b/tests/ssl-opt.sh
|
||||
@@ -14948,7 +14948,6 @@ run_test "TLS 1.2: Check rsa_pss_rsae
|
||||
-c "Protocol is TLSv1.2" \
|
||||
-c "HTTP/1.0 200 [Oo][Kk]"
|
||||
|
||||
-
|
||||
requires_gnutls_tls1_3
|
||||
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||
requires_config_enabled MBEDTLS_DEBUG_C
|
||||
@@ -14964,6 +14963,43 @@ run_test "TLS 1.2: Check rsa_pss_rsae
|
||||
-c "Protocol is TLSv1.2" \
|
||||
-c "HTTP/1.0 200 [Oo][Kk]"
|
||||
|
||||
+requires_openssl_tls1_3_with_compatible_ephemeral
|
||||
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
|
||||
+requires_config_enabled MBEDTLS_DEBUG_C
|
||||
+requires_config_enabled MBEDTLS_SSL_CLI_C
|
||||
+requires_config_enabled PSA_WANT_ALG_RSA_PSS
|
||||
+requires_config_enabled PSA_WANT_ALG_SHA_256
|
||||
+run_test "TLS 1.2: Server forces TLS 1.2 and rsa_pss_rsae_sha256, m->O" \
|
||||
+ "$O_NEXT_SRV_NO_CERT -cert $DATA_FILES_PATH/server2-sha256.crt -key $DATA_FILES_PATH/server2.key
|
||||
+ -tls1_2 -sigalgs rsa_pss_rsae_sha256 " \
|
||||
+ "$P_CLI debug_level=3" \
|
||||
+ 0 \
|
||||
+ -c "sent signature scheme \\[804\\] rsa_pss_rsae_sha256" \
|
||||
+ -c "Perform .* computation of digest of ServerKeyExchange" \
|
||||
+ -c "Server used the signature algorithm rsa_pss_rsae_sha256" \
|
||||
+ -c "Protocol is TLSv1.2" \
|
||||
+ -c "HTTP/1.0 200 [Oo][Kk]"
|
||||
+
|
||||
+requires_gnutls_tls1_3
|
||||
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
|
||||
+requires_config_enabled MBEDTLS_DEBUG_C
|
||||
+requires_config_enabled MBEDTLS_SSL_CLI_C
|
||||
+requires_config_enabled PSA_WANT_ALG_RSA_PSS
|
||||
+requires_config_enabled PSA_WANT_ALG_SHA_256
|
||||
+run_test "TLS 1.2: Server forces TLS 1.2 and rsa_pss_rsae_sha256, m->G" \
|
||||
+ "$G_NEXT_SRV_NO_CERT --x509certfile $DATA_FILES_PATH/server2-sha256.crt --x509keyfile $DATA_FILES_PATH/server2.key
|
||||
+ --disable-client-cert
|
||||
+ --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256" \
|
||||
+ "$P_CLI debug_level=3" \
|
||||
+ 0 \
|
||||
+ -c "sent signature scheme \\[804\\] rsa_pss_rsae_sha256" \
|
||||
+ -c "Perform .* computation of digest of ServerKeyExchange" \
|
||||
+ -c "Server used the signature algorithm rsa_pss_rsae_sha256" \
|
||||
+ -c "Protocol is TLSv1.2" \
|
||||
+ -c "HTTP/1.0 200 [Oo][Kk]"
|
||||
+
|
||||
requires_config_enabled MBEDTLS_SSL_SRV_C
|
||||
requires_config_enabled MBEDTLS_DEBUG_C
|
||||
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
|
||||
--- a/tests/suites/test_suite_ssl.data
|
||||
+++ b/tests/suites/test_suite_ssl.data
|
||||
@@ -3546,15 +3546,3 @@ send_invalid_sig_alg:MBEDTLS_SSL_SIG_ECD
|
||||
|
||||
Default verify_result before doing a handshake
|
||||
verify_result_without_handshake
|
||||
-
|
||||
-TLS 1.2 accepts rsa_pss_rsae_sha256 in signature_algorithm
|
||||
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256
|
||||
-ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:1
|
||||
-
|
||||
-TLS 1.2 accepts rsa_pss_rsae_sha384 in signature_algorithm
|
||||
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_384
|
||||
-ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:1
|
||||
-
|
||||
-TLS 1.2 accepts rsa_pss_rsae_sha512 in signature_algorithm
|
||||
-depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_512
|
||||
-ssl_tls12_sig_alg_supported:MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:1
|
||||
--- a/tests/suites/test_suite_ssl.function
|
||||
+++ b/tests/suites/test_suite_ssl.function
|
||||
@@ -5861,14 +5861,6 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
-/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
-void ssl_tls12_sig_alg_supported(int sig_alg, int expected)
|
||||
-{
|
||||
- TEST_EQUAL(mbedtls_ssl_tls12_sig_alg_is_supported((uint16_t) sig_alg),
|
||||
- expected);
|
||||
-}
|
||||
-/* END_CASE */
|
||||
-
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */
|
||||
void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int use_context)
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/library/common.h
|
||||
+++ b/library/common.h
|
||||
@@ -199,7 +199,7 @@ static inline void mbedtls_xor(unsigned
|
||||
@@ -224,7 +224,7 @@ static inline void mbedtls_xor(unsigned
|
||||
uint8x16_t x = veorq_u8(v1, v2);
|
||||
vst1q_u8(r + i, x);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=openssl
|
||||
PKG_VERSION:=3.0.19
|
||||
PKG_VERSION:=3.0.20
|
||||
PKG_RELEASE:=1
|
||||
PKG_BUILD_FLAGS:=no-mips16 gc-sections no-lto
|
||||
|
||||
@@ -21,7 +21,7 @@ PKG_SOURCE_URL:= \
|
||||
https://www.openssl.org/source/old/$(PKG_BASE)/ \
|
||||
https://github.com/openssl/openssl/releases/download/$(PKG_NAME)-$(PKG_VERSION)/
|
||||
|
||||
PKG_HASH:=fa5a4143b8aae18be53ef2f3caf29a2e0747430b8bc74d32d88335b94ab63072
|
||||
PKG_HASH:=c80a01dfc70ece4dc21168932c37739042d404d46ccc81a5986dd75314ecda6f
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_LICENSE_FILES:=LICENSE.txt
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wolfssl
|
||||
PKG_VERSION:=5.7.6
|
||||
PKG_VERSION:=5.9.1
|
||||
PKG_REAL_VERSION:=$(PKG_VERSION)-stable
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_REAL_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/wolfSSL/wolfssl/archive/v$(PKG_REAL_VERSION)
|
||||
PKG_HASH:=52b1e439e30d1ed8162a16308a8525a862183b67aa30373b11166ecbab000d63
|
||||
PKG_HASH:=d5ca7af48cd2d9a91d539e9baedeba55a0605a28d7ac8b01dc3d5254a13ca341
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_REAL_VERSION)
|
||||
|
||||
@@ -22,7 +22,7 @@ PKG_FIXUP:=libtool libtool-abiver
|
||||
PKG_INSTALL:=1
|
||||
PKG_BUILD_FLAGS:=no-mips16 lto
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_LICENSE:=GPL-2.0-or-later
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_LICENSE_FILES:=LICENSING COPYING
|
||||
PKG_MAINTAINER:=Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||||
PKG_CPE_ID:=cpe:/a:wolfssl:wolfssl
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/wolfssl/wolfcrypt/settings.h
|
||||
+++ b/wolfssl/wolfcrypt/settings.h
|
||||
@@ -3722,7 +3722,7 @@ extern void uITRON4_free(void *p) ;
|
||||
@@ -4154,7 +4154,7 @@ extern void uITRON4_free(void *p) ;
|
||||
|
||||
/* warning for not using harden build options (default with ./configure) */
|
||||
/* do not warn if big integer support is disabled */
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
commit ec2fbfbbdaa7d7db1c707dce26ce1a37cfe09660
|
||||
Author: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Fri Apr 10 16:29:31 2026 +0100
|
||||
|
||||
Fix buffer overflow in struct bigname. CVE-2026-2291
|
||||
|
||||
All buffers capable of holding a domain name should be
|
||||
at least MAXDNAME*2 + 1 bytes long, where MAXDNAME is the maximum
|
||||
size of a domain name. The accounts for the trailing zero and the
|
||||
fact that some characters are escaped in the internal representation
|
||||
of a domain name in dnsmasq.
|
||||
|
||||
The declaration of struct bigname get this wrong, with the effect
|
||||
that a remote attacker capable of asking DNS queries or answering DNS
|
||||
queries can cause a large OOB write in the heap.
|
||||
|
||||
This was first spotted by Andrew S. Fasano.
|
||||
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -467,7 +467,7 @@ struct interface_name {
|
||||
};
|
||||
|
||||
union bigname {
|
||||
- char name[MAXDNAME];
|
||||
+ char name[(2*MAXDNAME) + 1];
|
||||
union bigname *next; /* freelist */
|
||||
};
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
commit de76f21e115c451cf0653790fc4b209cd4778a07
|
||||
Author: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Fri Apr 10 22:16:45 2026 +0100
|
||||
|
||||
Fix NSEC bitmap parsing infinite loop. CVE-2026-4890
|
||||
|
||||
Report from Royce M <royce@xchglabs.com>.
|
||||
|
||||
Location: dnssec.c:1290-1306, dnssec.c:1450-1463
|
||||
|
||||
The bitmap window iteration advances by p[1] instead of p[1]+2 (missing the 2-byte window header). With bitmap_length=0, both rdlen and p are
|
||||
unchanged, causing an infinite loop and dnsmasq stops responding to all queries.
|
||||
|
||||
The same code accesses p[2] after only checking rdlen >= 2 without verifying p[1] >= 1, causing OOB reads at 6 locations.
|
||||
|
||||
Both bugs are reachable before RRSIG validation (confirmed by the source comment at line 2125), so no valid DNSSEC signatures are needed.
|
||||
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -1270,10 +1270,10 @@ static int prove_non_existence_nsec(stru
|
||||
packet checked to be as long as rdlen implies in prove_non_existence() */
|
||||
|
||||
/* If we can prove that there's no NS record, return that information. */
|
||||
- if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) != 0)
|
||||
+ if (nons && rdlen >= 2 && p[0] == 0 && p[1] >= 1 && (p[2] & (0x80 >> T_NS)) != 0)
|
||||
*nons = 0;
|
||||
|
||||
- if (rdlen >= 2 && p[0] == 0)
|
||||
+ if (rdlen >= 2 && p[0] == 0 && p[1] >= 1)
|
||||
{
|
||||
/* A CNAME answer would also be valid, so if there's a CNAME is should
|
||||
have been returned. */
|
||||
@@ -1301,8 +1301,8 @@ static int prove_non_existence_nsec(stru
|
||||
break; /* finished checking */
|
||||
}
|
||||
|
||||
- rdlen -= p[1];
|
||||
- p += p[1];
|
||||
+ rdlen -= p[1] + 2;
|
||||
+ p += p[1] + 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1429,7 +1429,7 @@ static int check_nsec3_coverage(struct d
|
||||
p += hash_len; /* skip next-domain hash */
|
||||
rdlen -= p - psave;
|
||||
|
||||
- if (rdlen >= 2 && p[0] == 0)
|
||||
+ if (rdlen >= 2 && p[0] == 0 && p[1] >= 1)
|
||||
{
|
||||
/* If we can prove that there's no NS record, return that information. */
|
||||
if (nons && (p[2] & (0x80 >> T_NS)) != 0)
|
||||
@@ -1458,8 +1458,8 @@ static int check_nsec3_coverage(struct d
|
||||
break; /* finished checking */
|
||||
}
|
||||
|
||||
- rdlen -= p[1];
|
||||
- p += p[1];
|
||||
+ rdlen -= p[1] + 2;
|
||||
+ p += p[1] + 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -0,0 +1,32 @@
|
||||
commit 2cacea42e4d45717bd0ce3ccfe8e78960245e5da
|
||||
Author: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed Mar 25 23:04:08 2026 +0000
|
||||
|
||||
Verify rdlen field in RRSIG packets. CVE-2026-4891
|
||||
|
||||
Bug report from Royce M <royce@xchglabs.com>
|
||||
|
||||
This avoids crafted packets which give a value for rdlen _less_
|
||||
then the space taken up by the fixed data and the signer's name
|
||||
and engender a negative calculated length for the signature.
|
||||
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -546,10 +546,14 @@ static int validate_rrset(time_t now, st
|
||||
|
||||
*ttl_out = ttl;
|
||||
}
|
||||
-
|
||||
+
|
||||
+ /* Don't trust rdlen not to be too small and give us a negative sig_len
|
||||
+ It has already been checked that it doesn't run us off the end
|
||||
+ of the packet. */
|
||||
+ if ((sig_len = rdlen - (p - psav)) <= 0)
|
||||
+ return STAT_BOGUS;
|
||||
+
|
||||
sig = p;
|
||||
- sig_len = rdlen - (p - psav);
|
||||
-
|
||||
nsigttl = htonl(orig_ttl);
|
||||
|
||||
hash->update(ctx, 18, psav);
|
||||
@@ -0,0 +1,28 @@
|
||||
commit 011a36c51438c986535a7248ed2e7f424f8e1078
|
||||
Author: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed Mar 25 23:16:35 2026 +0000
|
||||
|
||||
Fix buffer overflow in helper.c with large CLIDs. CVE-2026-4892
|
||||
|
||||
Bug reported bt Royce M <royce@xchglabs.com>
|
||||
|
||||
Location: helper.c:265-270
|
||||
DHCPv6 CLIDs can be up to 65535 bytes. When --dhcp-script is configured,
|
||||
the helper hex-encodes raw CLID bytes via sprintf("%.2x") into daemon->packet (5131 bytes).
|
||||
A 1000-byte CLID writes ~3000 bytes. The helper process retains root privileges.
|
||||
|
||||
Note: log6_packet() correctly caps CLID to 100 bytes for logging, but the helper code path was missed.
|
||||
|
||||
--- a/src/helper.c
|
||||
+++ b/src/helper.c
|
||||
@@ -261,8 +261,8 @@ int create_helper(int event_fd, int err_
|
||||
data.hostname_len + data.ed_len + data.clid_len, 1))
|
||||
continue;
|
||||
|
||||
- /* CLID into packet */
|
||||
- for (p = daemon->packet, i = 0; i < data.clid_len; i++)
|
||||
+ /* CLID into packet: limit to 100 bytes to avoid overflowing buffer. */
|
||||
+ for (p = daemon->packet, i = 0; i < data.clid_len && i < 100; i++)
|
||||
{
|
||||
p += sprintf(p, "%.2x", buf[i]);
|
||||
if (i != data.clid_len - 1)
|
||||
@@ -0,0 +1,26 @@
|
||||
commit 434d68f2eb1a58744470698483a3ae09b5a9a870
|
||||
Author: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Wed Mar 25 23:22:37 2026 +0000
|
||||
|
||||
Fix broken client subnet validation. CVE-2026-4893
|
||||
|
||||
Bug report from Royce M <royce@xchglabs.com>
|
||||
|
||||
Location: forward.c:713, edns0.c:421
|
||||
|
||||
With --add-subnet enabled, process_reply() passes the OPT record
|
||||
length (~23 bytes) instead of the packet length to check_source().
|
||||
All internal bounds checks fail, and the function always returns 1.
|
||||
ECS source validation per RFC 7871 Section 9.2 is completely bypassed.
|
||||
|
||||
--- a/src/forward.c
|
||||
+++ b/src/forward.c
|
||||
@@ -710,7 +710,7 @@ static size_t process_reply(struct dns_h
|
||||
/* Get extended RCODE. */
|
||||
rcode |= sizep[2] << 4;
|
||||
|
||||
- if (option_bool(OPT_CLIENT_SUBNET) && !check_source(header, plen, pheader, query_source))
|
||||
+ if (option_bool(OPT_CLIENT_SUBNET) && !check_source(header, n, pheader, query_source))
|
||||
{
|
||||
my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch"));
|
||||
return 0;
|
||||
@@ -0,0 +1,26 @@
|
||||
commit fa3c8ddef6712b52f562813317e6a997e1210123
|
||||
Author: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Mon Mar 30 16:24:33 2026 +0100
|
||||
|
||||
Fix buffer overflow vulnerability in extract_addresses() CVE-2026-5172
|
||||
|
||||
Thanks to Hugo Martinez Ray for spotting this.
|
||||
|
||||
The value of rdlen for an RR can be a lie, allowing the
|
||||
call to extract_name() at rfc1025.c:952 to advance the value of p1
|
||||
past the calculated end of the record. The makes the calculation
|
||||
of bytes remaining in the RR underflow to a huge number and results
|
||||
in a massive heap OOB read and certain crash.
|
||||
|
||||
--- a/src/rfc1035.c
|
||||
+++ b/src/rfc1035.c
|
||||
@@ -932,7 +932,8 @@ int extract_addresses(struct dns_header
|
||||
/* Name, extract it then re-encode. */
|
||||
int len;
|
||||
|
||||
- if (!extract_name(header, qlen, &p1, name, 1, 0))
|
||||
+ /* rdlen may lie, and extract_name() advances p1 past where it says the record ends. */
|
||||
+ if (!extract_name(header, qlen, &p1, name, 1, 0) || (p1 > endrr))
|
||||
{
|
||||
blockdata_free(addr.rrblock.rrdata);
|
||||
return 2;
|
||||
@@ -231,7 +231,7 @@ CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_AIROHA=y
|
||||
CONFIG_NET_AIROHA_FLOW_STATS=y
|
||||
# CONFIG_NET_AIROHA_FLOW_STATS is not set
|
||||
CONFIG_NET_AIROHA_NPU=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include "an7581.dtsi"
|
||||
#include "an7581-npu-mt7996.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Airoha AN7581 Evaluation Board";
|
||||
@@ -214,6 +215,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
&npu {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
|
||||
&npu {
|
||||
firmware-name = "airoha/en7581_npu_rv32.bin",
|
||||
"airoha/en7581_npu_data.bin";
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
|
||||
&npu {
|
||||
firmware-name = "airoha/en7581_MT7996_npu_rv32.bin",
|
||||
"airoha/en7581_MT7996_npu_data.bin";
|
||||
};
|
||||
@@ -54,6 +54,11 @@
|
||||
no-map;
|
||||
reg = <0x0 0x90c00000 0x0 0x6800>;
|
||||
};
|
||||
|
||||
npu_ba: npu-ba@90c06800 {
|
||||
no-map;
|
||||
reg = <0x0 0x90c06800 0x0 0x200000>;
|
||||
};
|
||||
};
|
||||
|
||||
psci {
|
||||
@@ -706,6 +711,8 @@
|
||||
|
||||
mediatek,pbus-csr = <&pbus_csr 0x0 0x4>;
|
||||
|
||||
airoha,np-scu = <&scuclk>;
|
||||
|
||||
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-range = <0x00 0xff>;
|
||||
#interrupt-cells = <1>;
|
||||
@@ -792,6 +799,8 @@
|
||||
|
||||
mediatek,pbus-csr = <&pbus_csr 0x10 0x14>;
|
||||
|
||||
airoha,np-scu = <&scuclk>;
|
||||
|
||||
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-range = <0x00 0xff>;
|
||||
#interrupt-cells = <1>;
|
||||
@@ -829,9 +838,9 @@
|
||||
<GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
|
||||
memory-region = <&npu_binary>, <&npu_pkt>, <&npu_txpkt>,
|
||||
<&npu_txbufid>;
|
||||
<&npu_txbufid>, <&npu_ba>;
|
||||
memory-region-names = "binary", "pkt", "tx-pkt",
|
||||
"tx-bufid";
|
||||
"tx-bufid", "ba";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -972,7 +981,6 @@
|
||||
gsw_phy1: ethernet-phy@9 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <9>;
|
||||
interrupts = <1>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
@@ -995,7 +1003,6 @@
|
||||
gsw_phy2: ethernet-phy@a {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <10>;
|
||||
interrupts = <2>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
@@ -1018,7 +1025,6 @@
|
||||
gsw_phy3: ethernet-phy@b {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <11>;
|
||||
interrupts = <3>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
@@ -1041,7 +1047,6 @@
|
||||
gsw_phy4: ethernet-phy@c {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <12>;
|
||||
interrupts = <4>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
|
||||
@@ -207,6 +207,9 @@ CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
# CONFIG_MDIO_AIROHA is not set
|
||||
# CONFIG_PCS_AIROHA_AN7581 is not set
|
||||
# CONFIG_PCS_AIROHA_AN7583 is not set
|
||||
CONFIG_OLD_SIGACTION=y
|
||||
CONFIG_OLD_SIGSUSPEND3=y
|
||||
CONFIG_OUTER_CACHE=y
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From a7fc8c641cab855824c45e5e8877e40fd528b5df Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 2 Jan 2026 12:29:38 +0100
|
||||
Subject: [PATCH] net: airoha: Fix npu rx DMA definitions
|
||||
|
||||
Fix typos in npu rx DMA descriptor definitions.
|
||||
|
||||
Fixes: b3ef7bdec66fb ("net: airoha: Add airoha_offload.h header")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260102-airoha-npu-dma-rx-def-fixes-v1-1-205fc6bf7d94@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/linux/soc/airoha/airoha_offload.h | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/include/linux/soc/airoha/airoha_offload.h
|
||||
+++ b/include/linux/soc/airoha/airoha_offload.h
|
||||
@@ -70,12 +70,12 @@ static inline void airoha_ppe_dev_check_
|
||||
#define NPU_RX1_DESC_NUM 512
|
||||
|
||||
/* CTRL */
|
||||
-#define NPU_RX_DMA_DESC_LAST_MASK BIT(29)
|
||||
-#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(28, 15)
|
||||
-#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(14, 1)
|
||||
+#define NPU_RX_DMA_DESC_LAST_MASK BIT(27)
|
||||
+#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(26, 14)
|
||||
+#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(13, 1)
|
||||
#define NPU_RX_DMA_DESC_DONE_MASK BIT(0)
|
||||
/* INFO */
|
||||
-#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 28)
|
||||
+#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 29)
|
||||
#define NPU_RX_DMA_PKT_ID_MASK GENMASK(28, 26)
|
||||
#define NPU_RX_DMA_SRC_PORT_MASK GENMASK(25, 21)
|
||||
#define NPU_RX_DMA_CRSN_MASK GENMASK(20, 16)
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
From 5e7365b5a1ac8f517a7a84442289d7de242deb76 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sun, 14 Dec 2025 10:30:07 +0100
|
||||
Subject: [PATCH] net: airoha: Move net_devs registration in a dedicated
|
||||
routine
|
||||
|
||||
Since airoha_probe() is not executed under rtnl lock, there is small race
|
||||
where a given device is configured by user-space while the remaining ones
|
||||
are not completely loaded from the dts yet. This condition will allow a
|
||||
hw device misconfiguration since there are some conditions (e.g. GDM2 check
|
||||
in airoha_dev_init()) that require all device are properly loaded from the
|
||||
device tree. Fix the issue moving net_devices registration at the end of
|
||||
the airoha_probe routine.
|
||||
|
||||
Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://patch.msgid.link/20251214-airoha-fix-dev-registration-v1-1-860e027ad4c6@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 39 ++++++++++++++++--------
|
||||
1 file changed, 26 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2925,19 +2925,26 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->id = id;
|
||||
eth->ports[p] = port;
|
||||
|
||||
- err = airoha_metadata_dst_alloc(port);
|
||||
- if (err)
|
||||
- return err;
|
||||
+ return airoha_metadata_dst_alloc(port);
|
||||
+}
|
||||
|
||||
- err = register_netdev(dev);
|
||||
- if (err)
|
||||
- goto free_metadata_dst;
|
||||
+static int airoha_register_gdm_devices(struct airoha_eth *eth)
|
||||
+{
|
||||
+ int i;
|
||||
|
||||
- return 0;
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
+ struct airoha_gdm_port *port = eth->ports[i];
|
||||
+ int err;
|
||||
+
|
||||
+ if (!port)
|
||||
+ continue;
|
||||
+
|
||||
+ err = register_netdev(port->dev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
-free_metadata_dst:
|
||||
- airoha_metadata_dst_free(port);
|
||||
- return err;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int airoha_probe(struct platform_device *pdev)
|
||||
@@ -3028,6 +3035,10 @@ static int airoha_probe(struct platform_
|
||||
}
|
||||
}
|
||||
|
||||
+ err = airoha_register_gdm_devices(eth);
|
||||
+ if (err)
|
||||
+ goto error_napi_stop;
|
||||
+
|
||||
return 0;
|
||||
|
||||
error_napi_stop:
|
||||
@@ -3041,10 +3052,12 @@ error_hw_cleanup:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
|
||||
- if (port && port->dev->reg_state == NETREG_REGISTERED) {
|
||||
+ if (!port)
|
||||
+ continue;
|
||||
+
|
||||
+ if (port->dev->reg_state == NETREG_REGISTERED)
|
||||
unregister_netdev(port->dev);
|
||||
- airoha_metadata_dst_free(port);
|
||||
- }
|
||||
+ airoha_metadata_dst_free(port);
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
From 4d513329b87c1bd0546d9f0288794e244322daa6 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 5 Jan 2026 10:40:47 +0100
|
||||
Subject: [PATCH] net: airoha: Use gdm port enum value whenever possible
|
||||
|
||||
Use AIROHA_GDMx_IDX enum value whenever possible.
|
||||
This patch is just cosmetic changes and does not introduce any logic one.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260105-airoha-use-port-idx-enum-v1-1-503ca5763858@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 40 +++++++++++++-----------
|
||||
1 file changed, 21 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -108,11 +108,11 @@ static int airoha_set_vip_for_gdm_port(s
|
||||
u32 vip_port;
|
||||
|
||||
switch (port->id) {
|
||||
- case 3:
|
||||
+ case AIROHA_GDM3_IDX:
|
||||
/* FIXME: handle XSI_PCIE1_PORT */
|
||||
vip_port = XSI_PCIE0_VIP_PORT_MASK;
|
||||
break;
|
||||
- case 4:
|
||||
+ case AIROHA_GDM4_IDX:
|
||||
/* FIXME: handle XSI_USB_PORT */
|
||||
vip_port = XSI_ETH_VIP_PORT_MASK;
|
||||
break;
|
||||
@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_
|
||||
FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
|
||||
FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
|
||||
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK);
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);
|
||||
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
@@ -1691,27 +1691,29 @@ static int airhoha_set_gdm2_loopback(str
|
||||
/* Forward the traffic to the proper GDM port */
|
||||
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
|
||||
: FE_PSE_PORT_GDM4;
|
||||
- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
|
||||
- airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC_MASK);
|
||||
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
|
||||
+ pse_port);
|
||||
+ airoha_fe_clear(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
|
||||
+ GDM_STRIP_CRC_MASK);
|
||||
|
||||
/* Enable GDM2 loopback */
|
||||
- airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff);
|
||||
- airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
|
||||
+ airoha_fe_wr(eth, REG_GDM_TXCHN_EN(AIROHA_GDM2_IDX), 0xffffffff);
|
||||
+ airoha_fe_wr(eth, REG_GDM_RXCHN_EN(AIROHA_GDM2_IDX), 0xffff);
|
||||
|
||||
chan = port->id == AIROHA_GDM3_IDX ? airoha_is_7581(eth) ? 4 : 3 : 0;
|
||||
- airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
|
||||
+ airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX),
|
||||
LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
|
||||
FIELD_PREP(LPBK_CHAN_MASK, chan) |
|
||||
LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK |
|
||||
LBK_CHAN_MODE_MASK | LPBK_EN_MASK);
|
||||
- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2),
|
||||
+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(AIROHA_GDM2_IDX),
|
||||
GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
|
||||
FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU));
|
||||
|
||||
/* Disable VIP and IFC for GDM2 */
|
||||
- airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
|
||||
- airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
|
||||
+ airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
+ airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
|
||||
/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
|
||||
nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
|
||||
@@ -1747,8 +1749,8 @@ static int airoha_dev_init(struct net_de
|
||||
airoha_set_macaddr(port, dev->dev_addr);
|
||||
|
||||
switch (port->id) {
|
||||
- case 3:
|
||||
- case 4:
|
||||
+ case AIROHA_GDM3_IDX:
|
||||
+ case AIROHA_GDM4_IDX:
|
||||
/* If GDM2 is active we can't enable loopback */
|
||||
if (!eth->ports[1]) {
|
||||
int err;
|
||||
@@ -1758,7 +1760,7 @@ static int airoha_dev_init(struct net_de
|
||||
return err;
|
||||
}
|
||||
fallthrough;
|
||||
- case 2:
|
||||
+ case AIROHA_GDM2_IDX:
|
||||
if (airoha_ppe_is_enabled(eth, 1)) {
|
||||
/* For PPE2 always use secondary cpu port. */
|
||||
fe_cpu_port = FE_PSE_PORT_CDM2;
|
||||
@@ -3102,14 +3104,14 @@ static const char * const en7581_xsi_rst
|
||||
static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
|
||||
{
|
||||
switch (port->id) {
|
||||
- case 3:
|
||||
+ case AIROHA_GDM3_IDX:
|
||||
/* 7581 SoC supports PCIe serdes on GDM3 port */
|
||||
if (nbq == 4)
|
||||
return HSGMII_LAN_7581_PCIE0_SRCPORT;
|
||||
if (nbq == 5)
|
||||
return HSGMII_LAN_7581_PCIE1_SRCPORT;
|
||||
break;
|
||||
- case 4:
|
||||
+ case AIROHA_GDM4_IDX:
|
||||
/* 7581 SoC supports eth and usb serdes on GDM4 port */
|
||||
if (!nbq)
|
||||
return HSGMII_LAN_7581_ETH_SRCPORT;
|
||||
@@ -3133,12 +3135,12 @@ static const char * const an7583_xsi_rst
|
||||
static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq)
|
||||
{
|
||||
switch (port->id) {
|
||||
- case 3:
|
||||
+ case AIROHA_GDM3_IDX:
|
||||
/* 7583 SoC supports eth serdes on GDM3 port */
|
||||
if (!nbq)
|
||||
return HSGMII_LAN_7583_ETH_SRCPORT;
|
||||
break;
|
||||
- case 4:
|
||||
+ case AIROHA_GDM4_IDX:
|
||||
/* 7583 SoC supports PCIe and USB serdes on GDM4 port */
|
||||
if (!nbq)
|
||||
return HSGMII_LAN_7583_PCIE_SRCPORT;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
From e4bc5dd53bf5d46cd58f081ffccc3809e2be5373 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 5 Jan 2026 09:49:16 +0100
|
||||
Subject: [PATCH] net: airoha: npu: Dump fw version during probe
|
||||
|
||||
Dump firmware version running on the npu during module probe.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260105-airoha-npu-dump-fw-v1-1-36d8326975f8@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_npu.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_npu.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_npu.c
|
||||
@@ -658,6 +658,7 @@ static int airoha_npu_probe(struct platf
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
int i, irq, err;
|
||||
+ u32 val;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
@@ -757,6 +758,11 @@ static int airoha_npu_probe(struct platf
|
||||
regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1);
|
||||
msleep(100);
|
||||
|
||||
+ if (!airoha_npu_wlan_msg_get(npu, 0, WLAN_FUNC_GET_WAIT_NPU_VERSION,
|
||||
+ &val, sizeof(val), GFP_KERNEL))
|
||||
+ dev_info(dev, "NPU fw version: %0d.%d\n",
|
||||
+ (val >> 16) & 0xffff, val & 0xffff);
|
||||
+
|
||||
platform_set_drvdata(pdev, npu);
|
||||
|
||||
return 0;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
From 6abcf751bc084804a9e5b3051442e8a2ce67f48a Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 5 Jan 2026 09:43:31 +0100
|
||||
Subject: [PATCH] net: airoha: Fix schedule while atomic in airoha_ppe_deinit()
|
||||
|
||||
airoha_ppe_deinit() runs airoha_npu_ppe_deinit() in atomic context.
|
||||
airoha_npu_ppe_deinit routine allocates ppe_data buffer with GFP_KERNEL
|
||||
flag. Rely on rcu_replace_pointer in airoha_ppe_deinit routine in order
|
||||
to fix schedule while atomic issue in airoha_npu_ppe_deinit() since we
|
||||
do not need atomic context there.
|
||||
|
||||
Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260105-airoha-fw-ethtool-v2-1-3b32b158cc31@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -1547,13 +1547,16 @@ void airoha_ppe_deinit(struct airoha_eth
|
||||
{
|
||||
struct airoha_npu *npu;
|
||||
|
||||
- rcu_read_lock();
|
||||
- npu = rcu_dereference(eth->npu);
|
||||
+ mutex_lock(&flow_offload_mutex);
|
||||
+
|
||||
+ npu = rcu_replace_pointer(eth->npu, NULL,
|
||||
+ lockdep_is_held(&flow_offload_mutex));
|
||||
if (npu) {
|
||||
npu->ops.ppe_deinit(npu);
|
||||
airoha_npu_put(npu);
|
||||
}
|
||||
- rcu_read_unlock();
|
||||
+
|
||||
+ mutex_unlock(&flow_offload_mutex);
|
||||
|
||||
rhashtable_destroy(ð->ppe->l2_flows);
|
||||
rhashtable_destroy(ð->flow_table);
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
From 50e194b6da721e4fa1fc6ebcf5969803c214929a Mon Sep 17 00:00:00 2001
|
||||
From: Aleksander Jan Bajkowski <olek2@wp.pl>
|
||||
Date: Sat, 10 Jan 2026 18:02:05 +0100
|
||||
Subject: [PATCH] net: airoha: implement get_link_ksettings
|
||||
|
||||
Implement the .get_link_ksettings to get the rate, duplex, and
|
||||
auto-negotiation status.
|
||||
|
||||
Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
|
||||
Tested-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260110170212.570793-1-olek2@wp.pl
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2806,6 +2806,7 @@ static const struct ethtool_ops airoha_e
|
||||
.get_drvinfo = airoha_ethtool_get_drvinfo,
|
||||
.get_eth_mac_stats = airoha_ethtool_get_mac_stats,
|
||||
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
|
||||
+ .get_link_ksettings = phy_ethtool_get_link_ksettings,
|
||||
.get_link = ethtool_op_get_link,
|
||||
};
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
From 875a59c9a9e584d99d8e9e5aa8435ec9300bfe91 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Thu, 8 Jan 2026 16:05:08 +0100
|
||||
Subject: [PATCH] net: airoha: npu: Init BA memory region if provided via DTS
|
||||
|
||||
Initialize NPU Block Ack memory region if reserved via DTS.
|
||||
Block Ack memory region is used by NPU MT7996 (Eagle) offloading.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260108-airoha-ba-memory-region-v3-2-bf1814e5dcc4@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_npu.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_npu.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_npu.c
|
||||
@@ -519,6 +519,14 @@ static int airoha_npu_wlan_init_memory(s
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ if (of_property_match_string(npu->dev->of_node, "memory-region-names",
|
||||
+ "ba") >= 0) {
|
||||
+ cmd = WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR;
|
||||
+ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "ba", cmd);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
cmd = WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU;
|
||||
return airoha_npu_wlan_msg_send(npu, 0, cmd, &val, sizeof(val),
|
||||
GFP_KERNEL);
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From 6406fc709ace081575de2a8a7eee12e63d4c96c6 Mon Sep 17 00:00:00 2001
|
||||
From: Sayantan Nandy <sayantann11@gmail.com>
|
||||
Date: Mon, 19 Jan 2026 13:06:58 +0530
|
||||
Subject: [PATCH] net: airoha_eth: increase max MTU to 9220 for DSA jumbo
|
||||
frames
|
||||
|
||||
The industry standard jumbo frame MTU is 9216 bytes. When using the DSA
|
||||
subsystem, a 4-byte tag is added to each Ethernet frame.
|
||||
|
||||
Increase AIROHA_MAX_MTU to 9220 bytes (9216 + 4) so that users can set a
|
||||
standard 9216-byte MTU on DSA ports.
|
||||
|
||||
The underlying hardware supports significantly larger frame sizes
|
||||
(approximately 16K). However, the maximum MTU is limited to 9220 bytes
|
||||
for now, as this is sufficient to support standard jumbo frames and does
|
||||
not incur additional memory allocation overhead.
|
||||
|
||||
Signed-off-by: Sayantan Nandy <sayantann11@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260119073658.6216-1-sayantann11@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -21,7 +21,7 @@
|
||||
#define AIROHA_MAX_NUM_IRQ_BANKS 4
|
||||
#define AIROHA_MAX_DSA_PORTS 7
|
||||
#define AIROHA_MAX_NUM_RSTS 3
|
||||
-#define AIROHA_MAX_MTU 9216
|
||||
+#define AIROHA_MAX_MTU 9220
|
||||
#define AIROHA_MAX_PACKET_SIZE 2048
|
||||
#define AIROHA_NUM_QOS_CHANNELS 4
|
||||
#define AIROHA_NUM_QOS_QUEUES 8
|
||||
-410
@@ -1,410 +0,0 @@
|
||||
From 527123b53739a2f73ca924b9c6e2f63dc66739a5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 1 Aug 2025 11:06:56 +0200
|
||||
Subject: [PATCH 1/3] ASoC: mediatek: move some header to global include
|
||||
|
||||
In preparation for support of Airoha SoC sound system based on Mediatek
|
||||
AFE, move some header to global include to prevent having to use complex
|
||||
redirection for inclusion.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
.../common => include/sound/mediatek}/mtk-afe-fe-dai.h | 0
|
||||
.../sound/mediatek}/mtk-afe-platform-driver.h | 0
|
||||
sound/soc/mediatek/common/mtk-afe-fe-dai.c | 4 ++--
|
||||
sound/soc/mediatek/common/mtk-afe-platform-driver.c | 2 +-
|
||||
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt6797/mt6797-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c | 2 +-
|
||||
sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c | 2 +-
|
||||
sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt8186/mt8186-misc-control.c | 4 ++--
|
||||
sound/soc/mediatek/mt8186/mt8186-mt6366-common.c | 2 +-
|
||||
sound/soc/mediatek/mt8186/mt8186-mt6366.c | 2 +-
|
||||
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt8188/mt8188-mt6359.c | 2 +-
|
||||
sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 2 +-
|
||||
sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 4 ++--
|
||||
sound/soc/mediatek/mt8195/mt8195-mt6359.c | 2 +-
|
||||
sound/soc/mediatek/mt8365/mt8365-afe-pcm.c | 4 ++--
|
||||
22 files changed, 32 insertions(+), 32 deletions(-)
|
||||
rename {sound/soc/mediatek/common => include/sound/mediatek}/mtk-afe-fe-dai.h (100%)
|
||||
rename {sound/soc/mediatek/common => include/sound/mediatek}/mtk-afe-platform-driver.h (100%)
|
||||
|
||||
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
|
||||
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
|
||||
@@ -11,9 +11,9 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
-#include "mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
#include <sound/pcm_params.h>
|
||||
-#include "mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
#include "mtk-base-afe.h"
|
||||
|
||||
#define AFE_BASE_END_OFFSET 8
|
||||
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c
|
||||
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
-#include "mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
#include "mtk-base-afe.h"
|
||||
|
||||
int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe)
|
||||
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
#include "mt2701-afe-common.h"
|
||||
#include "mt2701-afe-clock-ctrl.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
static const struct snd_pcm_hardware mt2701_afe_hardware = {
|
||||
.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
|
||||
--- a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
|
||||
@@ -16,8 +16,8 @@
|
||||
#include "mt6797-afe-clk.h"
|
||||
#include "mt6797-interconnection.h"
|
||||
#include "mt6797-reg.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
enum {
|
||||
MTK_AFE_RATE_8K = 0,
|
||||
--- a/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
#include "mt7986-afe-common.h"
|
||||
#include "mt7986-reg.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
enum {
|
||||
MTK_AFE_RATE_8K = 0,
|
||||
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
|
||||
@@ -19,8 +19,8 @@
|
||||
#include <sound/soc.h>
|
||||
#include "mt8173-afe-common.h"
|
||||
#include "../common/mtk-base-afe.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* R E G I S T E R D E F I N I T I O N
|
||||
--- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
|
||||
@@ -18,8 +18,8 @@
|
||||
#include "mt8183-afe-clk.h"
|
||||
#include "mt8183-interconnection.h"
|
||||
#include "mt8183-reg.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
enum {
|
||||
MTK_AFE_RATE_8K = 0,
|
||||
--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
|
||||
+++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../../codecs/da7219.h"
|
||||
#include "../../codecs/rt1015.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
#include "mt8183-afe-common.h"
|
||||
|
||||
#define DA7219_CODEC_DAI "da7219-hifi"
|
||||
--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
|
||||
+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "../../codecs/rt1015.h"
|
||||
#include "../../codecs/ts3a227e.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
#include "mt8183-afe-common.h"
|
||||
|
||||
#define RT1015_CODEC_DAI "rt1015-aif"
|
||||
--- a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
|
||||
@@ -15,8 +15,8 @@
|
||||
#include <linux/reset.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
#include "mt8186-afe-common.h"
|
||||
#include "mt8186-afe-clk.h"
|
||||
--- a/sound/soc/mediatek/mt8186/mt8186-misc-control.c
|
||||
+++ b/sound/soc/mediatek/mt8186/mt8186-misc-control.c
|
||||
@@ -11,8 +11,8 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
#include "mt8186-afe-common.h"
|
||||
|
||||
static const char * const mt8186_sgen_mode_str[] = {
|
||||
--- a/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c
|
||||
+++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-common.c
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "../../codecs/mt6358.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
#include "mt8186-afe-common.h"
|
||||
#include "mt8186-mt6366-common.h"
|
||||
|
||||
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "mt8188-afe-common.h"
|
||||
#include "mt8188-afe-clk.h"
|
||||
#include "mt8188-reg.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
#define MT8188_MEMIF_BUFFER_BYTES_ALIGN (0x40)
|
||||
#define MT8188_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff)
|
||||
--- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
|
||||
@@ -17,8 +17,8 @@
|
||||
#include <linux/reset.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
|
||||
#include "mt8192-afe-common.h"
|
||||
#include "mt8192-afe-clk.h"
|
||||
--- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
|
||||
+++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
|
||||
@@ -20,8 +20,8 @@
|
||||
#include "mt8195-afe-common.h"
|
||||
#include "mt8195-afe-clk.h"
|
||||
#include "mt8195-reg.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
-#include "../common/mtk-afe-fe-dai.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
|
||||
#define MT8195_MEMIF_BUFFER_BYTES_ALIGN (0x40)
|
||||
#define MT8195_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff)
|
||||
--- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c
|
||||
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "../../codecs/mt6359.h"
|
||||
#include "../../codecs/rt1011.h"
|
||||
#include "../../codecs/rt5682.h"
|
||||
-#include "../common/mtk-afe-platform-driver.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
#include "../common/mtk-dsp-sof-common.h"
|
||||
#include "../common/mtk-soc-card.h"
|
||||
#include "mt8195-afe-clk.h"
|
||||
--- /dev/null
|
||||
+++ b/include/sound/mediatek/mtk-afe-fe-dai.h
|
||||
@@ -0,0 +1,53 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition
|
||||
+ *
|
||||
+ * Copyright (c) 2016 MediaTek Inc.
|
||||
+ * Author: Garlic Tseng <garlic.tseng@mediatek.com>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _MTK_AFE_FE_DAI_H_
|
||||
+#define _MTK_AFE_FE_DAI_H_
|
||||
+
|
||||
+struct snd_soc_dai_ops;
|
||||
+struct mtk_base_afe;
|
||||
+struct mtk_base_afe_memif;
|
||||
+
|
||||
+int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai);
|
||||
+void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai);
|
||||
+int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params,
|
||||
+ struct snd_soc_dai *dai);
|
||||
+int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai);
|
||||
+int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai);
|
||||
+int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
+ struct snd_soc_dai *dai);
|
||||
+
|
||||
+extern const struct snd_soc_dai_ops mtk_afe_fe_ops;
|
||||
+
|
||||
+int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe);
|
||||
+int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id);
|
||||
+int mtk_afe_suspend(struct snd_soc_component *component);
|
||||
+int mtk_afe_resume(struct snd_soc_component *component);
|
||||
+
|
||||
+int mtk_memif_set_enable(struct mtk_base_afe *afe, int id);
|
||||
+int mtk_memif_set_disable(struct mtk_base_afe *afe, int id);
|
||||
+int mtk_memif_set_addr(struct mtk_base_afe *afe, int id,
|
||||
+ unsigned char *dma_area,
|
||||
+ dma_addr_t dma_addr,
|
||||
+ size_t dma_bytes);
|
||||
+int mtk_memif_set_channel(struct mtk_base_afe *afe,
|
||||
+ int id, unsigned int channel);
|
||||
+int mtk_memif_set_rate(struct mtk_base_afe *afe,
|
||||
+ int id, unsigned int rate);
|
||||
+int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream,
|
||||
+ int id, unsigned int rate);
|
||||
+int mtk_memif_set_format(struct mtk_base_afe *afe,
|
||||
+ int id, snd_pcm_format_t format);
|
||||
+int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe,
|
||||
+ int id, int pbuf_size);
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/include/sound/mediatek/mtk-afe-platform-driver.h
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition
|
||||
+ *
|
||||
+ * Copyright (c) 2016 MediaTek Inc.
|
||||
+ * Author: Garlic Tseng <garlic.tseng@mediatek.com>
|
||||
+ */
|
||||
+
|
||||
+#ifndef _MTK_AFE_PLATFORM_DRIVER_H_
|
||||
+#define _MTK_AFE_PLATFORM_DRIVER_H_
|
||||
+
|
||||
+#define AFE_PCM_NAME "mtk-afe-pcm"
|
||||
+extern const struct snd_soc_component_driver mtk_afe_pcm_platform;
|
||||
+
|
||||
+struct mtk_base_afe;
|
||||
+struct snd_pcm;
|
||||
+struct snd_soc_component;
|
||||
+struct snd_soc_pcm_runtime;
|
||||
+
|
||||
+snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component,
|
||||
+ struct snd_pcm_substream *substream);
|
||||
+int mtk_afe_pcm_new(struct snd_soc_component *component,
|
||||
+ struct snd_soc_pcm_runtime *rtd);
|
||||
+
|
||||
+int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe);
|
||||
+int mtk_afe_add_sub_dai_control(struct snd_soc_component *component);
|
||||
+#endif
|
||||
+
|
||||
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.h
|
||||
+++ /dev/null
|
||||
@@ -1,53 +0,0 @@
|
||||
-/* SPDX-License-Identifier: GPL-2.0 */
|
||||
-/*
|
||||
- * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition
|
||||
- *
|
||||
- * Copyright (c) 2016 MediaTek Inc.
|
||||
- * Author: Garlic Tseng <garlic.tseng@mediatek.com>
|
||||
- */
|
||||
-
|
||||
-#ifndef _MTK_AFE_FE_DAI_H_
|
||||
-#define _MTK_AFE_FE_DAI_H_
|
||||
-
|
||||
-struct snd_soc_dai_ops;
|
||||
-struct mtk_base_afe;
|
||||
-struct mtk_base_afe_memif;
|
||||
-
|
||||
-int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
|
||||
- struct snd_soc_dai *dai);
|
||||
-void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
|
||||
- struct snd_soc_dai *dai);
|
||||
-int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
|
||||
- struct snd_pcm_hw_params *params,
|
||||
- struct snd_soc_dai *dai);
|
||||
-int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream,
|
||||
- struct snd_soc_dai *dai);
|
||||
-int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
|
||||
- struct snd_soc_dai *dai);
|
||||
-int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
- struct snd_soc_dai *dai);
|
||||
-
|
||||
-extern const struct snd_soc_dai_ops mtk_afe_fe_ops;
|
||||
-
|
||||
-int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe);
|
||||
-int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id);
|
||||
-int mtk_afe_suspend(struct snd_soc_component *component);
|
||||
-int mtk_afe_resume(struct snd_soc_component *component);
|
||||
-
|
||||
-int mtk_memif_set_enable(struct mtk_base_afe *afe, int id);
|
||||
-int mtk_memif_set_disable(struct mtk_base_afe *afe, int id);
|
||||
-int mtk_memif_set_addr(struct mtk_base_afe *afe, int id,
|
||||
- unsigned char *dma_area,
|
||||
- dma_addr_t dma_addr,
|
||||
- size_t dma_bytes);
|
||||
-int mtk_memif_set_channel(struct mtk_base_afe *afe,
|
||||
- int id, unsigned int channel);
|
||||
-int mtk_memif_set_rate(struct mtk_base_afe *afe,
|
||||
- int id, unsigned int rate);
|
||||
-int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream,
|
||||
- int id, unsigned int rate);
|
||||
-int mtk_memif_set_format(struct mtk_base_afe *afe,
|
||||
- int id, snd_pcm_format_t format);
|
||||
-int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe,
|
||||
- int id, int pbuf_size);
|
||||
-#endif
|
||||
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.h
|
||||
+++ /dev/null
|
||||
@@ -1,28 +0,0 @@
|
||||
-/* SPDX-License-Identifier: GPL-2.0 */
|
||||
-/*
|
||||
- * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition
|
||||
- *
|
||||
- * Copyright (c) 2016 MediaTek Inc.
|
||||
- * Author: Garlic Tseng <garlic.tseng@mediatek.com>
|
||||
- */
|
||||
-
|
||||
-#ifndef _MTK_AFE_PLATFORM_DRIVER_H_
|
||||
-#define _MTK_AFE_PLATFORM_DRIVER_H_
|
||||
-
|
||||
-#define AFE_PCM_NAME "mtk-afe-pcm"
|
||||
-extern const struct snd_soc_component_driver mtk_afe_pcm_platform;
|
||||
-
|
||||
-struct mtk_base_afe;
|
||||
-struct snd_pcm;
|
||||
-struct snd_soc_component;
|
||||
-struct snd_soc_pcm_runtime;
|
||||
-
|
||||
-snd_pcm_uframes_t mtk_afe_pcm_pointer(struct snd_soc_component *component,
|
||||
- struct snd_pcm_substream *substream);
|
||||
-int mtk_afe_pcm_new(struct snd_soc_component *component,
|
||||
- struct snd_soc_pcm_runtime *rtd);
|
||||
-
|
||||
-int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe);
|
||||
-int mtk_afe_add_sub_dai_control(struct snd_soc_component *component);
|
||||
-#endif
|
||||
-
|
||||
-729
@@ -1,729 +0,0 @@
|
||||
From 9989af6ed0dba86f57ac4aa1574f9ce9b1e640af Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Thu, 31 Jul 2025 15:32:32 +0200
|
||||
Subject: [PATCH 2/3] ASoC: airoha: Add AFE and I2S driver for Airoha AN7581
|
||||
|
||||
Add support for the Sound system present on Airoha AN7581 SoC. This is
|
||||
based on the mediatek AFE drivers.
|
||||
|
||||
Also add the I2S driver to create an actual sound card for the AFE.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
sound/soc/Kconfig | 1 +
|
||||
sound/soc/Makefile | 1 +
|
||||
sound/soc/airoha/Kconfig | 19 +
|
||||
sound/soc/airoha/Makefile | 2 +
|
||||
sound/soc/airoha/an7581/Makefile | 8 +
|
||||
sound/soc/airoha/an7581/an7581-afe-common.h | 35 ++
|
||||
sound/soc/airoha/an7581/an7581-afe-pcm.c | 455 ++++++++++++++++++++
|
||||
sound/soc/airoha/an7581/an7581-i2s.c | 110 +++++
|
||||
sound/soc/airoha/an7581/an7581-reg.h | 29 ++
|
||||
9 files changed, 660 insertions(+)
|
||||
create mode 100644 sound/soc/airoha/Kconfig
|
||||
create mode 100644 sound/soc/airoha/Makefile
|
||||
create mode 100644 sound/soc/airoha/an7581/Makefile
|
||||
create mode 100644 sound/soc/airoha/an7581/an7581-afe-common.h
|
||||
create mode 100644 sound/soc/airoha/an7581/an7581-afe-pcm.c
|
||||
create mode 100644 sound/soc/airoha/an7581/an7581-i2s.c
|
||||
create mode 100644 sound/soc/airoha/an7581/an7581-reg.h
|
||||
|
||||
--- a/sound/soc/Kconfig
|
||||
+++ b/sound/soc/Kconfig
|
||||
@@ -78,6 +78,7 @@ config SND_SOC_ACPI
|
||||
|
||||
# All the supported SoCs
|
||||
source "sound/soc/adi/Kconfig"
|
||||
+source "sound/soc/airoha/Kconfig"
|
||||
source "sound/soc/amd/Kconfig"
|
||||
source "sound/soc/apple/Kconfig"
|
||||
source "sound/soc/atmel/Kconfig"
|
||||
--- a/sound/soc/Makefile
|
||||
+++ b/sound/soc/Makefile
|
||||
@@ -36,6 +36,7 @@ obj-$(CONFIG_SND_SOC) += codecs/
|
||||
obj-$(CONFIG_SND_SOC) += generic/
|
||||
obj-$(CONFIG_SND_SOC) += apple/
|
||||
obj-$(CONFIG_SND_SOC) += adi/
|
||||
+obj-$(CONFIG_SND_SOC) += airoha/
|
||||
obj-$(CONFIG_SND_SOC) += amd/
|
||||
obj-$(CONFIG_SND_SOC) += atmel/
|
||||
obj-$(CONFIG_SND_SOC) += au1x/
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/airoha/Kconfig
|
||||
@@ -0,0 +1,19 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+config SND_SOC_AN7581
|
||||
+ tristate "ASoC support for Airoha AN7581 chip"
|
||||
+ depends on ARCH_AIROHA || COMPILE_TEST
|
||||
+ select SND_SOC_MEDIATEK
|
||||
+ help
|
||||
+ This adds ASoC driver for Airoha AN7581 boards
|
||||
+ that can be used with other codecs.
|
||||
+ Select Y if you have such device.
|
||||
+ If unsure select "N".
|
||||
+
|
||||
+config SND_SOC_AN7581_I2S
|
||||
+ tristate "I2S support for Airoha AN7581 chip"
|
||||
+ depends on SND_SOC_AN7581
|
||||
+ help
|
||||
+ This adds I2S driver for Airoha AN7581 boards
|
||||
+ that can be used with other codecs.
|
||||
+ Select Y if you have such device.
|
||||
+ If unsure select "N".
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/airoha/Makefile
|
||||
@@ -0,0 +1,2 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_SND_SOC_AN7581) += an7581/
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/airoha/an7581/Makefile
|
||||
@@ -0,0 +1,8 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+# platform driver
|
||||
+snd-soc-an7581-afe-y := \
|
||||
+ an7581-afe-pcm.o
|
||||
+
|
||||
+obj-$(CONFIG_SND_SOC_AN7581) += snd-soc-an7581-afe.o
|
||||
+obj-$(CONFIG_SND_SOC_AN7581_I2S) += an7581-i2s.o
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/airoha/an7581/an7581-afe-common.h
|
||||
@@ -0,0 +1,35 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * an7581-afe-common.h -- Airoha AN7581 audio driver definitions
|
||||
+ */
|
||||
+
|
||||
+#ifndef _AN7581_AFE_COMMON_H_
|
||||
+#define _AN7581_AFE_COMMON_H_
|
||||
+
|
||||
+#include <sound/soc.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include "../../mediatek/common/mtk-base-afe.h"
|
||||
+
|
||||
+enum {
|
||||
+ AN7581_MEMIF_DL1,
|
||||
+ AN7581_MEMIF_UL1,
|
||||
+ AN7581_MEMIF_NUM,
|
||||
+ AN7581_DAI_NUM = AN7581_MEMIF_NUM,
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ AN7581_IRQ_0,
|
||||
+ AN7581_IRQ_1,
|
||||
+ AN7581_IRQ_NUM,
|
||||
+};
|
||||
+
|
||||
+struct an7581_afe_private {
|
||||
+ /* dai */
|
||||
+ void *dai_priv[AN7581_DAI_NUM];
|
||||
+};
|
||||
+
|
||||
+unsigned int an7581_afe_rate_transform(struct device *dev,
|
||||
+ unsigned int rate);
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/airoha/an7581/an7581-afe-pcm.c
|
||||
@@ -0,0 +1,455 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Airoha ALSA SoC AFE platform driver for AN7581
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+
|
||||
+#include "an7581-afe-common.h"
|
||||
+#include "an7581-reg.h"
|
||||
+#include <sound/mediatek/mtk-afe-platform-driver.h>
|
||||
+#include <sound/mediatek/mtk-afe-fe-dai.h>
|
||||
+
|
||||
+enum {
|
||||
+ ARH_AFE_RATE_7K = 16,
|
||||
+ ARH_AFE_RATE_8K = 0,
|
||||
+ ARH_AFE_RATE_11K = 17,
|
||||
+ ARH_AFE_RATE_12K = 1,
|
||||
+ ARH_AFE_RATE_14K = 18,
|
||||
+ ARH_AFE_RATE_16K = 2,
|
||||
+ ARH_AFE_RATE_22K = 19,
|
||||
+ ARH_AFE_RATE_24K = 3,
|
||||
+ ARH_AFE_RATE_29K = 20,
|
||||
+ ARH_AFE_RATE_32K = 4,
|
||||
+ ARH_AFE_RATE_44K = 21,
|
||||
+ ARH_AFE_RATE_48K = 5,
|
||||
+ ARH_AFE_RATE_88K = 22,
|
||||
+ ARH_AFE_RATE_96K = 6,
|
||||
+ ARH_AFE_RATE_176K = 23,
|
||||
+ ARH_AFE_RATE_192K = 7,
|
||||
+ ARH_AFE_RATE_352K = 24,
|
||||
+ ARH_AFE_RATE_384K = 8,
|
||||
+};
|
||||
+
|
||||
+unsigned int an7581_afe_rate_transform(struct device *dev, unsigned int rate)
|
||||
+{
|
||||
+ switch (rate) {
|
||||
+ case 7350:
|
||||
+ return ARH_AFE_RATE_7K;
|
||||
+ case 8000:
|
||||
+ return ARH_AFE_RATE_8K;
|
||||
+ case 11025:
|
||||
+ return ARH_AFE_RATE_11K;
|
||||
+ case 12000:
|
||||
+ return ARH_AFE_RATE_12K;
|
||||
+ case 14700:
|
||||
+ return ARH_AFE_RATE_14K;
|
||||
+ case 16000:
|
||||
+ return ARH_AFE_RATE_16K;
|
||||
+ case 22050:
|
||||
+ return ARH_AFE_RATE_22K;
|
||||
+ case 24000:
|
||||
+ return ARH_AFE_RATE_24K;
|
||||
+ case 29400:
|
||||
+ return ARH_AFE_RATE_29K;
|
||||
+ case 32000:
|
||||
+ return ARH_AFE_RATE_32K;
|
||||
+ case 44100:
|
||||
+ return ARH_AFE_RATE_44K;
|
||||
+ case 48000:
|
||||
+ return ARH_AFE_RATE_48K;
|
||||
+ case 88200:
|
||||
+ return ARH_AFE_RATE_88K;
|
||||
+ case 96000:
|
||||
+ return ARH_AFE_RATE_96K;
|
||||
+ case 176400:
|
||||
+ return ARH_AFE_RATE_176K;
|
||||
+ case 192000:
|
||||
+ return ARH_AFE_RATE_192K;
|
||||
+ case 352800:
|
||||
+ return ARH_AFE_RATE_352K;
|
||||
+ case 384000:
|
||||
+ return ARH_AFE_RATE_384K;
|
||||
+ default:
|
||||
+ dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n",
|
||||
+ __func__, rate, ARH_AFE_RATE_48K);
|
||||
+ return ARH_AFE_RATE_48K;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const int an7581_memif_specified_irqs[AN7581_MEMIF_NUM] = {
|
||||
+ [AN7581_MEMIF_DL1] = AN7581_IRQ_0,
|
||||
+ [AN7581_MEMIF_UL1] = AN7581_IRQ_1,
|
||||
+};
|
||||
+
|
||||
+static const struct snd_pcm_hardware an7581_afe_hardware = {
|
||||
+ .info = SNDRV_PCM_INFO_MMAP |
|
||||
+ SNDRV_PCM_INFO_INTERLEAVED |
|
||||
+ SNDRV_PCM_INFO_MMAP_VALID,
|
||||
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S24_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S32_LE,
|
||||
+ .period_bytes_min = 512,
|
||||
+ .period_bytes_max = 128 * 1024,
|
||||
+ .periods_min = 2,
|
||||
+ .periods_max = 256,
|
||||
+ .buffer_bytes_max = 256 * 1024,
|
||||
+ .fifo_size = 0,
|
||||
+};
|
||||
+
|
||||
+static int an7581_memif_fs(struct snd_pcm_substream *substream,
|
||||
+ unsigned int rate)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
|
||||
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
|
||||
+
|
||||
+ return an7581_afe_rate_transform(afe->dev, rate);
|
||||
+}
|
||||
+
|
||||
+static int an7581_irq_fs(struct snd_pcm_substream *substream,
|
||||
+ unsigned int rate)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
|
||||
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
|
||||
+
|
||||
+ return an7581_afe_rate_transform(afe->dev, rate);
|
||||
+}
|
||||
+
|
||||
+#define ARH_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
|
||||
+ SNDRV_PCM_FMTBIT_S32_LE)
|
||||
+
|
||||
+static struct snd_soc_dai_driver an7581_memif_dai_driver[] = {
|
||||
+ /* FE DAIs: memory intefaces to CPU */
|
||||
+ {
|
||||
+ .name = "DL1",
|
||||
+ .id = AN7581_MEMIF_DL1,
|
||||
+ .playback = {
|
||||
+ .stream_name = "DL1",
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 8,
|
||||
+ .rates = SNDRV_PCM_RATE_8000_192000,
|
||||
+ .formats = ARH_PCM_FORMATS,
|
||||
+ },
|
||||
+ .ops = &mtk_afe_fe_ops,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "UL1",
|
||||
+ .id = AN7581_MEMIF_UL1,
|
||||
+ .capture = {
|
||||
+ .stream_name = "UL1",
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 2,
|
||||
+ .rates = SNDRV_PCM_RATE_8000_192000,
|
||||
+ .formats = ARH_PCM_FORMATS,
|
||||
+ },
|
||||
+ .ops = &mtk_afe_fe_ops,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct snd_soc_component_driver an7581_afe_pcm_dai_component = {
|
||||
+ .name = "an7581-afe-pcm-dai",
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_base_memif_data memif_data[AN7581_MEMIF_NUM] = {
|
||||
+ [AN7581_MEMIF_DL1] = {
|
||||
+ .name = "DL1",
|
||||
+ .id = AN7581_MEMIF_DL1,
|
||||
+ .reg_ofs_base = AFE_DL1_BASE,
|
||||
+ .reg_ofs_cur = AFE_DL1_CUR,
|
||||
+ .reg_ofs_end = AFE_DL1_END,
|
||||
+ .fs_reg = -1,
|
||||
+ .fs_shift = -1,
|
||||
+ .fs_maskbit = -1,
|
||||
+ .mono_reg = -1,
|
||||
+ .mono_shift = -1,
|
||||
+ .hd_reg = -1,
|
||||
+ .hd_shift = -1,
|
||||
+ .enable_reg = AFE_DAC_CON0,
|
||||
+ .enable_shift = 17,
|
||||
+ .msb_reg = -1,
|
||||
+ .msb_shift = -1,
|
||||
+ .agent_disable_reg = -1,
|
||||
+ .agent_disable_shift = -1,
|
||||
+ },
|
||||
+ [AN7581_MEMIF_UL1] = {
|
||||
+ .name = "UL1",
|
||||
+ .id = AN7581_MEMIF_UL1,
|
||||
+ .reg_ofs_base = AFE_UL1_BASE,
|
||||
+ .reg_ofs_cur = AFE_UL1_CUR,
|
||||
+ .reg_ofs_end = AFE_UL1_END,
|
||||
+ .fs_reg = -1,
|
||||
+ .fs_shift = -1,
|
||||
+ .fs_maskbit = -1,
|
||||
+ .mono_reg = -1,
|
||||
+ .mono_shift = -1,
|
||||
+ .hd_reg = -1,
|
||||
+ .hd_shift = -1,
|
||||
+ .enable_reg = AFE_DAC_CON0,
|
||||
+ .enable_shift = 1,
|
||||
+ .msb_reg = -1,
|
||||
+ .msb_shift = -1,
|
||||
+ .agent_disable_reg = -1,
|
||||
+ .agent_disable_shift = -1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_base_irq_data irq_data[AN7581_IRQ_NUM] = {
|
||||
+ [AN7581_IRQ_0] = {
|
||||
+ .id = AN7581_IRQ_0,
|
||||
+ .irq_cnt_reg = -1,
|
||||
+ .irq_cnt_shift = -1,
|
||||
+ .irq_cnt_maskbit = -1,
|
||||
+ .irq_en_reg = AFE_IRQ1_CON0,
|
||||
+ .irq_en_shift = 4,
|
||||
+ .irq_fs_reg = -1,
|
||||
+ .irq_fs_shift = -1,
|
||||
+ .irq_fs_maskbit = -1,
|
||||
+ .irq_clr_reg = AFE_IRQ1_CON0,
|
||||
+ .irq_clr_shift = 0,
|
||||
+ },
|
||||
+ [AN7581_IRQ_1] = {
|
||||
+ .id = AN7581_IRQ_1,
|
||||
+ .irq_cnt_reg = -1,
|
||||
+ .irq_cnt_shift = -1,
|
||||
+ .irq_cnt_maskbit = -1,
|
||||
+ .irq_en_reg = AFE_IRQ0_CON0,
|
||||
+ .irq_en_shift = 4,
|
||||
+ .irq_fs_reg = -1,
|
||||
+ .irq_fs_shift = -1,
|
||||
+ .irq_fs_maskbit = -1,
|
||||
+ .irq_clr_reg = AFE_IRQ0_CON0,
|
||||
+ .irq_clr_shift = 1,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config an7581_afe_regmap_config = {
|
||||
+ .reg_bits = 32,
|
||||
+ .reg_stride = 4,
|
||||
+ .val_bits = 32,
|
||||
+ .max_register = AFE_MAX_REGISTER,
|
||||
+ .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1),
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t an7581_afe_irq_handler(int irq_id, void *dev)
|
||||
+{
|
||||
+ struct mtk_base_afe *afe = dev;
|
||||
+ struct mtk_base_afe_irq *irq;
|
||||
+ u32 status;
|
||||
+ u32 reg;
|
||||
+ int i;
|
||||
+
|
||||
+ regmap_read(afe->regmap, AFE_IRQ_STS, &status);
|
||||
+
|
||||
+ if (status & AFE_IRQ_STS_RECORD)
|
||||
+ reg = AFE_IRQ0_CON0;
|
||||
+ else
|
||||
+ reg = AFE_IRQ1_CON0;
|
||||
+
|
||||
+ regmap_set_bits(afe->regmap, reg, BIT(2));
|
||||
+ regmap_clear_bits(afe->regmap, reg, BIT(2));
|
||||
+
|
||||
+ regmap_set_bits(afe->regmap, reg, BIT(3));
|
||||
+ regmap_clear_bits(afe->regmap, reg, BIT(3));
|
||||
+
|
||||
+ for (i = 0; i < AN7581_MEMIF_NUM; i++) {
|
||||
+ struct mtk_base_afe_memif *memif = &afe->memif[i];
|
||||
+
|
||||
+ if (!memif->substream)
|
||||
+ continue;
|
||||
+
|
||||
+ if (memif->irq_usage < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ irq = &afe->irqs[memif->irq_usage];
|
||||
+
|
||||
+ if (status & (1 << irq->irq_data->irq_clr_shift))
|
||||
+ snd_pcm_period_elapsed(memif->substream);
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int an7581_afe_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int an7581_afe_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int an7581_dai_memif_register(struct mtk_base_afe *afe)
|
||||
+{
|
||||
+ struct mtk_base_afe_dai *dai;
|
||||
+
|
||||
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
|
||||
+ if (!dai)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ list_add(&dai->list, &afe->sub_dais);
|
||||
+
|
||||
+ dai->dai_drivers = an7581_memif_dai_driver;
|
||||
+ dai->num_dai_drivers = ARRAY_SIZE(an7581_memif_dai_driver);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+typedef int (*dai_register_cb)(struct mtk_base_afe *);
|
||||
+static const dai_register_cb dai_register_cbs[] = {
|
||||
+ an7581_dai_memif_register,
|
||||
+};
|
||||
+
|
||||
+static int an7581_afe_pcm_dev_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_base_afe *afe;
|
||||
+ struct an7581_afe_private *afe_priv;
|
||||
+ struct device *dev;
|
||||
+ int i, irq_id, ret;
|
||||
+
|
||||
+ afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
|
||||
+ if (!afe)
|
||||
+ return -ENOMEM;
|
||||
+ platform_set_drvdata(pdev, afe);
|
||||
+
|
||||
+ afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!afe->platform_priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ afe_priv = afe->platform_priv;
|
||||
+ afe->dev = &pdev->dev;
|
||||
+ dev = afe->dev;
|
||||
+
|
||||
+ afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(afe->base_addr))
|
||||
+ return PTR_ERR(afe->base_addr);
|
||||
+
|
||||
+ ret = devm_pm_runtime_enable(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ pm_runtime_get_sync(&pdev->dev);
|
||||
+
|
||||
+ afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
|
||||
+ &an7581_afe_regmap_config);
|
||||
+
|
||||
+ pm_runtime_put_sync(&pdev->dev);
|
||||
+ if (IS_ERR(afe->regmap))
|
||||
+ return PTR_ERR(afe->regmap);
|
||||
+
|
||||
+ mutex_init(&afe->irq_alloc_lock);
|
||||
+
|
||||
+ /* irq initialize */
|
||||
+ afe->irqs_size = AN7581_IRQ_NUM;
|
||||
+ afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!afe->irqs)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < afe->irqs_size; i++)
|
||||
+ afe->irqs[i].irq_data = &irq_data[i];
|
||||
+
|
||||
+ /* request irq */
|
||||
+ irq_id = platform_get_irq(pdev, 0);
|
||||
+ if (irq_id < 0)
|
||||
+ return irq_id;
|
||||
+
|
||||
+ ret = devm_request_irq(dev, irq_id, an7581_afe_irq_handler,
|
||||
+ IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Failed to request irq for asys-isr\n");
|
||||
+
|
||||
+ /* init memif */
|
||||
+ afe->memif_size = AN7581_MEMIF_NUM;
|
||||
+ afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!afe->memif)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < afe->memif_size; i++) {
|
||||
+ int sel_irq = an7581_memif_specified_irqs[i];
|
||||
+
|
||||
+ afe->memif[i].data = &memif_data[i];
|
||||
+ afe->memif[i].irq_usage = sel_irq;
|
||||
+ afe->memif[i].const_irq = 1;
|
||||
+ afe->irqs[sel_irq].irq_occupyed = true;
|
||||
+ }
|
||||
+
|
||||
+ /* init sub_dais */
|
||||
+ INIT_LIST_HEAD(&afe->sub_dais);
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
|
||||
+ ret = dai_register_cbs[i](afe);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "DAI register failed, i: %d\n", i);
|
||||
+ }
|
||||
+
|
||||
+ /* init dai_driver and component_driver */
|
||||
+ ret = mtk_afe_combine_sub_dai(afe);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n");
|
||||
+
|
||||
+ afe->mtk_afe_hardware = &an7581_afe_hardware;
|
||||
+ afe->memif_fs = an7581_memif_fs;
|
||||
+ afe->irq_fs = an7581_irq_fs;
|
||||
+
|
||||
+ afe->runtime_resume = an7581_afe_runtime_resume;
|
||||
+ afe->runtime_suspend = an7581_afe_runtime_suspend;
|
||||
+
|
||||
+ /* register component */
|
||||
+ ret = devm_snd_soc_register_component(&pdev->dev,
|
||||
+ &mtk_afe_pcm_platform,
|
||||
+ NULL, 0);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Cannot register AFE component\n");
|
||||
+
|
||||
+ ret = devm_snd_soc_register_component(afe->dev,
|
||||
+ &an7581_afe_pcm_dai_component,
|
||||
+ afe->dai_drivers,
|
||||
+ afe->num_dai_drivers);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Cannot register PCM DAI component\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void an7581_afe_pcm_dev_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+ if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
+ an7581_afe_runtime_suspend(&pdev->dev);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id an7581_afe_pcm_dt_match[] = {
|
||||
+ { .compatible = "airoha,an7581-afe" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, an7581_afe_pcm_dt_match);
|
||||
+
|
||||
+static const struct dev_pm_ops an7581_afe_pm_ops = {
|
||||
+ RUNTIME_PM_OPS(an7581_afe_runtime_suspend,
|
||||
+ an7581_afe_runtime_resume, NULL)
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver an7581_afe_pcm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "an7581-audio",
|
||||
+ .of_match_table = an7581_afe_pcm_dt_match,
|
||||
+ .pm = pm_ptr(&an7581_afe_pm_ops),
|
||||
+ },
|
||||
+ .probe = an7581_afe_pcm_dev_probe,
|
||||
+ .remove_new = an7581_afe_pcm_dev_remove,
|
||||
+};
|
||||
+module_platform_driver(an7581_afe_pcm_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Airoha SoC AFE platform driver for ALSA AN7581");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/airoha/an7581/an7581-i2s.c
|
||||
@@ -0,0 +1,110 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Airoha ALSA SoC I2S platform driver for AN7581
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <sound/soc.h>
|
||||
+
|
||||
+#include "an7581-afe-common.h"
|
||||
+
|
||||
+SND_SOC_DAILINK_DEFS(playback,
|
||||
+ DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
|
||||
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
+
|
||||
+SND_SOC_DAILINK_DEFS(capture,
|
||||
+ DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
|
||||
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
+
|
||||
+static struct snd_soc_dai_link an7581_i2s_dai_links[] = {
|
||||
+ {
|
||||
+ .name = "an7581-i2s-playback",
|
||||
+ .stream_name = "an7581-i2s-playback",
|
||||
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||
+ SND_SOC_DPCM_TRIGGER_POST},
|
||||
+ .dynamic = 0,
|
||||
+ .playback_only = 1,
|
||||
+ SND_SOC_DAILINK_REG(playback),
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "an7581-i2s-capture",
|
||||
+ .stream_name = "an7581-i2s-capture",
|
||||
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||
+ SND_SOC_DPCM_TRIGGER_POST},
|
||||
+ .dynamic = 0,
|
||||
+ .capture_only = 1,
|
||||
+ SND_SOC_DAILINK_REG(capture),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct snd_soc_card an7581_i2s_card = {
|
||||
+ .name = "an7581-i2s",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .dai_link = an7581_i2s_dai_links,
|
||||
+ .num_links = ARRAY_SIZE(an7581_i2s_dai_links),
|
||||
+};
|
||||
+
|
||||
+static int an7581_i2s_machine_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct snd_soc_card *card = &an7581_i2s_card;
|
||||
+ struct device_node *platform_dai_node;
|
||||
+ struct snd_soc_dai_link *dai_link;
|
||||
+ struct device_node *platform;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ card->dev = &pdev->dev;
|
||||
+
|
||||
+ platform = of_get_child_by_name(pdev->dev.of_node, "platform");
|
||||
+
|
||||
+ if (platform) {
|
||||
+ platform_dai_node = of_parse_phandle(platform, "sound-dai", 0);
|
||||
+ of_node_put(platform);
|
||||
+
|
||||
+ if (!platform_dai_node) {
|
||||
+ dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ for_each_card_prelinks(card, i, dai_link) {
|
||||
+ if (dai_link->platforms->name)
|
||||
+ continue;
|
||||
+ dai_link->platforms->of_node = platform_dai_node;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__);
|
||||
+ goto err_of_node_put;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_of_node_put:
|
||||
+ of_node_put(platform_dai_node);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id an7581_i2s_machine_dt_match[] = {
|
||||
+ { .compatible = "airoha,an7581-i2s" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, an7581_i2s_machine_dt_match);
|
||||
+
|
||||
+static struct platform_driver an7581_i2s_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "an7581-i2s",
|
||||
+ .of_match_table = an7581_i2s_machine_dt_match,
|
||||
+ },
|
||||
+ .probe = an7581_i2s_machine_probe,
|
||||
+};
|
||||
+module_platform_driver(an7581_i2s_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Airoha SoC I2S platform driver for ALSA AN7581");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/airoha/an7581/an7581-reg.h
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * an7581-reg.h -- Airoha AN7581 audio driver reg definition
|
||||
+ */
|
||||
+
|
||||
+#ifndef _AN7581_REG_H_
|
||||
+#define _AN7581_REG_H_
|
||||
+
|
||||
+#define AFE_DAC_CON0 0x0
|
||||
+
|
||||
+#define AFE_DL1_BASE 0xa8
|
||||
+#define AFE_DL1_END 0xac
|
||||
+#define AFE_DL1_CUR 0xb0
|
||||
+
|
||||
+#define AFE_UL1_BASE 0xc4
|
||||
+#define AFE_UL1_END 0xc8
|
||||
+#define AFE_UL1_CUR 0xcc
|
||||
+
|
||||
+#define AFE_IRQ0_CON0 0xe4
|
||||
+
|
||||
+#define AFE_IRQ_STS 0xf8
|
||||
+#define AFE_IRQ_STS_PLAY BIT(1)
|
||||
+#define AFE_IRQ_STS_RECORD BIT(0)
|
||||
+
|
||||
+#define AFE_IRQ1_CON0 0x100
|
||||
+
|
||||
+#define AFE_MAX_REGISTER AFE_IRQ1_CON0
|
||||
+
|
||||
+#endif
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
From 3847173525e307ebcd23bd4863da943ea78b0057 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 20 Jan 2026 11:17:18 +0100
|
||||
Subject: [PATCH] net: airoha: npu: Add the capability to read firmware names
|
||||
from dts
|
||||
|
||||
Introduce the capability to read the firmware binary names from device-tree
|
||||
using the firmware-name property if available.
|
||||
This patch is needed because NPU firmware binaries are board specific since
|
||||
they depend on the MediaTek WiFi chip used on the board (e.g. MT7996 or
|
||||
MT7992) and the WiFi chip version info is not available in the NPU driver.
|
||||
This is a preliminary patch to enable MT76 NPU offloading if the Airoha SoC
|
||||
is equipped with MT7996 (Eagle) WiFi chipset.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Link: https://patch.msgid.link/20260120-airoha-npu-firmware-name-v4-2-88999628b4c1@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_npu.c | 46 ++++++++++++++++++++----
|
||||
1 file changed, 40 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_npu.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_npu.c
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin"
|
||||
#define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin"
|
||||
+#define NPU_EN7581_7996_FIRMWARE_DATA "airoha/en7581_MT7996_npu_data.bin"
|
||||
+#define NPU_EN7581_7996_FIRMWARE_RV32 "airoha/en7581_MT7996_npu_rv32.bin"
|
||||
#define NPU_AN7583_FIRMWARE_DATA "airoha/an7583_npu_data.bin"
|
||||
#define NPU_AN7583_FIRMWARE_RV32 "airoha/an7583_npu_rv32.bin"
|
||||
#define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000
|
||||
@@ -195,18 +197,18 @@ static int airoha_npu_send_msg(struct ai
|
||||
}
|
||||
|
||||
static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr,
|
||||
- const struct airoha_npu_fw *fw_info)
|
||||
+ const char *fw_name, int fw_max_size)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
int ret;
|
||||
|
||||
- ret = request_firmware(&fw, fw_info->name, dev);
|
||||
+ ret = request_firmware(&fw, fw_name, dev);
|
||||
if (ret)
|
||||
return ret == -ENOENT ? -EPROBE_DEFER : ret;
|
||||
|
||||
- if (fw->size > fw_info->max_size) {
|
||||
+ if (fw->size > fw_max_size) {
|
||||
dev_err(dev, "%s: fw size too overlimit (%zu)\n",
|
||||
- fw_info->name, fw->size);
|
||||
+ fw_name, fw->size);
|
||||
ret = -E2BIG;
|
||||
goto out;
|
||||
}
|
||||
@@ -218,6 +220,28 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int
|
||||
+airoha_npu_load_firmware_from_dts(struct device *dev, void __iomem *addr,
|
||||
+ void __iomem *base)
|
||||
+{
|
||||
+ const char *fw_names[2];
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = of_property_read_string_array(dev->of_node, "firmware-name",
|
||||
+ fw_names, ARRAY_SIZE(fw_names));
|
||||
+ if (ret != ARRAY_SIZE(fw_names))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = airoha_npu_load_firmware(dev, addr, fw_names[0],
|
||||
+ NPU_EN7581_FIRMWARE_RV32_MAX_SIZE);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM,
|
||||
+ fw_names[1],
|
||||
+ NPU_EN7581_FIRMWARE_DATA_MAX_SIZE);
|
||||
+}
|
||||
+
|
||||
static int airoha_npu_run_firmware(struct device *dev, void __iomem *base,
|
||||
struct reserved_mem *rmem)
|
||||
{
|
||||
@@ -233,14 +257,22 @@ static int airoha_npu_run_firmware(struc
|
||||
if (IS_ERR(addr))
|
||||
return PTR_ERR(addr);
|
||||
|
||||
+ /* Try to load firmware images using the firmware names provided via
|
||||
+ * dts if available.
|
||||
+ */
|
||||
+ if (of_find_property(dev->of_node, "firmware-name", NULL))
|
||||
+ return airoha_npu_load_firmware_from_dts(dev, addr, base);
|
||||
+
|
||||
/* Load rv32 npu firmware */
|
||||
- ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32);
|
||||
+ ret = airoha_npu_load_firmware(dev, addr, soc->fw_rv32.name,
|
||||
+ soc->fw_rv32.max_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Load data npu firmware */
|
||||
return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM,
|
||||
- &soc->fw_data);
|
||||
+ soc->fw_data.name,
|
||||
+ soc->fw_data.max_size);
|
||||
}
|
||||
|
||||
static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance)
|
||||
@@ -797,6 +829,8 @@ module_platform_driver(airoha_npu_driver
|
||||
|
||||
MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA);
|
||||
MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32);
|
||||
+MODULE_FIRMWARE(NPU_EN7581_7996_FIRMWARE_DATA);
|
||||
+MODULE_FIRMWARE(NPU_EN7581_7996_FIRMWARE_RV32);
|
||||
MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_DATA);
|
||||
MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_RV32);
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -0,0 +1,53 @@
|
||||
From aebf15e8eb09b01e99f043e9f5d423798aac9d32 Mon Sep 17 00:00:00 2001
|
||||
From: Zhengping Zhang <aquapinn@qq.com>
|
||||
Date: Thu, 26 Feb 2026 10:37:08 +0800
|
||||
Subject: [PATCH] net: airoha: fix typo in function name
|
||||
|
||||
Corrected the typo in the function name from
|
||||
`airhoa_is_lan_gdm_port` to `airoha_is_lan_gdm_port`. This change ensures
|
||||
consistency in the API naming convention.
|
||||
|
||||
Signed-off-by: Zhengping Zhang <aquapinn@qq.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/tencent_E4FD5D6BC0131E617D848896F5F9FCED6E0A@qq.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -76,7 +76,7 @@ static void airoha_set_macaddr(struct ai
|
||||
struct airoha_eth *eth = port->qdma->eth;
|
||||
u32 val, reg;
|
||||
|
||||
- reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
|
||||
+ reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
|
||||
: REG_FE_WAN_MAC_H;
|
||||
val = (addr[0] << 16) | (addr[1] << 8) | addr[2];
|
||||
airoha_fe_wr(eth, reg, val);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -626,7 +626,7 @@ u32 airoha_rmw(void __iomem *base, u32 o
|
||||
#define airoha_qdma_clear(qdma, offset, val) \
|
||||
airoha_rmw((qdma)->regs, (offset), (val), 0)
|
||||
|
||||
-static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
|
||||
+static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port)
|
||||
{
|
||||
/* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
|
||||
* GDM{2,3,4} can be used as wan port connected to an external
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -321,7 +321,7 @@ static int airoha_ppe_foe_entry_prepare(
|
||||
/* For downlink traffic consume SRAM memory for hw
|
||||
* forwarding descriptors queue.
|
||||
*/
|
||||
- if (airhoa_is_lan_gdm_port(port))
|
||||
+ if (airoha_is_lan_gdm_port(port))
|
||||
val |= AIROHA_FOE_IB2_FAST_PATH;
|
||||
if (dsa_port >= 0)
|
||||
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ,
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
From 7600fb3b41dd6ab65ed61169df1b6099044edf97 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 4 Mar 2026 11:56:47 +0100
|
||||
Subject: [PATCH] net: airoha: Rely __field_prep for non-constant masks
|
||||
|
||||
Rely on __field_prep macros for non-constant masks preparing the values
|
||||
for register updates instead of open-coding.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260304-airoha-__field_prep-v1-1-b185facc4e2f@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1728,7 +1728,7 @@ static int airhoha_set_gdm2_loopback(str
|
||||
airoha_fe_rmw(eth,
|
||||
REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
|
||||
SP_CPORT_MASK(val),
|
||||
- FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val)));
|
||||
+ __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
|
||||
|
||||
if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth))
|
||||
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
|
||||
@@ -1782,7 +1782,7 @@ static int airoha_dev_init(struct net_de
|
||||
ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0;
|
||||
airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id),
|
||||
DFT_CPORT_MASK(port->id),
|
||||
- fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id)));
|
||||
+ __field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2139,7 +2139,7 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
|
||||
airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3),
|
||||
CHAN_QOS_MODE_MASK(channel),
|
||||
- mode << __ffs(CHAN_QOS_MODE_MASK(channel)));
|
||||
+ __field_prep(CHAN_QOS_MODE_MASK(channel), mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
From bf3471e6e6c02137dc0d26caa783ac1849f9aab8 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 6 Mar 2026 09:07:27 +0100
|
||||
Subject: [PATCH] net: airoha: Make flow control source port mapping dependent
|
||||
on nbq parameter
|
||||
|
||||
Flow control source port mapping for USB serdes needs to be configured
|
||||
according to the GDM port nbq parameter. This is a preliminary patch
|
||||
since nbq parameter is specific for the given port serdes and needs to
|
||||
be read from the DTS (in the current codebase is assigned statically).
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260306-airoha-fix-loopback-for-usb-serdes-v2-1-319de9c96826@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 10 ++++++----
|
||||
drivers/net/ethernet/airoha/airoha_regs.h | 5 +----
|
||||
2 files changed, 7 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1730,10 +1730,12 @@ static int airhoha_set_gdm2_loopback(str
|
||||
SP_CPORT_MASK(val),
|
||||
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
|
||||
|
||||
- if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth))
|
||||
- airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
|
||||
- FC_ID_OF_SRC_PORT24_MASK,
|
||||
- FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
|
||||
+ if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
|
||||
+ u32 mask = FC_ID_OF_SRC_PORT_MASK(nbq);
|
||||
+
|
||||
+ airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
|
||||
+ __field_prep(mask, AIROHA_GDM2_IDX));
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
@@ -376,10 +376,7 @@
|
||||
#define SP_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2))
|
||||
|
||||
#define REG_SRC_PORT_FC_MAP6 0x2298
|
||||
-#define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24)
|
||||
-#define FC_ID_OF_SRC_PORT26_MASK GENMASK(20, 16)
|
||||
-#define FC_ID_OF_SRC_PORT25_MASK GENMASK(12, 8)
|
||||
-#define FC_ID_OF_SRC_PORT24_MASK GENMASK(4, 0)
|
||||
+#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3))
|
||||
|
||||
#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
From 46097d011f77f5758fb47b7059b4f1f2e7403940 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 6 Mar 2026 16:09:47 +0100
|
||||
Subject: [PATCH] net: airoha: Move GDM forward port configuration in
|
||||
ndo_open/ndo_stop callbacks
|
||||
|
||||
This change allows to set GDM forward port configuration to
|
||||
FE_PSE_PORT_DROP stopping the network device. Hw design requires to stop
|
||||
packet forwarding putting the interface down. Moreover, PPE firmware
|
||||
requires to use PPE1 for GDM3 or GDM4.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260306-airoha-gdm-forward-ndo-open-stop-v1-1-7b7a20dd9ef0@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 20 +++++++++++++++-----
|
||||
1 file changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1612,6 +1612,7 @@ static int airoha_dev_open(struct net_de
|
||||
int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
+ u32 pse_port = FE_PSE_PORT_PPE1;
|
||||
|
||||
netif_tx_start_all_queues(dev);
|
||||
err = airoha_set_vip_for_gdm_port(port, true);
|
||||
@@ -1635,6 +1636,14 @@ static int airoha_dev_open(struct net_de
|
||||
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||
atomic_inc(&qdma->users);
|
||||
|
||||
+ if (port->id == AIROHA_GDM2_IDX &&
|
||||
+ airoha_ppe_is_enabled(qdma->eth, 1)) {
|
||||
+ /* For PPE2 always use secondary cpu port. */
|
||||
+ pse_port = FE_PSE_PORT_PPE2;
|
||||
+ }
|
||||
+ airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
||||
+ pse_port);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1652,6 +1661,9 @@ static int airoha_dev_stop(struct net_de
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++)
|
||||
netdev_tx_reset_subqueue(dev, i);
|
||||
|
||||
+ airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
||||
+ FE_PSE_PORT_DROP);
|
||||
+
|
||||
if (atomic_dec_and_test(&qdma->users)) {
|
||||
airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||
@@ -1745,7 +1757,7 @@ static int airoha_dev_init(struct net_de
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
- u32 pse_port, fe_cpu_port;
|
||||
+ u32 fe_cpu_port;
|
||||
u8 ppe_id;
|
||||
|
||||
airoha_set_macaddr(port, dev->dev_addr);
|
||||
@@ -1766,7 +1778,7 @@ static int airoha_dev_init(struct net_de
|
||||
if (airoha_ppe_is_enabled(eth, 1)) {
|
||||
/* For PPE2 always use secondary cpu port. */
|
||||
fe_cpu_port = FE_PSE_PORT_CDM2;
|
||||
- pse_port = FE_PSE_PORT_PPE2;
|
||||
+ ppe_id = 1;
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
@@ -1775,13 +1787,11 @@ static int airoha_dev_init(struct net_de
|
||||
|
||||
/* For PPE1 select cpu port according to the running QDMA. */
|
||||
fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
|
||||
- pse_port = FE_PSE_PORT_PPE1;
|
||||
+ ppe_id = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port);
|
||||
- ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0;
|
||||
airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id),
|
||||
DFT_CPORT_MASK(port->id),
|
||||
__field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port));
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
From d4a533ad249e9fbdc2d0633f2ddd60a5b3a9a4ca Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 13 Mar 2026 12:27:00 +0100
|
||||
Subject: [PATCH] net: airoha: Remove airoha_dev_stop() in airoha_remove()
|
||||
|
||||
Do not run airoha_dev_stop routine explicitly in airoha_remove()
|
||||
since ndo_stop() callback is already executed by unregister_netdev() in
|
||||
__dev_close_many routine if necessary and, doing so, we will end up causing
|
||||
an underflow in the qdma users atomic counters. Rely on networking subsystem
|
||||
to stop the device removing the airoha_eth module.
|
||||
|
||||
Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://patch.msgid.link/20260313-airoha-remove-ndo_stop-remove-net-v2-1-67542c3ceeca@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -3096,7 +3096,6 @@ static void airoha_remove(struct platfor
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- airoha_dev_stop(port->dev);
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
From 8737d7194d6d5947c3d7d8813895b44a25b84477 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 13 Mar 2026 17:28:36 +0100
|
||||
Subject: [PATCH] net: airoha: select QDMA block according LAN/WAN
|
||||
configuration
|
||||
|
||||
Before this patch even GDM ports were assigned to QDMA0 while odd GDM
|
||||
ports were using QDMA1, so, based on the DTS configuration, both QDMA0
|
||||
and QDMA1 can theoretically receive traffic destinated to the host cpu
|
||||
from LAN or WAN GDM ports.
|
||||
Airoha folks reported the hw design assumes the LAN traffic destinated
|
||||
to the host cpu is be forwarded to QDMA0 while traffic received on WAN
|
||||
GDM port is managed by QDMA1. For this reason, select QDMA block according
|
||||
to the GDM port LAN or WAN configuration:
|
||||
- QDMA0 is used for GDM LAN devices
|
||||
- QDMA1 is used for GDM WAN device
|
||||
|
||||
Assuming a device with three GDM ports, a typical configuration could be:
|
||||
- MT7530 DSA switch -> GDM1 (eth0) -> QDMA0 (LAN traffic)
|
||||
- External PHY -> GDM2 (eth1) -> QDMA1 (WAN traffic)
|
||||
- External PHY -> GDM3 (eth2) -> QDMA0 (LAN traffic)
|
||||
|
||||
We can then bridge eth0 DSA port (lanX) with eth2 since they all tx/rx
|
||||
LAN traffic.
|
||||
|
||||
Please note this patch introduces a change not visible to the user since
|
||||
airoha_eth driver currently supports just the internal phy available via
|
||||
the MT7530 DSA switch and there are no WAN interfaces officially supported
|
||||
since PCS/external phy is not merged mainline yet (it will be posted with
|
||||
following patches).
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260313-airoha-qdma-lan-wan-mode-v2-1-7d577db6e40c@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 18 ++++++++----------
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
|
||||
2 files changed, 9 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1755,11 +1755,13 @@ static int airhoha_set_gdm2_loopback(str
|
||||
static int airoha_dev_init(struct net_device *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
- struct airoha_eth *eth = qdma->eth;
|
||||
+ struct airoha_eth *eth = port->eth;
|
||||
u32 fe_cpu_port;
|
||||
u8 ppe_id;
|
||||
|
||||
+ /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
+ port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
|
||||
+ port->dev->irq = port->qdma->irq_banks[0].irq;
|
||||
airoha_set_macaddr(port, dev->dev_addr);
|
||||
|
||||
switch (port->id) {
|
||||
@@ -1783,7 +1785,7 @@ static int airoha_dev_init(struct net_de
|
||||
}
|
||||
fallthrough;
|
||||
default: {
|
||||
- u8 qdma_id = qdma - ð->qdma[0];
|
||||
+ u8 qdma_id = port->qdma - ð->qdma[0];
|
||||
|
||||
/* For PPE1 select cpu port according to the running QDMA. */
|
||||
fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
|
||||
@@ -2867,11 +2869,10 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
}
|
||||
|
||||
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
||||
- struct device_node *np, int index)
|
||||
+ struct device_node *np)
|
||||
{
|
||||
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
|
||||
struct airoha_gdm_port *port;
|
||||
- struct airoha_qdma *qdma;
|
||||
struct net_device *dev;
|
||||
int err, p;
|
||||
u32 id;
|
||||
@@ -2902,7 +2903,6 @@ static int airoha_alloc_gdm_port(struct
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA];
|
||||
dev->netdev_ops = &airoha_netdev_ops;
|
||||
dev->ethtool_ops = &airoha_ethtool_ops;
|
||||
dev->max_mtu = AIROHA_MAX_MTU;
|
||||
@@ -2914,7 +2914,6 @@ static int airoha_alloc_gdm_port(struct
|
||||
dev->features |= dev->hw_features;
|
||||
dev->vlan_features = dev->hw_features;
|
||||
dev->dev.of_node = np;
|
||||
- dev->irq = qdma->irq_banks[0].irq;
|
||||
SET_NETDEV_DEV(dev, eth->dev);
|
||||
|
||||
/* reserve hw queues for HTB offloading */
|
||||
@@ -2935,7 +2934,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
port = netdev_priv(dev);
|
||||
u64_stats_init(&port->stats.syncp);
|
||||
spin_lock_init(&port->stats.lock);
|
||||
- port->qdma = qdma;
|
||||
+ port->eth = eth;
|
||||
port->dev = dev;
|
||||
port->id = id;
|
||||
eth->ports[p] = port;
|
||||
@@ -3035,7 +3034,6 @@ static int airoha_probe(struct platform_
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_start_napi(ð->qdma[i]);
|
||||
|
||||
- i = 0;
|
||||
for_each_child_of_node(pdev->dev.of_node, np) {
|
||||
if (!of_device_is_compatible(np, "airoha,eth-mac"))
|
||||
continue;
|
||||
@@ -3043,7 +3041,7 @@ static int airoha_probe(struct platform_
|
||||
if (!of_device_is_available(np))
|
||||
continue;
|
||||
|
||||
- err = airoha_alloc_gdm_port(eth, np, i++);
|
||||
+ err = airoha_alloc_gdm_port(eth, np);
|
||||
if (err) {
|
||||
of_node_put(np);
|
||||
goto error_napi_stop;
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -533,6 +533,7 @@ struct airoha_qdma {
|
||||
|
||||
struct airoha_gdm_port {
|
||||
struct airoha_qdma *qdma;
|
||||
+ struct airoha_eth *eth;
|
||||
struct net_device *dev;
|
||||
int id;
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
From dfdf774656205515b2d6ad94fce63c7ccbe92d91 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 9 Jan 2026 10:29:06 +0100
|
||||
Subject: [PATCH] net: airoha: Fix typo in airoha_ppe_setup_tc_block_cb
|
||||
definition
|
||||
|
||||
Fix Typo in airoha_ppe_dev_setup_tc_block_cb routine definition when
|
||||
CONFIG_NET_AIROHA is not enabled.
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202601090517.Fj6v501r-lkp@intel.com/
|
||||
Fixes: f45fc18b6de04 ("net: airoha: Add airoha_ppe_dev struct definition")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260109-airoha_ppe_dev_setup_tc_block_cb-typo-v1-1-282e8834a9f9@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/linux/soc/airoha/airoha_offload.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/include/linux/soc/airoha/airoha_offload.h
|
||||
+++ b/include/linux/soc/airoha/airoha_offload.h
|
||||
@@ -51,8 +51,8 @@ static inline void airoha_ppe_put_dev(st
|
||||
{
|
||||
}
|
||||
|
||||
-static inline int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev,
|
||||
- void *type_data)
|
||||
+static inline int airoha_ppe_dev_setup_tc_block_cb(struct airoha_ppe_dev *dev,
|
||||
+ void *type_data)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
+1295
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -19,16 +19,16 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
|
||||
FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
|
||||
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK);
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(3),
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX),
|
||||
+ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(4),
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX),
|
||||
+ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
|
||||
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
@@ -1625,7 +1627,8 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1626,7 +1628,8 @@ static int airoha_dev_open(struct net_de
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -3089,7 +3089,6 @@ static void airoha_remove(struct platfor
|
||||
@@ -3114,7 +3114,6 @@ static void airoha_remove(struct platfor
|
||||
}
|
||||
|
||||
static const char * const en7581_xsi_rsts_names[] = {
|
||||
@@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
"hsi0-mac",
|
||||
"hsi1-mac",
|
||||
"hsi-mac",
|
||||
@@ -3121,7 +3120,6 @@ static int airoha_en7581_get_src_port_id
|
||||
@@ -3146,7 +3145,6 @@ static int airoha_en7581_get_src_port_id
|
||||
}
|
||||
|
||||
static const char * const an7583_xsi_rsts_names[] = {
|
||||
+24
-24
@@ -35,9 +35,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
|
||||
{
|
||||
struct airoha_eth *eth = port->qdma->eth;
|
||||
@@ -1622,6 +1628,17 @@ static int airoha_dev_open(struct net_de
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
@@ -1623,6 +1629,17 @@ static int airoha_dev_open(struct net_de
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
u32 pse_port = FE_PSE_PORT_PPE1;
|
||||
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
|
||||
@@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
netif_tx_start_all_queues(dev);
|
||||
err = airoha_set_vip_for_gdm_port(port, true);
|
||||
if (err)
|
||||
@@ -1675,6 +1692,11 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1687,6 +1704,11 @@ static int airoha_dev_stop(struct net_de
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2817,6 +2839,20 @@ static const struct ethtool_ops airoha_e
|
||||
@@ -2834,6 +2856,20 @@ static const struct ethtool_ops airoha_e
|
||||
.get_link = ethtool_op_get_link,
|
||||
};
|
||||
|
||||
@@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
|
||||
{
|
||||
int i;
|
||||
@@ -2861,6 +2897,99 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
@@ -2878,6 +2914,99 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -184,34 +184,34 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
+}
|
||||
+
|
||||
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
||||
struct device_node *np, int index)
|
||||
struct device_node *np)
|
||||
{
|
||||
@@ -2939,6 +3068,12 @@ static int airoha_alloc_gdm_port(struct
|
||||
if (err)
|
||||
return err;
|
||||
@@ -2949,6 +3078,12 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->id = id;
|
||||
eth->ports[p] = port;
|
||||
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ err = airoha_setup_phylink(dev);
|
||||
+ if (err)
|
||||
+ goto free_metadata_dst;
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
err = register_netdev(dev);
|
||||
if (err)
|
||||
goto free_metadata_dst;
|
||||
@@ -3054,6 +3189,10 @@ error_hw_cleanup:
|
||||
if (port && port->dev->reg_state == NETREG_REGISTERED) {
|
||||
return airoha_metadata_dst_alloc(port);
|
||||
}
|
||||
|
||||
@@ -3080,6 +3215,10 @@ error_hw_cleanup:
|
||||
|
||||
if (port->dev->reg_state == NETREG_REGISTERED)
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ phylink_destroy(port->phylink);
|
||||
+ airoha_pcs_destroy(port->pcs);
|
||||
+ }
|
||||
}
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ phylink_destroy(port->phylink);
|
||||
+ airoha_pcs_destroy(port->pcs);
|
||||
+ }
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
@@ -3081,6 +3220,10 @@ static void airoha_remove(struct platfor
|
||||
airoha_dev_stop(port->dev);
|
||||
@@ -3106,6 +3245,10 @@ static void airoha_remove(struct platfor
|
||||
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
@@ -223,7 +223,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -536,6 +536,10 @@ struct airoha_gdm_port {
|
||||
@@ -537,6 +537,10 @@ struct airoha_gdm_port {
|
||||
struct net_device *dev;
|
||||
int id;
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
From 843e2892f2d9353bf039e0dfb5442a600e75009e Mon Sep 17 00:00:00 2001
|
||||
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
Date: Thu, 9 Oct 2025 23:46:08 +0300
|
||||
Subject: [PATCH] net: airoha: disable external phy code if PCS_AIROHA is not
|
||||
enabled
|
||||
|
||||
External phy code breaks building for EN7523, so disable it if
|
||||
PCS_AIROHA is not selected.
|
||||
|
||||
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++++++++++
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 2 ++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -72,10 +72,12 @@ static void airoha_qdma_irq_disable(stru
|
||||
airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
static bool airhoa_is_phy_external(struct airoha_gdm_port *port)
|
||||
{
|
||||
return port->id != 1;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
|
||||
{
|
||||
@@ -1632,6 +1634,7 @@ static int airoha_dev_open(struct net_de
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
u32 pse_port = FE_PSE_PORT_PPE1;
|
||||
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
|
||||
if (err) {
|
||||
@@ -1642,6 +1645,7 @@ static int airoha_dev_open(struct net_de
|
||||
|
||||
phylink_start(port->phylink);
|
||||
}
|
||||
+#endif
|
||||
|
||||
netif_tx_start_all_queues(dev);
|
||||
err = airoha_set_vip_for_gdm_port(port, true);
|
||||
@@ -1707,10 +1711,12 @@ static int airoha_dev_stop(struct net_de
|
||||
}
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
phylink_stop(port->phylink);
|
||||
phylink_disconnect_phy(port->phylink);
|
||||
}
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2859,6 +2865,7 @@ static const struct ethtool_ops airoha_e
|
||||
.get_link = ethtool_op_get_link,
|
||||
};
|
||||
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -2872,6 +2879,7 @@ static void airoha_mac_config(struct phy
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
}
|
||||
+#endif
|
||||
|
||||
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
|
||||
{
|
||||
@@ -2917,6 +2925,7 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
return false;
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
|
||||
unsigned int mode, phy_interface_t interface,
|
||||
int speed, int duplex, bool tx_pause, bool rx_pause)
|
||||
@@ -3009,6 +3018,7 @@ static int airoha_setup_phylink(struct n
|
||||
|
||||
return 0;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
||||
struct device_node *np)
|
||||
@@ -3081,11 +3091,13 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->id = id;
|
||||
eth->ports[p] = port;
|
||||
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
err = airoha_setup_phylink(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
+#endif
|
||||
|
||||
return airoha_metadata_dst_alloc(port);
|
||||
}
|
||||
@@ -3218,10 +3230,12 @@ error_hw_cleanup:
|
||||
|
||||
if (port->dev->reg_state == NETREG_REGISTERED)
|
||||
unregister_netdev(port->dev);
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
phylink_destroy(port->phylink);
|
||||
airoha_pcs_destroy(port->pcs);
|
||||
}
|
||||
+#endif
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
@@ -3248,10 +3262,12 @@ static void airoha_remove(struct platfor
|
||||
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
phylink_destroy(port->phylink);
|
||||
airoha_pcs_destroy(port->pcs);
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -537,9 +537,11 @@ struct airoha_gdm_port {
|
||||
struct net_device *dev;
|
||||
int id;
|
||||
|
||||
+#if defined(CONFIG_PCS_AIROHA)
|
||||
struct phylink *phylink;
|
||||
struct phylink_config phylink_config;
|
||||
struct phylink_pcs *pcs;
|
||||
+#endif
|
||||
|
||||
struct airoha_hw_stats stats;
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From: Ryan Chen <rchen14b@gmail.com>
|
||||
Subject: clk: en7581: Separate PERST from refclk in PCIe clock callbacks
|
||||
|
||||
The EN7581 PCIe clock enable/disable callbacks currently toggle both
|
||||
PERST (reset) and reference clock signals together. This prevents the
|
||||
PCIe controller driver from properly sequencing PERST relative to MAC
|
||||
register configuration, which is required for x2 link mode.
|
||||
|
||||
Separate the two concerns: clock callbacks only manage reference clocks
|
||||
(REFCLK_EN0/EN1), while PERST (PERSTOUT/PERSTOUT1/PERSTOUT2) is left
|
||||
to the PCIe controller driver to manage directly via the NP_SCU regmap.
|
||||
|
||||
Signed-off-by: Ryan Chen <rchen14b@gmail.com>
|
||||
--- a/drivers/clk/clk-en7523.c
|
||||
+++ b/drivers/clk/clk-en7523.c
|
||||
@@ -909,9 +909,11 @@ static int en7581_pci_enable(struct clk_
|
||||
struct regmap *map = cg->map;
|
||||
u32 mask;
|
||||
|
||||
- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
|
||||
- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
|
||||
- REG_PCI_CONTROL_PERSTOUT;
|
||||
+ /* Only enable reference clocks - PERST is managed separately by the
|
||||
+ * PCIe controller driver to allow proper sequencing of MAC register
|
||||
+ * configuration between PERST assert and deassert.
|
||||
+ */
|
||||
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
|
||||
regmap_set_bits(map, REG_PCI_CONTROL, mask);
|
||||
|
||||
return 0;
|
||||
@@ -923,9 +925,8 @@ static void en7581_pci_disable(struct cl
|
||||
struct regmap *map = cg->map;
|
||||
u32 mask;
|
||||
|
||||
- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
|
||||
- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
|
||||
- REG_PCI_CONTROL_PERSTOUT;
|
||||
+ /* Only disable reference clocks - PCIe driver manages PERST */
|
||||
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
|
||||
regmap_clear_bits(map, REG_PCI_CONTROL, mask);
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
From: Ryan Chen <rchen14b@gmail.com>
|
||||
Subject: PCI: mediatek-gen3: Add PCIe x2 link support for Airoha EN7581
|
||||
|
||||
The Airoha EN7581 SoC supports PCIe x2 mode where two PCIe lanes are
|
||||
bonded together for a single x2 link. This requires coordination with
|
||||
the NP_SCU system controller for serdes mux routing, PERST management,
|
||||
and lane configuration.
|
||||
|
||||
The x2 initialization sequence:
|
||||
1. Assert serdes reset and PERST before enabling clocks
|
||||
2. Configure serdes mux for 2-lane mode
|
||||
3. Enable reference clocks, deassert serdes reset
|
||||
4. Clear x1 mode bit and write EQ presets on both MACs
|
||||
5. Deassert PERST to start link training
|
||||
|
||||
After initial link training, if the link negotiates Gen2 instead of
|
||||
Gen3, a serdes reset toggle forces the MAC to re-discover the PHY
|
||||
Gen3 capability from the Link Capabilities 2 register, allowing the
|
||||
link to retrain at Gen3 x2 (8 GT/s).
|
||||
|
||||
Signed-off-by: Ryan Chen <rchen14b@gmail.com>
|
||||
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
|
||||
@@ -61,6 +61,14 @@
|
||||
#define PCIE_LTSSM_STATE(val) ((val & PCIE_LTSSM_STATE_MASK) >> 24)
|
||||
#define PCIE_LTSSM_STATE_L2_IDLE 0x14
|
||||
|
||||
+/* EN7581 x2 mode support */
|
||||
+#define PCIE_SETTING_REG_X1_MODE BIT(13)
|
||||
+
|
||||
+/* EN7581 NP_SCU register offsets for x2 link init */
|
||||
+#define NP_SCU_LANE_CFG0 0x830
|
||||
+#define NP_SCU_LANE_CFG1 0x834
|
||||
+#define NP_SCU_CTRL_REG 0x88
|
||||
+
|
||||
#define PCIE_LINK_STATUS_REG 0x154
|
||||
#define PCIE_PORT_LINKUP BIT(8)
|
||||
|
||||
@@ -205,6 +213,11 @@ struct mtk_gen3_pcie {
|
||||
DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM);
|
||||
|
||||
const struct mtk_gen3_pcie_pdata *soc;
|
||||
+
|
||||
+ /* EN7581 x2 mode support */
|
||||
+ struct regmap *np_scu;
|
||||
+ bool x2_mode;
|
||||
+ void __iomem *sister_base;
|
||||
};
|
||||
|
||||
/* LTSSM state in PCIE_LTSSM_STATUS_REG bit[28:24] */
|
||||
@@ -932,6 +945,28 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
size = lower_32_bits(resource_size(entry->res));
|
||||
regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size)));
|
||||
|
||||
+ /* Lookup NP_SCU regmap for x2 mode support */
|
||||
+ pcie->np_scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,np-scu");
|
||||
+ if (IS_ERR(pcie->np_scu)) {
|
||||
+ dev_dbg(dev, "np_scu not available, x2 mode disabled\n");
|
||||
+ pcie->np_scu = NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Check for x2 mode property */
|
||||
+ pcie->x2_mode = of_property_read_bool(dev->of_node, "airoha,x2-mode");
|
||||
+ if (pcie->x2_mode)
|
||||
+ dev_info(dev, "x2 mode enabled\n");
|
||||
+
|
||||
+ /* Map sister MAC for x2 mode (MAC1 at +0x20000) */
|
||||
+ if (pcie->x2_mode) {
|
||||
+ pcie->sister_base = devm_ioremap(dev,
|
||||
+ pcie->reg_base + 0x20000, 0x20000);
|
||||
+ if (!pcie->sister_base)
|
||||
+ dev_warn(dev, "failed to map sister MAC for x2\n");
|
||||
+ else
|
||||
+ dev_info(dev, "x2 mode: sister MAC mapped\n");
|
||||
+ }
|
||||
+
|
||||
err = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to set PHY mode\n");
|
||||
@@ -969,17 +1004,28 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
- val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
|
||||
- FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
|
||||
- FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
|
||||
- FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
|
||||
- writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG);
|
||||
-
|
||||
- val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
|
||||
- FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
|
||||
- FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
|
||||
- FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
|
||||
- writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
|
||||
+ /*
|
||||
+ * EN7581 x2: Assert PERST and serdes reset before enabling clocks
|
||||
+ * so that MAC registers can be configured while devices are held
|
||||
+ * in reset, ensuring link trains with the correct x2 settings.
|
||||
+ */
|
||||
+ if (pcie->x2_mode && pcie->np_scu) {
|
||||
+ /* Assert serdes reset on all lanes */
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1,
|
||||
+ BIT(26) | BIT(27), BIT(26) | BIT(27));
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0,
|
||||
+ BIT(27), BIT(27));
|
||||
+ msleep(100);
|
||||
+
|
||||
+ /* Assert PERST on all ports */
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG,
|
||||
+ BIT(16) | BIT(26) | BIT(29), 0);
|
||||
+
|
||||
+ /* Set serdes mux for 2-lane mode (bits[1:0] = 2) */
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG,
|
||||
+ BIT(0) | BIT(1), BIT(1));
|
||||
+ mdelay(1);
|
||||
+ }
|
||||
|
||||
err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
|
||||
if (err) {
|
||||
@@ -988,12 +1034,121 @@ static int mtk_pcie_en7581_power_up(stru
|
||||
}
|
||||
|
||||
/*
|
||||
- * Airoha EN7581 performs PCIe reset via clk callbacks since it has a
|
||||
- * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to
|
||||
- * complete the PCIe reset.
|
||||
+ * Airoha EN7581: clock enable only provides refclk (patch 911).
|
||||
+ * For x2, PERST + serdes are already asserted above.
|
||||
+ * Wait for refclk to stabilize.
|
||||
*/
|
||||
msleep(PCIE_T_PVPERL_MS);
|
||||
|
||||
+ if (pcie->x2_mode && pcie->np_scu) {
|
||||
+ /*
|
||||
+ * EN7581 x2: PERST asserted, serdes reset asserted,
|
||||
+ * refclk now stable. Complete the init sequence.
|
||||
+ */
|
||||
+ msleep(30);
|
||||
+
|
||||
+ /* Deassert serdes reset on all lanes */
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1,
|
||||
+ BIT(26) | BIT(27), 0);
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0,
|
||||
+ BIT(27), 0);
|
||||
+
|
||||
+ /* Clear SETTING_REG bit 13 for x2 mode on both MACs */
|
||||
+ val = readl_relaxed(pcie->base + PCIE_SETTING_REG);
|
||||
+ writel_relaxed(val & ~PCIE_SETTING_REG_X1_MODE,
|
||||
+ pcie->base + PCIE_SETTING_REG);
|
||||
+ if (pcie->sister_base) {
|
||||
+ val = readl_relaxed(pcie->sister_base + 0x80);
|
||||
+ writel_relaxed(val & ~PCIE_SETTING_REG_X1_MODE,
|
||||
+ pcie->sister_base + 0x80);
|
||||
+ }
|
||||
+
|
||||
+ /* EQ presets on both MACs */
|
||||
+ writel_relaxed(0x41474147, pcie->base + PCIE_EQ_PRESET_01_REG);
|
||||
+ if (pcie->sister_base)
|
||||
+ writel_relaxed(0x41474147, pcie->sister_base + 0x100);
|
||||
+ writel_relaxed(0x1018020f, pcie->base + PCIE_PIPE4_PIE8_REG);
|
||||
+ if (pcie->sister_base)
|
||||
+ writel_relaxed(0x1018020f, pcie->sister_base + 0x338);
|
||||
+
|
||||
+ /* Deassert PERST for all ports - link training starts */
|
||||
+ msleep(10);
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG,
|
||||
+ BIT(16) | BIT(26) | BIT(29),
|
||||
+ BIT(16) | BIT(26) | BIT(29));
|
||||
+
|
||||
+ /* Wait for link training to complete */
|
||||
+ msleep(800);
|
||||
+
|
||||
+ /*
|
||||
+ * Check if link trained at Gen3. If not, toggle serdes
|
||||
+ * reset to force MAC to re-discover PHY Gen3 capability.
|
||||
+ * Without this, MAC only advertises Gen1-Gen2 in LnkCap2.
|
||||
+ */
|
||||
+ val = readl_relaxed(pcie->base + PCIE_LINK_STATUS_REG);
|
||||
+ if (val & PCIE_PORT_LINKUP) {
|
||||
+ void __iomem *cfg = pcie->base + PCIE_CFG_OFFSET_ADDR;
|
||||
+ u8 cap_ptr;
|
||||
+ int speed = 0;
|
||||
+
|
||||
+ /* Walk PCI cap list to find PCIe cap (ID=0x10) */
|
||||
+ cap_ptr = readl_relaxed(cfg + PCI_CAPABILITY_LIST) & 0xFF;
|
||||
+ while (cap_ptr >= 0x40) {
|
||||
+ u32 hdr = readl_relaxed(cfg + cap_ptr);
|
||||
+ if ((hdr & 0xFF) == PCI_CAP_ID_EXP) {
|
||||
+ u32 lnk = readl_relaxed(cfg + cap_ptr + PCI_EXP_LNKCTL);
|
||||
+ speed = (lnk >> 16) & PCI_EXP_LNKSTA_CLS;
|
||||
+ break;
|
||||
+ }
|
||||
+ cap_ptr = (hdr >> 8) & 0xFF;
|
||||
+ }
|
||||
+
|
||||
+ if (speed > 0 && speed < 3) {
|
||||
+ dev_info(dev, "x2: link at Gen%d, toggling serdes for Gen3\n", speed);
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0,
|
||||
+ BIT(7) | BIT(8), BIT(7) | BIT(8));
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1,
|
||||
+ BIT(26) | BIT(27), BIT(26) | BIT(27));
|
||||
+ msleep(1000);
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0,
|
||||
+ BIT(7) | BIT(8), 0);
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1,
|
||||
+ BIT(26) | BIT(27), 0);
|
||||
+ msleep(2000);
|
||||
+ dev_info(dev, "x2: serdes toggle done, link retraining\n");
|
||||
+ } else {
|
||||
+ dev_info(dev, "x2: link at Gen%d, no toggle needed\n", speed);
|
||||
+ }
|
||||
+ } else {
|
||||
+ dev_info(dev, "x2: link not up after init, skipping speed check\n");
|
||||
+ }
|
||||
+
|
||||
+ dev_info(dev, "x2: init complete, PERST deasserted\n");
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Non-x2 mode: standard EQ config then deassert PERST.
|
||||
+ */
|
||||
+ val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
|
||||
+ FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
|
||||
+ FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
|
||||
+ FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
|
||||
+ writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG);
|
||||
+
|
||||
+ val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
|
||||
+ FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
|
||||
+ FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
|
||||
+ FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
|
||||
+ writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
|
||||
+
|
||||
+ /* Deassert PERST for all ports */
|
||||
+ if (pcie->np_scu) {
|
||||
+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG,
|
||||
+ BIT(16) | BIT(26) | BIT(29),
|
||||
+ BIT(16) | BIT(26) | BIT(29));
|
||||
+ msleep(100);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_clk_prepare_enable:
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
From 2a6c045640c38a407a39cd40c3c4d8dd2fd89aa8 Mon Sep 17 00:00:00 2001
|
||||
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Date: Thu, 6 Nov 2025 14:34:00 +0100
|
||||
Subject: [PATCH 1/2] bitfield: Add less-checking __FIELD_{GET,PREP}()
|
||||
|
||||
The BUILD_BUG_ON_MSG() check against "~0ull" works only with "unsigned
|
||||
(long) long" _mask types. For constant masks, that condition is usually
|
||||
met, as GENMASK() yields an UL value. The few places where the
|
||||
constant mask is stored in an intermediate variable were fixed by
|
||||
changing the variable type to u64 (see e.g. [1] and [2]).
|
||||
|
||||
However, for non-constant masks, smaller unsigned types should be valid,
|
||||
too, but currently lead to "result of comparison of constant
|
||||
18446744073709551615 with expression of type ... is always
|
||||
false"-warnings with clang and W=1.
|
||||
|
||||
Hence refactor the __BF_FIELD_CHECK() helper, and factor out
|
||||
__FIELD_{GET,PREP}(). The later lack the single problematic check, but
|
||||
are otherwise identical to FIELD_{GET,PREP}(), and are intended to be
|
||||
used in the fully non-const variants later.
|
||||
|
||||
[1] commit 5c667d5a5a3ec166 ("clk: sp7021: Adjust width of _m in
|
||||
HWM_FIELD_PREP()")
|
||||
[2] commit cfd6fb45cfaf46fa ("crypto: ccree - avoid out-of-range
|
||||
warnings from clang")
|
||||
|
||||
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Link: https://git.kernel.org/torvalds/c/5c667d5a5a3ec166 [1]
|
||||
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
|
||||
---
|
||||
include/linux/bitfield.h | 36 ++++++++++++++++++++++++++++--------
|
||||
1 file changed, 28 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/include/linux/bitfield.h
|
||||
+++ b/include/linux/bitfield.h
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
#define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x))
|
||||
|
||||
-#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
|
||||
+#define __BF_FIELD_CHECK_MASK(_mask, _val, _pfx) \
|
||||
({ \
|
||||
BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
|
||||
_pfx "mask is not constant"); \
|
||||
@@ -68,13 +68,33 @@
|
||||
BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \
|
||||
~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
|
||||
_pfx "value too large for the field"); \
|
||||
- BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
|
||||
- __bf_cast_unsigned(_reg, ~0ull), \
|
||||
- _pfx "type of reg too small for mask"); \
|
||||
__BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
|
||||
(1ULL << __bf_shf(_mask))); \
|
||||
})
|
||||
|
||||
+#define __BF_FIELD_CHECK_REG(mask, reg, pfx) \
|
||||
+ BUILD_BUG_ON_MSG(__bf_cast_unsigned(mask, mask) > \
|
||||
+ __bf_cast_unsigned(reg, ~0ull), \
|
||||
+ pfx "type of reg too small for mask")
|
||||
+
|
||||
+#define __BF_FIELD_CHECK(mask, reg, val, pfx) \
|
||||
+ ({ \
|
||||
+ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
|
||||
+ __BF_FIELD_CHECK_REG(mask, reg, pfx); \
|
||||
+ })
|
||||
+
|
||||
+#define __FIELD_PREP(mask, val, pfx) \
|
||||
+ ({ \
|
||||
+ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
|
||||
+ ((typeof(mask))(val) << __bf_shf(mask)) & (mask); \
|
||||
+ })
|
||||
+
|
||||
+#define __FIELD_GET(mask, reg, pfx) \
|
||||
+ ({ \
|
||||
+ __BF_FIELD_CHECK_MASK(mask, 0U, pfx); \
|
||||
+ (typeof(mask))(((reg) & (mask)) >> __bf_shf(mask)); \
|
||||
+ })
|
||||
+
|
||||
/**
|
||||
* FIELD_MAX() - produce the maximum value representable by a field
|
||||
* @_mask: shifted mask defining the field's length and position
|
||||
@@ -111,8 +131,8 @@
|
||||
*/
|
||||
#define FIELD_PREP(_mask, _val) \
|
||||
({ \
|
||||
- __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
|
||||
- ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
|
||||
+ __BF_FIELD_CHECK_REG(_mask, 0ULL, "FIELD_PREP: "); \
|
||||
+ __FIELD_PREP(_mask, _val, "FIELD_PREP: "); \
|
||||
})
|
||||
|
||||
#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
|
||||
@@ -151,8 +171,8 @@
|
||||
*/
|
||||
#define FIELD_GET(_mask, _reg) \
|
||||
({ \
|
||||
- __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
|
||||
- (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
|
||||
+ __BF_FIELD_CHECK_REG(_mask, _reg, "FIELD_GET: "); \
|
||||
+ __FIELD_GET(_mask, _reg, "FIELD_GET: "); \
|
||||
})
|
||||
|
||||
extern void __compiletime_error("value doesn't fit into mask")
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
From c1c6ab80b25c8db1e2ef5ae3ac8075d2c242ae13 Mon Sep 17 00:00:00 2001
|
||||
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Date: Thu, 6 Nov 2025 14:34:01 +0100
|
||||
Subject: [PATCH 2/2] bitfield: Add non-constant field_{prep,get}() helpers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The existing FIELD_{GET,PREP}() macros are limited to compile-time
|
||||
constants. However, it is very common to prepare or extract bitfield
|
||||
elements where the bitfield mask is not a compile-time constant.
|
||||
|
||||
To avoid this limitation, the AT91 clock driver and several other
|
||||
drivers already have their own non-const field_{prep,get}() macros.
|
||||
Make them available for general use by adding them to
|
||||
<linux/bitfield.h>, and improve them slightly:
|
||||
1. Avoid evaluating macro parameters more than once,
|
||||
2. Replace "ffs() - 1" by "__ffs()",
|
||||
3. Support 64-bit use on 32-bit architectures,
|
||||
4. Wire field_{get,prep}() to FIELD_{GET,PREP}() when mask is
|
||||
actually constant.
|
||||
|
||||
This is deliberately not merged into the existing FIELD_{GET,PREP}()
|
||||
macros, as people expressed the desire to keep stricter variants for
|
||||
increased safety, or for performance critical paths.
|
||||
|
||||
Yury: use __mask withing new macros.
|
||||
|
||||
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Acked-by: Crt Mori <cmo@melexis.com>
|
||||
Acked-by: Nuno Sá <nuno.sa@analog.com>
|
||||
Acked-by: Richard Genoud <richard.genoud@bootlin.com>
|
||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
|
||||
Reviewed-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
|
||||
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
|
||||
---
|
||||
include/linux/bitfield.h | 59 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 59 insertions(+)
|
||||
|
||||
--- a/include/linux/bitfield.h
|
||||
+++ b/include/linux/bitfield.h
|
||||
@@ -16,6 +16,7 @@
|
||||
* FIELD_{GET,PREP} macros take as first parameter shifted mask
|
||||
* from which they extract the base mask and shift amount.
|
||||
* Mask must be a compilation time constant.
|
||||
+ * field_{get,prep} are variants that take a non-const mask.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
@@ -222,4 +223,62 @@ __MAKE_OP(64)
|
||||
#undef __MAKE_OP
|
||||
#undef ____MAKE_OP
|
||||
|
||||
+#define __field_prep(mask, val) \
|
||||
+ ({ \
|
||||
+ __auto_type __mask = (mask); \
|
||||
+ typeof(__mask) __val = (val); \
|
||||
+ unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \
|
||||
+ __ffs(__mask) : __ffs64(__mask); \
|
||||
+ (__val << __shift) & __mask; \
|
||||
+ })
|
||||
+
|
||||
+#define __field_get(mask, reg) \
|
||||
+ ({ \
|
||||
+ __auto_type __mask = (mask); \
|
||||
+ typeof(__mask) __reg = (reg); \
|
||||
+ unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \
|
||||
+ __ffs(__mask) : __ffs64(__mask); \
|
||||
+ (__reg & __mask) >> __shift; \
|
||||
+ })
|
||||
+
|
||||
+/**
|
||||
+ * field_prep() - prepare a bitfield element
|
||||
+ * @mask: shifted mask defining the field's length and position, must be
|
||||
+ * non-zero
|
||||
+ * @val: value to put in the field
|
||||
+ *
|
||||
+ * Return: field value masked and shifted to its final destination
|
||||
+ *
|
||||
+ * field_prep() masks and shifts up the value. The result should be
|
||||
+ * combined with other fields of the bitfield using logical OR.
|
||||
+ * Unlike FIELD_PREP(), @mask is not limited to a compile-time constant.
|
||||
+ * Typical usage patterns are a value stored in a table, or calculated by
|
||||
+ * shifting a constant by a variable number of bits.
|
||||
+ * If you want to ensure that @mask is a compile-time constant, please use
|
||||
+ * FIELD_PREP() directly instead.
|
||||
+ */
|
||||
+#define field_prep(mask, val) \
|
||||
+ (__builtin_constant_p(mask) ? __FIELD_PREP(mask, val, "field_prep: ") \
|
||||
+ : __field_prep(mask, val))
|
||||
+
|
||||
+/**
|
||||
+ * field_get() - extract a bitfield element
|
||||
+ * @mask: shifted mask defining the field's length and position, must be
|
||||
+ * non-zero
|
||||
+ * @reg: value of entire bitfield
|
||||
+ *
|
||||
+ * Return: extracted field value
|
||||
+ *
|
||||
+ * field_get() extracts the field specified by @mask from the
|
||||
+ * bitfield passed in as @reg by masking and shifting it down.
|
||||
+ * Unlike FIELD_GET(), @mask is not limited to a compile-time constant.
|
||||
+ * Typical usage patterns are a value stored in a table, or calculated by
|
||||
+ * shifting a constant by a variable number of bits.
|
||||
+ * If you want to ensure that @mask is a compile-time constant, please use
|
||||
+ * FIELD_GET() directly instead.
|
||||
+ */
|
||||
+#define field_get(mask, reg) \
|
||||
+ (__builtin_constant_p(mask) ? __FIELD_GET(mask, reg, "field_get: ") \
|
||||
+ : __field_get(mask, reg))
|
||||
+
|
||||
#endif
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
From 0f8407a1f1c795c417e4c7750654a6024a3ec68b Mon Sep 17 00:00:00 2001
|
||||
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Date: Thu, 6 Nov 2025 14:34:02 +0100
|
||||
Subject: [PATCH] clk: at91: Convert to common field_{get,prep}() helpers
|
||||
|
||||
Drop the driver-specific field_get() and field_prep() macros, in favor
|
||||
of the globally available variants from <linux/bitfield.h>.
|
||||
|
||||
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Acked-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
|
||||
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
|
||||
---
|
||||
drivers/clk/at91/clk-peripheral.c | 1 +
|
||||
drivers/clk/at91/pmc.h | 5 -----
|
||||
2 files changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/clk/at91/clk-peripheral.c
|
||||
+++ b/drivers/clk/at91/clk-peripheral.c
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
|
||||
*/
|
||||
|
||||
+#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
--- a/drivers/clk/at91/pmc.h
|
||||
+++ b/drivers/clk/at91/pmc.h
|
||||
@@ -114,9 +114,6 @@ struct at91_clk_pms {
|
||||
unsigned int parent;
|
||||
};
|
||||
|
||||
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
|
||||
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
|
||||
-
|
||||
#define ndck(a, s) (a[s - 1].id + 1)
|
||||
#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
|
||||
struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From 1fe1c28a108e4953f083c0106575ee0eccc296ae Mon Sep 17 00:00:00 2001
|
||||
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Date: Thu, 6 Nov 2025 14:34:07 +0100
|
||||
Subject: [PATCH] iio: mlx90614: Convert to common field_{get,prep}() helpers
|
||||
|
||||
Drop the driver-specific field_get() and field_prep() macros, in favor
|
||||
of the globally available variants from <linux/bitfield.h>.
|
||||
|
||||
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Acked-by: Crt Mori <cmo@melexis.com>
|
||||
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
|
||||
---
|
||||
drivers/iio/temperature/mlx90614.c | 7 +------
|
||||
1 file changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/iio/temperature/mlx90614.c
|
||||
+++ b/drivers/iio/temperature/mlx90614.c
|
||||
@@ -22,6 +22,7 @@
|
||||
* the "wakeup" GPIO is not given, power management will be disabled.
|
||||
*/
|
||||
|
||||
+#include <linux/bitfield.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
@@ -68,10 +69,6 @@
|
||||
#define MLX90614_CONST_SCALE 20 /* Scale in milliKelvin (0.02 * 1000) */
|
||||
#define MLX90614_CONST_FIR 0x7 /* Fixed value for FIR part of low pass filter */
|
||||
|
||||
-/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
|
||||
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
|
||||
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
|
||||
-
|
||||
struct mlx_chip_info {
|
||||
/* EEPROM offsets with 16-bit data, MSB first */
|
||||
/* emissivity correction coefficient */
|
||||
Reference in New Issue
Block a user