Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2023-02-06 03:37:49 +08:00
commit 4580230440
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
169 changed files with 6885 additions and 1365 deletions

View File

@ -5,7 +5,6 @@
config EXPERIMENTAL
bool "Enable experimental features by default"
default n
help
Set this option to build with latest bleeding edge features
which may or may not work as expected.
@ -42,7 +41,6 @@ menu "Global build settings"
config BUILDBOT
bool "Set build defaults for automatic builds (e.g. via buildbot)"
default n
help
This option changes several defaults to be more suitable for
automatic builds. This includes the following changes:
@ -75,10 +73,8 @@ menu "Global build settings"
config DISPLAY_SUPPORT
bool "Show packages that require graphics support (local or remote)"
default n
config BUILD_PATENTED
default n
bool "Compile with support for patented functionality"
help
When this option is disabled, software which provides patented functionality
@ -86,7 +82,6 @@ menu "Global build settings"
functionality, this optional support will get disabled for this package.
config BUILD_NLS
default n
bool "Compile with full language support"
help
When this option is enabled, packages are built with the full versions of
@ -100,7 +95,6 @@ menu "Global build settings"
config CLEAN_IPKG
bool
prompt "Remove ipkg/opkg status data files in final images"
default n
help
This removes all ipkg/opkg status data files from the target directory
before building the root filesystem.
@ -108,14 +102,12 @@ menu "Global build settings"
config IPK_FILES_CHECKSUMS
bool
prompt "Record files checksums in package metadata"
default n
help
This makes file checksums part of package metadata. It increases size
but provides you with pkg_check command to check for flash corruptions.
config INCLUDE_CONFIG
bool "Include build configuration in firmware" if DEVEL
default n
help
If enabled, buildinfo files will be stored in /etc/build.* of firmware.
@ -149,7 +141,6 @@ menu "Global build settings"
config DEBUG
bool
prompt "Compile packages with debugging info"
default n
help
Adds -g3 to the CFLAGS.

View File

@ -4,11 +4,9 @@
menuconfig DEVEL
bool "Advanced configuration options (for developers)"
default n
config BROKEN
bool "Show broken platforms / packages / devices" if DEVEL
default n
config BINARY_FOLDER
string "Binary folder" if DEVEL
@ -53,7 +51,6 @@ menuconfig DEVEL
config AUTOREMOVE
bool "Automatic removal of build directories" if DEVEL
default n
help
Automatically delete build directories after make target completed.
This allows you to symlink build_dir into a scratch location, e.g. a ramdisk,
@ -61,7 +58,6 @@ menuconfig DEVEL
config BUILD_ALL_HOST_TOOLS
bool "Compile all host tools" if DEVEL
default n
help
Compile all host host tools even if not needed. This is needed to prepare a
universal precompiled host tools archive to use in another buildroot.
@ -84,7 +80,6 @@ menuconfig DEVEL
config CCACHE
bool "Use ccache" if DEVEL
default n
help
Compiler cache; see https://ccache.samba.org/

View File

@ -59,7 +59,6 @@ menu "Target Images"
config TARGET_INITRAMFS_FORCE
bool "Force"
depends on TARGET_ROOTFS_INITRAMFS
default n
help
Ignore the initramfs passed by the bootloader.
@ -128,7 +127,6 @@ menu "Target Images"
config TARGET_EXT4_JOURNAL
bool "Create a journaling filesystem"
depends on TARGET_ROOTFS_EXT4FS
default n
help
Create an ext4 filesystem with a journal.
@ -233,7 +231,6 @@ menu "Target Images"
config GRUB_FLOWCONTROL
bool "Use RTE/CTS on serial console"
depends on GRUB_SERIAL != ""
default n
config GRUB_BOOTOPTS
string "Extra kernel boot options"
@ -324,7 +321,6 @@ menu "Target Images"
config TARGET_ROOTFS_PERSIST_VAR
bool "Make /var persistent"
default n
help
Do not symlink /var to /tmp, so that its content will persist
across reboots. When enabled, /var/run will still be linked

View File

@ -47,12 +47,10 @@ config KERNEL_MIPS_FP_SUPPORT
config KERNEL_ARM_PMU
bool
default n
depends on (arm || aarch64)
config KERNEL_X86_VSYSCALL_EMULATION
bool "Enable vsyscall emulation"
default n
depends on x86_64
help
This enables emulation of the legacy vsyscall page. Disabling
@ -70,12 +68,10 @@ config KERNEL_X86_VSYSCALL_EMULATION
config KERNEL_PERF_EVENTS
bool "Compile the kernel with performance events and counters"
default n
select KERNEL_ARM_PMU if (arm || aarch64)
config KERNEL_PROFILING
bool "Compile the kernel with profiling enabled"
default n
select KERNEL_PERF_EVENTS
help
Enable the extended profiling support mechanisms used by profilers such
@ -255,7 +251,6 @@ config KERNEL_KCOV_INSTRUMENT_ALL
config KERNEL_TASKSTATS
bool "Compile the kernel with task resource/io statistics and accounting"
default n
help
Enable the collection and publishing of task/io statistics and
accounting. Enable this option to enable i/o monitoring in system
@ -283,37 +278,30 @@ config KERNEL_KALLSYMS
config KERNEL_FTRACE
bool "Compile the kernel with tracing support"
depends on !TARGET_uml
default n
config KERNEL_FTRACE_SYSCALLS
bool "Trace system calls"
depends on KERNEL_FTRACE
default n
config KERNEL_ENABLE_DEFAULT_TRACERS
bool "Trace process context switches and events"
depends on KERNEL_FTRACE
default n
config KERNEL_FUNCTION_TRACER
bool "Function tracer"
depends on KERNEL_FTRACE
default n
config KERNEL_FUNCTION_GRAPH_TRACER
bool "Function graph tracer"
depends on KERNEL_FUNCTION_TRACER
default n
config KERNEL_DYNAMIC_FTRACE
bool "Enable/disable function tracing dynamically"
depends on KERNEL_FUNCTION_TRACER
default n
config KERNEL_FUNCTION_PROFILER
bool "Function profiler"
depends on KERNEL_FUNCTION_TRACER
default n
config KERNEL_IRQSOFF_TRACER
bool "Interrupts-off Latency Tracer"
@ -364,7 +352,6 @@ config KERNEL_HIST_TRIGGERS
config KERNEL_DEBUG_KERNEL
bool
default n
config KERNEL_DEBUG_INFO
bool "Compile the kernel with debug information"
@ -376,7 +363,6 @@ config KERNEL_DEBUG_INFO
config KERNEL_DEBUG_INFO_BTF
bool "Enable additional BTF type information"
default n
depends on !HOST_OS_MACOS
depends on KERNEL_DEBUG_INFO && !KERNEL_DEBUG_INFO_REDUCED
select DWARVES
@ -403,12 +389,10 @@ config KERNEL_DEBUG_INFO_REDUCED
config KERNEL_DEBUG_LL_UART_NONE
bool
default n
depends on arm
config KERNEL_DEBUG_LL
bool
default n
depends on arm
select KERNEL_DEBUG_LL_UART_NONE
help
@ -417,7 +401,6 @@ config KERNEL_DEBUG_LL
config KERNEL_DEBUG_VIRTUAL
bool "Compile the kernel with VM translations debugging"
select KERNEL_DEBUG_KERNEL
default n
help
Enable checks sanity checks to catch invalid uses of
virt_to_phys()/phys_to_virt() against the non-linear address space.
@ -425,7 +408,6 @@ config KERNEL_DEBUG_VIRTUAL
config KERNEL_DYNAMIC_DEBUG
bool "Compile the kernel with dynamic printk"
select KERNEL_DEBUG_FS
default n
help
Compiles debug level messages into the kernel, which would not
otherwise be available at runtime. These messages can then be
@ -437,7 +419,6 @@ config KERNEL_DYNAMIC_DEBUG
config KERNEL_EARLY_PRINTK
bool "Compile the kernel with early printk"
default y if TARGET_bcm53xx
default n
depends on arm
select KERNEL_DEBUG_KERNEL
select KERNEL_DEBUG_LL if arm
@ -448,7 +429,6 @@ config KERNEL_EARLY_PRINTK
config KERNEL_KPROBES
bool "Compile the kernel with kprobes support"
default n
select KERNEL_FTRACE
select KERNEL_PERF_EVENTS
help
@ -465,7 +445,6 @@ config KERNEL_KPROBE_EVENTS
config KERNEL_BPF_EVENTS
bool "Compile the kernel with BPF event support"
default n
select KERNEL_KPROBES
help
Allows to attach BPF programs to kprobe, uprobe and tracepoint events.
@ -475,7 +454,6 @@ config KERNEL_BPF_EVENTS
config KERNEL_BPF_KPROBE_OVERRIDE
bool
default n
depends on KERNEL_KPROBES
config KERNEL_AIO
@ -496,7 +474,6 @@ config KERNEL_FANOTIFY
config KERNEL_BLK_DEV_BSG
bool "Compile the kernel with SCSI generic v4 support for any block device"
default n
config KERNEL_TRANSPARENT_HUGEPAGE
bool
@ -520,7 +497,6 @@ config KERNEL_HUGETLB_PAGE
bool "Compile the kernel with HugeTLB support"
select KERNEL_TRANSPARENT_HUGEPAGE
select KERNEL_HUGETLBFS
default n
config KERNEL_MAGIC_SYSRQ
bool "Compile the kernel with SysRq support"
@ -545,7 +521,6 @@ config KERNEL_ELF_CORE
config KERNEL_PROVE_LOCKING
bool "Enable kernel lock checking"
select KERNEL_DEBUG_KERNEL
default n
config KERNEL_SOFTLOCKUP_DETECTOR
bool "Compile the kernel with detect Soft Lockups"
@ -647,11 +622,9 @@ config USE_RFKILL
config USE_SPARSE
bool "Enable sparse check during kernel build"
default n
config KERNEL_DEVTMPFS
bool "Compile the kernel with device tmpfs enabled"
default n
help
devtmpfs is a simple, kernel-managed /dev filesystem. The kernel creates
devices nodes for all registered devices to simplify boot, but leaves more
@ -661,7 +634,6 @@ if KERNEL_DEVTMPFS
config KERNEL_DEVTMPFS_MOUNT
bool "Automatically mount devtmpfs after root filesystem is mounted"
default n
endif
@ -672,17 +644,14 @@ config KERNEL_KEYS
config KERNEL_PERSISTENT_KEYRINGS
bool "Enable kernel persistent keyrings"
depends on KERNEL_KEYS
default n
config KERNEL_KEYS_REQUEST_CACHE
bool "Enable temporary caching of the last request_key() result"
depends on KERNEL_KEYS
default n
config KERNEL_BIG_KEYS
bool "Enable large payload keys on kernel keyrings"
depends on KERNEL_KEYS
default n
#
# CGROUP support symbols
@ -696,7 +665,6 @@ if KERNEL_CGROUPS
config KERNEL_CGROUP_DEBUG
bool "Example debug cgroup subsystem"
default n
help
This option enables a simple cgroup subsystem that
exports useful debugging information about the cgroups
@ -707,7 +675,6 @@ if KERNEL_CGROUPS
config KERNEL_CGROUP_FREEZER
bool "legacy Freezer cgroup subsystem"
default n
select KERNEL_FREEZER
help
Provides a way to freeze and unfreeze all tasks in a
@ -717,7 +684,6 @@ if KERNEL_CGROUPS
config KERNEL_CGROUP_DEVICE
bool "legacy Device controller for cgroups"
default n
help
Provides a cgroup implementing whitelists for devices which
a process in the cgroup can mknod or open.
@ -725,7 +691,6 @@ if KERNEL_CGROUPS
config KERNEL_CGROUP_HUGETLB
bool "HugeTLB controller"
default n
select KERNEL_HUGETLB_PAGE
config KERNEL_CGROUP_PIDS
@ -754,7 +719,6 @@ if KERNEL_CGROUPS
config KERNEL_PROC_PID_CPUSET
bool "Include legacy /proc/<pid>/cpuset file"
default n
depends on KERNEL_CPUSETS
config KERNEL_CGROUP_CPUACCT
@ -820,7 +784,6 @@ if KERNEL_CGROUPS
config KERNEL_MEMCG_SWAP_ENABLED
bool "Memory Resource Controller Swap Extension enabled by default"
default n
depends on KERNEL_MEMCG_SWAP
help
Memory Resource Controller Swap Extension comes with its price in
@ -849,7 +812,6 @@ if KERNEL_CGROUPS
config KERNEL_CGROUP_PERF
bool "Enable perf_event per-cpu per-container group (cgroup) monitoring"
select KERNEL_PERF_EVENTS
default n
help
This option extends the per-cpu mode to restrict monitoring to
threads which belong to the cgroup specified and run on the
@ -926,7 +888,6 @@ if KERNEL_CGROUPS
config KERNEL_DEBUG_BLK_CGROUP
bool "Enable Block IO controller debugging"
default n
depends on KERNEL_BLK_CGROUP
help
Enable some debugging help. Currently it exports additional stat
@ -934,15 +895,12 @@ if KERNEL_CGROUPS
config KERNEL_NET_CLS_CGROUP
bool "legacy Control Group Classifier"
default n
config KERNEL_CGROUP_NET_CLASSID
bool "legacy Network classid cgroup"
default n
config KERNEL_CGROUP_NET_PRIO
bool "legacy Network priority cgroup"
default n
endif
@ -1168,7 +1126,6 @@ endif
menu "Filesystem ACL and attr support options"
config USE_FS_ACL_ATTR
bool "Use filesystem ACL and attr support by default"
default n
help
Make using ACLs (e.g. POSIX ACL, NFSv4 ACL) the default
for kernel and packages, except tmpfs, flash filesystems,
@ -1193,17 +1150,14 @@ menu "Filesystem ACL and attr support options"
config KERNEL_F2FS_FS_POSIX_ACL
bool "Enable POSIX ACL for F2FS Filesystems"
select KERNEL_FS_POSIX_ACL
default n
config KERNEL_JFFS2_FS_POSIX_ACL
bool "Enable POSIX ACL for JFFS2 Filesystems"
select KERNEL_FS_POSIX_ACL
default n
config KERNEL_TMPFS_POSIX_ACL
bool "Enable POSIX ACL for TMPFS Filesystems"
select KERNEL_FS_POSIX_ACL
default n
config KERNEL_CIFS_ACL
bool "Enable CIFS ACLs"
@ -1226,15 +1180,12 @@ menu "Filesystem ACL and attr support options"
config KERNEL_NFS_V3_ACL_SUPPORT
bool "Enable ACLs for NFSv3"
default n
config KERNEL_NFSD_V2_ACL_SUPPORT
bool "Enable ACLs for NFSDv2"
default n
config KERNEL_NFSD_V3_ACL_SUPPORT
bool "Enable ACLs for NFSDv3"
default n
config KERNEL_REISER_FS_POSIX_ACL
bool "Enable POSIX ACLs for ReiserFS"

View File

@ -1,2 +1,2 @@
LINUX_VERSION-5.10 = .165
LINUX_KERNEL_HASH-5.10.165 = 971defc48f19ed0a2a7ffd4b48234619cac28895c985c6d747f5b707ba47af0d
LINUX_VERSION-5.10 = .166
LINUX_KERNEL_HASH-5.10.166 = 0051a1780e5bda0efc68dafab7c728b8283d2b028fedb439418f478be7d3e1af

View File

@ -1,2 +1,2 @@
LINUX_VERSION-5.15 = .90
LINUX_KERNEL_HASH-5.15.90 = e6fd430022686753af7516fe7544f96aab379509dc5b7829017bdcd92b393b42
LINUX_VERSION-5.15 = .91
LINUX_KERNEL_HASH-5.15.91 = a63c2bb1beb15f1aea9c63cf80559f5b7ab58afd2da2fa5e7670c515ebe1fe80

View File

@ -232,7 +232,7 @@ export_partdevice() {
while read line; do
export -n "$line"
done < "$uevent"
if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then
if [ "$BOOTDEV_MAJOR" = "$MAJOR" -a $(($BOOTDEV_MINOR + $offset)) = "$MINOR" -a -b "/dev/$DEVNAME" ]; then
export "$var=$DEVNAME"
return 0
fi

View File

@ -9,7 +9,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ltq-vdsl-vr9
PKG_VERSION:=4.17.18.6
PKG_RELEASE:=7
PKG_RELEASE:=8
PKG_BASE_NAME:=drv_dsl_cpe_api
PKG_SOURCE:=$(PKG_BASE_NAME)_vrx-$(PKG_VERSION).tar.gz

View File

@ -0,0 +1,22 @@
--- a/src/pm/drv_dsl_cpe_api_pm_vrx.c
+++ b/src/pm/drv_dsl_cpe_api_pm_vrx.c
@@ -1435,9 +1435,16 @@ DSL_Error_t DSL_DRV_PM_DEV_ReTxCountersG
/* ignore zero value*/
if (nEftrMin)
{
- /* Fw Format: kBit/s */
- /* API format: bit/s */
- pCounters->nEftrMin = nEftrMin*1000;
+ if (nDirection == DSL_NEAR_END)
+ {
+ /* Fw Format: kBit/s */
+ /* API format: bit/s */
+ pCounters->nEftrMin = nEftrMin*1000;
+ }
+ else
+ {
+ pCounters->nEftrMin = nEftrMin;
+ }
}
}
else

View File

@ -243,6 +243,22 @@ endef
$(eval $(call KernelPackage,gpio-f7188x))
define KernelPackage/lkdtm
SUBMENU:=$(OTHER_MENU)
TITLE:=Linux Kernel Dump Test Tool Module
KCONFIG:=CONFIG_LKDTM
FILES:=$(LINUX_DIR)/drivers/misc/lkdtm/lkdtm.ko
AUTOLOAD:=$(call AutoProbe,lkdtm)
endef
define KernelPackage/lkdtm/description
This module enables testing of the different dumping mechanisms by inducing
system failures at predefined crash points.
endef
$(eval $(call KernelPackage,lkdtm))
define KernelPackage/pinctrl-mcp23s08
SUBMENU:=$(OTHER_MENU)
TITLE:=Microchip MCP23xxx I/O expander

View File

@ -8,9 +8,9 @@ PKG_LICENSE_FILES:=
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-12-22
PKG_SOURCE_VERSION:=5b509e80384ab019ac11aa90c81ec0dbb5b0d7f2
PKG_MIRROR_HASH:=6fc25df4d28becd010ff4971b23731c08b53e69381a9e4c868091899712f78a9
PKG_SOURCE_DATE:=2023-02-02
PKG_SOURCE_VERSION:=b2360d59747c6fed2b65bc1c3563c10593c83f3e
PKG_MIRROR_HASH:=f85f00fa8f549de348a115f92c4f0235e413ed924669aece390c7570882526dd
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_USE_NINJA:=0
@ -40,7 +40,8 @@ define KernelPackage/mt76-default
SUBMENU:=Wireless Drivers
DEPENDS:= \
+kmod-mac80211 \
+@DRIVER_11AC_SUPPORT
+@DRIVER_11AC_SUPPORT \
+@KERNEL_PAGE_POOL
endef
define KernelPackage/mt76

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=mbedtls
PKG_VERSION:=2.28.2
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_USE_MIPS16:=0
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz

View File

@ -0,0 +1,181 @@
From 272d48fe7a2ff00285d4ee166d3a9beca1d5122f Mon Sep 17 00:00:00 2001
From: Glenn Strauss <gstrauss@gluelogic.com>
Date: Sun, 23 Oct 2022 19:48:18 -0400
Subject: [PATCH 1/4] x509 crt verify SAN iPAddress
Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
---
include/mbedtls/x509_crt.h | 2 +-
library/x509_crt.c | 115 +++++++++++++++++++++++++++++--------
2 files changed, 93 insertions(+), 24 deletions(-)
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -597,7 +597,7 @@ int mbedtls_x509_crt_verify_info( char *
* \param cn The expected Common Name. This will be checked to be
* present in the certificate's subjectAltNames extension or,
* if this extension is absent, as a CN component in its
- * Subject name. Currently only DNS names are supported. This
+ * Subject name. DNS names and IP addresses are supported. This
* may be \c NULL if the CN need not be verified.
* \param flags The address at which to store the result of the verification.
* If the verification couldn't be completed, the flag value is
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -2986,6 +2986,54 @@ find_parent:
}
}
+#ifdef _WIN32
+/* ??? */
+#elif defined(__sun)
+/* Solaris requires -lsocket -lnsl for inet_pton() */
+#elif defined(__has_include)
+#if __has_include(<sys/socket.h>)
+#include <sys/socket.h>
+#endif
+#if __has_include(<arpa/inet.h>)
+#include <arpa/inet.h>
+#endif
+#endif
+
+/* Use whether or not AF_INET6 is defined to indicate whether or not to use
+ * the platform inet_pton() or a local implementation (below). The local
+ * implementation may be used even in cases where the platform provides
+ * inet_pton(), e.g. when there are different includes required and/or the
+ * platform implementation requires dependencies on additional libraries.
+ * Specifically, Windows requires custom includes and additional link
+ * dependencies, and Solaris requires additional link dependencies.
+ * Also, as a coarse heuristic, use the local implementation if the compiler
+ * does not support __has_include(), or if the definition of AF_INET6 is not
+ * provided by headers included (or not) via __has_include() above. */
+#ifndef AF_INET6
+
+#define x509_cn_inet_pton( cn, dst ) ( 0 )
+
+#else
+
+static int x509_inet_pton_ipv6( const char *src, void *dst )
+{
+ return( inet_pton( AF_INET6, src, dst ) == 1 ? 0 : -1 );
+}
+
+static int x509_inet_pton_ipv4( const char *src, void *dst )
+{
+ return( inet_pton( AF_INET, src, dst ) == 1 ? 0 : -1 );
+}
+
+#endif /* AF_INET6 */
+
+static size_t x509_cn_inet_pton( const char *cn, void *dst )
+{
+ return( strchr( cn, ':' ) == NULL
+ ? x509_inet_pton_ipv4( cn, dst ) == 0 ? 4 : 0
+ : x509_inet_pton_ipv6( cn, dst ) == 0 ? 16 : 0 );
+}
+
/*
* Check for CN match
*/
@@ -3008,23 +3056,51 @@ static int x509_crt_check_cn( const mbed
return( -1 );
}
+static int x509_crt_check_san_ip( const mbedtls_x509_sequence *san,
+ const char *cn, size_t cn_len )
+{
+ uint32_t ip[4];
+ cn_len = x509_cn_inet_pton( cn, ip );
+ if( cn_len == 0 )
+ return( -1 );
+
+ for( const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next )
+ {
+ const unsigned char san_type = (unsigned char) cur->buf.tag &
+ MBEDTLS_ASN1_TAG_VALUE_MASK;
+ if( san_type == MBEDTLS_X509_SAN_IP_ADDRESS &&
+ cur->buf.len == cn_len && memcmp( cur->buf.p, ip, cn_len ) == 0 )
+ return( 0 );
+ }
+
+ return( -1 );
+}
+
/*
* Check for SAN match, see RFC 5280 Section 4.2.1.6
*/
-static int x509_crt_check_san( const mbedtls_x509_buf *name,
+static int x509_crt_check_san( const mbedtls_x509_sequence *san,
const char *cn, size_t cn_len )
{
- const unsigned char san_type = (unsigned char) name->tag &
- MBEDTLS_ASN1_TAG_VALUE_MASK;
-
- /* dNSName */
- if( san_type == MBEDTLS_X509_SAN_DNS_NAME )
- return( x509_crt_check_cn( name, cn, cn_len ) );
-
- /* (We may handle other types here later.) */
+ int san_ip = 0;
+ for( const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next )
+ {
+ switch( (unsigned char) cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK )
+ {
+ case MBEDTLS_X509_SAN_DNS_NAME: /* dNSName */
+ if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 )
+ return( 0 );
+ break;
+ case MBEDTLS_X509_SAN_IP_ADDRESS: /* iPAddress */
+ san_ip = 1;
+ break;
+ /* (We may handle other types here later.) */
+ default: /* Unrecognized type */
+ break;
+ }
+ }
- /* Unrecognized type */
- return( -1 );
+ return( san_ip ? x509_crt_check_san_ip( san, cn, cn_len ) : -1 );
}
/*
@@ -3035,19 +3111,12 @@ static void x509_crt_verify_name( const
uint32_t *flags )
{
const mbedtls_x509_name *name;
- const mbedtls_x509_sequence *cur;
size_t cn_len = strlen( cn );
if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
{
- for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next )
- {
- if( x509_crt_check_san( &cur->buf, cn, cn_len ) == 0 )
- break;
- }
-
- if( cur == NULL )
- *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
+ if( x509_crt_check_san( &crt->subject_alt_names, cn, cn_len ) == 0 )
+ return;
}
else
{
@@ -3056,13 +3125,13 @@ static void x509_crt_verify_name( const
if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 &&
x509_crt_check_cn( &name->val, cn, cn_len ) == 0 )
{
- break;
+ return;
}
}
- if( name == NULL )
- *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
}
+
+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
}
/*

View File

@ -151,6 +151,33 @@ CONFIGURE_ARGS += \
--$(if $(CONFIG_WOLFSSL_HAS_ECC448),enable,disable)-curve448 \
--$(if $(CONFIG_WOLFSSL_HAS_OPENVPN),enable,disable)-openvpn
define Package/libwolfsslcpu-crypto/preinst-aarch64
#!/bin/sh
exec >&2
printf "[libwolfsslcpu-crypto] Checking for Arm v8-A Cryptographic Extension support: "
if [ -n "$${IPKG_INSTROOT}" ]; then
printf "...[offline]... "
eval "$$(grep '^DISTRIB_TARGET=' "$${IPKG_INSTROOT}/etc/openwrt_release")"
echo "$${DISTRIB_TARGET}" | grep '^bcm27xx/.*' > /dev/null && {
echo "not supported"
echo "Error: Target $${DISTRIB_TARGET} does not support Arm Cryptographic Extension."
echo "Install the regular libwolfssl package instead of libwolfsslcpu-crypto."
exit 1
}
else
grep -q '^Features.*\baes\b' /proc/cpuinfo || {
echo "not supported"
echo "Error: Arm v8-A Cryptographic Extension not supported."
echo "Install the regular libwolfssl package instead of libwolfsslcpu-crypto."
echo "Contents of /proc/cpuinfo:"
cat /proc/cpuinfo
exit 1
}
fi
echo OK
exit 0
endef
ifeq ($(BUILD_VARIANT),regular)
CONFIGURE_ARGS += \
--$(if $(CONFIG_WOLFSSL_HAS_AFALG),enable,disable)-afalg \
@ -160,9 +187,7 @@ CONFIGURE_ARGS += \
else ifdef CONFIG_aarch64
CONFIGURE_ARGS += --enable-armasm
TARGET_CFLAGS:=$(TARGET_CFLAGS:-mcpu%=-mcpu%+crypto)
WOLFSSL_NOASM_REGEX:=^bcm27xx/.*
Package/libwolfsslcpu-crypto/preinst=\
$(subst @@WOLFSSL_NOASM_REGEX@@,$(WOLFSSL_NOASM_REGEX),$(file <preinst.arm-ce))
Package/libwolfsslcpu-crypto/preinst=$(Package/libwolfsslcpu-crypto/preinst-aarch64)
else ifdef CONFIG_TARGET_x86_64
CONFIGURE_ARGS += --enable-intelasm
endif

View File

@ -1,25 +0,0 @@
#!/bin/sh
exec >&2
printf "[libwolfsslcpu-crypto] Checking for Arm v8-A Cryptographic Extension support: "
if [ -n "${IPKG_INSTROOT}" ]; then
printf "...[offline]... "
eval "$(grep '^DISTRIB_TARGET=' "${IPKG_INSTROOT}/etc/openwrt_release")"
### @@WOLFSSL_NOASM_REGEX@@ is expanded from WOLFSSL_NOASM_REGEX in the Makefile
echo "${DISTRIB_TARGET}" | grep '@@WOLFSSL_NOASM_REGEX@@' > /dev/null && {
echo "not supported"
echo "Error: Target ${DISTRIB_TARGET} does not support Arm Cryptographic Extension."
echo "Install the regular libwolfssl package instead of libwolfsslcpu-crypto."
exit 1
}
else
grep -q '^Features.*\baes\b' /proc/cpuinfo || {
echo "not supported"
echo "Error: Arm v8-A Cryptographic Extension not supported."
echo "Install the regular libwolfssl package instead of libwolfsslcpu-crypto."
echo "Contents of /proc/cpuinfo:"
cat /proc/cpuinfo
exit 1
}
fi
echo OK
exit 0

View File

@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=dsl_cpe_control_danube
PKG_VERSION:=3.24.4.4
PKG_RELEASE:=10
PKG_RELEASE:=11
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_BUILD_DIR:=$(BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION)
PKG_SOURCE_URL:=@OPENWRT

View File

@ -9,7 +9,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ltq-vdsl-vr11-app
PKG_VERSION:=4.23.1
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_BASE_NAME:=dsl_cpe_control
UGW_VERSION=8.5.2.10

View File

@ -133,6 +133,17 @@ enum {
PSTATE_MAP_L3,
};
/* These values are exported via ubus and backwards compability
* needs to be kept!
*/
enum {
RAMODE_MAP_UNKNOWN = -1,
RAMODE_MAP_MANUAL,
RAMODE_MAP_AT_INIT,
RAMODE_MAP_DYNAMIC,
RAMODE_MAP_DYNAMIC_SOS,
};
static DSL_CPE_ThreadCtrl_t thread;
static struct ubus_context *ctx;
static struct blob_buf b;
@ -171,6 +182,15 @@ static inline void m_array(const char *id, const uint8_t *value, size_t len) {
blobmsg_close_array(&b, c);
}
static inline void m_array_u16(const char *id, const uint16_t *value, size_t len) {
void *c = blobmsg_open_array(&b, id);
for (size_t i = 0; i < len; ++i)
blobmsg_add_u16(&b, "", value[i]);
blobmsg_close_array(&b, c);
}
static void m_vendor(const char *id, const uint8_t *value) {
// ITU-T T.35: U.S.
if (U16(value[0], value[1]) != 0xb500)
@ -418,6 +438,31 @@ static void g997_line_inventory(int fd) {
m_array("serial", out.data.SerialNumber, DSL_G997_LI_MAXLEN_SERIAL);
}
static void pilot_tones_status(int fd) {
#ifndef INCLUDE_DSL_CPE_API_DANUBE
IOCTL(DSL_PilotTonesStatus_t, DSL_FIO_PILOT_TONES_STATUS_GET);
m_array_u16("pilot_tones", out.data.nPilotTone, out.data.nNumData);
#endif
}
static void band_border_status(int fd, DSL_AccessDir_t direction) {
IOCTL(DSL_BandBorderStatus_t, DSL_FIO_BAND_BORDER_STATUS_GET);
void *c, *c2;
c = blobmsg_open_array(&b, "limits");
for (size_t i = 0; i < out.data.nNumData; i++) {
c2 = blobmsg_open_table(&b, "");
blobmsg_add_u16(&b, "first", out.data.nBandLimits[i].nFirstToneIndex);
blobmsg_add_u16(&b, "last", out.data.nBandLimits[i].nLastToneIndex);
blobmsg_close_table(&b, c2);
}
blobmsg_close_array(&b, c);
}
static void g977_get_bit_allocation(int fd, DSL_AccessDir_t direction) {
IOCTL_DIR(DSL_G997_BitAllocationNsc_t, DSL_FIO_G997_BIT_ALLOCATION_NSC_GET, direction);
@ -639,19 +684,46 @@ static void band_plan_status(int fd, profile_t *profile) {
#endif
}
static void line_feature_config(int fd, DSL_AccessDir_t direction) {
static void line_feature_config(int fd, DSL_AccessDir_t direction, bool *retx) {
IOCTL_DIR(DSL_LineFeature_t, DSL_FIO_LINE_FEATURE_STATUS_GET, direction)
m_bool("trellis", out.data.bTrellisEnable);
m_bool("bitswap", out.data.bBitswapEnable);
m_bool("retx", out.data.bReTxEnable);
m_bool("virtual_noise", out.data.bVirtualNoiseSupport);
*retx = out.data.bReTxEnable;
}
static void g997_rate_adaptation_status(int fd, DSL_AccessDir_t direction) {
#ifndef INCLUDE_DSL_CPE_API_DANUBE
IOCTL_DIR(DSL_G997_RateAdaptationStatus_t, DSL_FIO_G997_RATE_ADAPTATION_STATUS_GET, direction);
int map = RAMODE_MAP_UNKNOWN;
const char *str;
switch (out.data.RA_MODE) {
STR_CASE_MAP(DSL_G997_RA_MODE_MANUAL, "Manual", RAMODE_MAP_MANUAL)
STR_CASE_MAP(DSL_G997_RA_MODE_AT_INIT, "At initialization", RAMODE_MAP_AT_INIT)
STR_CASE_MAP(DSL_G997_RA_MODE_DYNAMIC, "Dynamic", RAMODE_MAP_DYNAMIC)
STR_CASE_MAP(DSL_G997_RA_MODE_DYNAMIC_SOS, "Dynamic with SOS", RAMODE_MAP_DYNAMIC_SOS)
default:
str = NULL;
break;
};
if (str)
m_str("ra_mode", str);
if (map != PSTATE_MAP_UNKNOWN)
m_u32("ra_mode_num", map);
#endif
}
static void g997_channel_status(int fd, DSL_AccessDir_t direction) {
IOCTL_DIR(DSL_G997_ChannelStatus_t, DSL_FIO_G997_CHANNEL_STATUS_GET, direction);
m_u32("interleave_delay", out.data.ActualInterleaveDelay * 10);
m_double("inp", (double)out.data.ActualImpulseNoiseProtection / 10);
#ifndef INCLUDE_DSL_CPE_API_DANUBE
// prefer ACTNDR, see comments in drv_dsl_cpe_api_g997.h
m_u32("data_rate", out.data.ActualNetDataRate);
@ -672,6 +744,41 @@ static void g997_line_status(int fd, DSL_AccessDir_t direction) {
m_u32("attndr", out.data.ATTNDR);
}
static void pm_retx_counters_showtime(int fd, DSL_XTUDir_t direction) {
#ifdef INCLUDE_DSL_CPE_PM_RETX_COUNTERS
IOCTL_DIR(DSL_PM_ReTxCounters_t, DSL_FIO_PM_RETX_COUNTERS_SHOWTIME_GET, direction);
m_u32("mineftr", out.data.nEftrMin);
#endif
}
#ifndef INCLUDE_DSL_CPE_API_DANUBE
static void olr_statistics(int fd, DSL_AccessDir_t direction) {
IOCTL_DIR(DSL_OlrStatistics_t, DSL_FIO_OLR_STATISTICS_GET, direction)
void *c = blobmsg_open_table(&b, "bitswap");
m_u32("requested", out.data.nBitswapRequested + out.data.nBitswapRequested);
m_u32("executed", out.data.nBitswapExecuted);
m_u32("rejected", out.data.nBitswapRejected);
m_u32("timeout", out.data.nBitswapTimeout);
blobmsg_close_table(&b, c);
c = blobmsg_open_table(&b, "sra");
m_u32("requested", out.data.nSraRequested);
m_u32("executed", out.data.nSraExecuted);
m_u32("rejected", out.data.nSraRejected);
m_u32("timeout", out.data.nSraTimeout);
blobmsg_close_table(&b, c);
c = blobmsg_open_table(&b, "sos");
m_u32("requested", out.data.nSosRequested);
m_u32("executed", out.data.nSosExecuted);
m_u32("rejected", out.data.nSosRejected);
m_u32("timeout", out.data.nSosTimeout);
blobmsg_close_table(&b, c);
}
#endif
static void pm_line_sec_counters_total(int fd, DSL_XTUDir_t direction) {
IOCTL_DIR(DSL_PM_LineSecCountersTotal_t, DSL_FIO_PM_LINE_SEC_COUNTERS_TOTAL_GET, direction)
@ -685,6 +792,21 @@ static void pm_line_sec_counters_total(int fd, DSL_XTUDir_t direction) {
#endif
}
static void pm_retx_counters_total(int fd, DSL_XTUDir_t direction) {
#ifdef INCLUDE_DSL_CPE_PM_RETX_COUNTERS
IOCTL_DIR(DSL_PM_ReTxCountersTotal_t, DSL_FIO_PM_RETX_COUNTERS_TOTAL_GET, direction);
m_u32("leftrs", out.data.nLeftr);
#endif
}
static void pm_channel_counters_total(int fd, DSL_XTUDir_t direction) {
IOCTL_DIR(DSL_PM_ChannelCountersTotal_t, DSL_FIO_PM_CHANNEL_COUNTERS_TOTAL_GET, direction);
m_u32("cv_c", out.data.nCodeViolations);
m_u32("fec_c", out.data.nFEC);
}
static void pm_data_path_counters_total(int fd, DSL_XTUDir_t direction) {
IOCTL_DIR(DSL_PM_DataPathCountersTotal_t, DSL_FIO_PM_DATA_PATH_COUNTERS_TOTAL_GET, direction);
@ -810,6 +932,17 @@ static int line_statistics(struct ubus_context *ctx, struct ubus_object *obj,
blob_buf_init(&b, 0);
pilot_tones_status(fd);
c = blobmsg_open_table(&b, "bands");
c2 = blobmsg_open_table(&b, "downstream");
band_border_status(fd, DSL_DOWNSTREAM);
blobmsg_close_table(&b, c2);
c2 = blobmsg_open_table(&b, "upstream");
band_border_status(fd, DSL_UPSTREAM);
blobmsg_close_table(&b, c2);
blobmsg_close_table(&b, c);
c = blobmsg_open_table(&b, "bits");
c2 = blobmsg_open_table(&b, "downstream");
g977_get_bit_allocation(fd, DSL_DOWNSTREAM);
@ -862,6 +995,7 @@ static int metrics(struct ubus_context *ctx, struct ubus_object *obj,
standard_t standard = STD_UNKNOWN;
profile_t profile = PROFILE_UNKNOWN;
vector_t vector = VECTOR_UNKNOWN;
bool retx_up = false, retx_down = false;
#ifndef INCLUDE_DSL_CPE_API_DANUBE
fd = open(DSL_CPE_DEVICE_NAME "/0", O_RDWR, 0644);
@ -908,9 +1042,12 @@ static int metrics(struct ubus_context *ctx, struct ubus_object *obj,
default:
break;
};
line_feature_config(fd, DSL_UPSTREAM);
line_feature_config(fd, DSL_UPSTREAM, &retx_up);
g997_rate_adaptation_status(fd, DSL_UPSTREAM);
g997_channel_status(fd, DSL_UPSTREAM);
g997_line_status(fd, DSL_UPSTREAM);
if (retx_up)
pm_retx_counters_showtime(fd, DSL_FAR_END);
blobmsg_close_table(&b, c);
c = blobmsg_open_table(&b, "downstream");
@ -925,20 +1062,40 @@ static int metrics(struct ubus_context *ctx, struct ubus_object *obj,
default:
break;
};
line_feature_config(fd, DSL_DOWNSTREAM);
line_feature_config(fd, DSL_DOWNSTREAM, &retx_down);
g997_rate_adaptation_status(fd, DSL_DOWNSTREAM);
g997_channel_status(fd, DSL_DOWNSTREAM);
g997_line_status(fd, DSL_DOWNSTREAM);
if (retx_down)
pm_retx_counters_showtime(fd, DSL_NEAR_END);
blobmsg_close_table(&b, c);
#ifndef INCLUDE_DSL_CPE_API_DANUBE
c = blobmsg_open_table(&b, "olr");
c2 = blobmsg_open_table(&b, "downstream");
olr_statistics(fd, DSL_DOWNSTREAM);
blobmsg_close_table(&b, c2);
c2 = blobmsg_open_table(&b, "upstream");
olr_statistics(fd, DSL_UPSTREAM);
blobmsg_close_table(&b, c2);
blobmsg_close_table(&b, c);
#endif
c = blobmsg_open_table(&b, "errors");
c2 = blobmsg_open_table(&b, "near");
pm_line_sec_counters_total(fd, DSL_NEAR_END);
if (retx_down)
pm_retx_counters_total(fd, DSL_NEAR_END);
pm_channel_counters_total(fd, DSL_NEAR_END);
pm_data_path_counters_total(fd, DSL_NEAR_END);
retx_statistics(fd, DSL_NEAR_END);
blobmsg_close_table(&b, c2);
c2 = blobmsg_open_table(&b, "far");
pm_line_sec_counters_total(fd, DSL_FAR_END);
if (retx_up)
pm_retx_counters_total(fd, DSL_FAR_END);
pm_channel_counters_total(fd, DSL_FAR_END);
pm_data_path_counters_total(fd, DSL_FAR_END);
retx_statistics(fd, DSL_FAR_END);
blobmsg_close_table(&b, c2);

View File

@ -12,9 +12,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/fstools.git
PKG_MIRROR_HASH:=edda9151c73c1adfe369f5e315347344727a540ad57d3e2b41b9f57f9d4313fe
PKG_SOURCE_DATE:=2023-01-22
PKG_SOURCE_VERSION:=1ea5855e980cd88766dd9f615e78e7dd6edfbb74
PKG_MIRROR_HASH:=d2fc78b66c4e6ac5f51c77f92bd0d2322db78905a9dfea582fc7d975ea68ffe4
PKG_SOURCE_DATE:=2023-02-04
PKG_SOURCE_VERSION:=14d535e4485dc030deecbba9ab493c379df5c237
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0

View File

@ -7,7 +7,7 @@ PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubus.git
PKG_SOURCE_DATE:=2022-06-15
PKG_SOURCE_VERSION:=9913aa61de739e3efe067a2d186021c20bcd65e2
PKG_MIRROR_HASH:=2a9fd9e895835b15948ab211963b7489f8437cd1b2bf43e0e321bc960e105774
PKG_MIRROR_HASH:=f6702e68d7c60388c11f40ca5ca8e932d0bf423325db5bee2c79404782bbcb52
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
CMAKE_INSTALL:=1

View File

@ -158,7 +158,8 @@ parse_args() {
return 1
}
[ -n "$o_subtarget" ] || o_subtarget="generic"
o_bindir="bin/targets/$o_target/$o_subtarget"
eval "$(grep ^CONFIG_BINARY_FOLDER= .config 2>/dev/null)"
o_bindir="${CONFIG_BINARY_FOLDER:-bin}/targets/$o_target/$o_subtarget"
}
start_qemu_armvirt() {

View File

@ -21,18 +21,21 @@
### -p --package-size Check IPK package size and not installed size
### -h --help This message
CONFIG_TARGET=$(sed -n 's/^CONFIG_TARGET_BOARD="\(.*\)"$/\1/p' .config)
CONFIG_SUBTARGET=$(sed -n 's/^CONFIG_TARGET_SUBTARGET="\(.*\)"$/\1/p' .config)
CONFIG_ARCH=$(sed -n 's/^CONFIG_TARGET_ARCH_PACKAGES="\(.*\)"$/\1/p' .config)
eval "$(grep \
-e ^CONFIG_TARGET_BOARD= \
-e ^CONFIG_TARGET_SUBTARGET= \
-e ^CONFIG_TARGET_ARCH_PACKAGES= \
-e ^CONFIG_BINARY_FOLDER= \
.config 2>/dev/null \
)"
CONFIG_PACKAGES=$(sed -n 's/^CONFIG_PACKAGE_\(.*\)=y$/\1/p' .config | tr '\n' ' ')
CONFIG_BIN_DIR=$(sed -n 's/^CONFIG_BINARY_DIR="\(.*\)"$/\1/p' .config)
TARGET=${TARGET:-$CONFIG_TARGET}
SUBTARGET=${SUBTARGET:-$CONFIG_SUBTARGET}
ARCH=${ARCH:-$CONFIG_ARCH}
TARGET=${TARGET:-$CONFIG_TARGET_BOARD}
SUBTARGET=${SUBTARGET:-$CONFIG_TARGET_SUBTARGET}
ARCH=${ARCH:-$CONFIG_TARGET_ARCH_PACKAGES}
PACKAGES=${PACKAGES:-$CONFIG_PACKAGES}
BIN_DIR=${CONFIG_BIN_DIR:-./bin}
BASE_URL="${BASE_URL:-https://downloads.immortalwrt.org/snapshots}"
BIN_DIR=${CONFIG_BINARY_FOLDER:-./bin}
BASE_URL="${BASE_URL:-https://downloads.openwrt.org/snapshots}"
CHECK_INSTALLED="${CHECK_INSTALLED:-y}"
TARGET_URL="$BASE_URL/targets/$TARGET/$SUBTARGET/packages/Packages.gz"
@ -72,6 +75,7 @@ package_size () {
}
compare_sizes () {
TOTAL_DIFF="0"
for PACKAGE in $PACKAGES; do
if [ "$PACKAGE" = "libc" ]; then
continue
@ -90,6 +94,7 @@ compare_sizes () {
fi
SIZE_UPSTREAM=$(package_size "$TMP_INDEX" "$PACKAGE")
SIZE_DIFF="$((SIZE_LOCAL - SIZE_UPSTREAM))"
TOTAL_DIFF="$((TOTAL_DIFF + SIZE_DIFF))"
if [ "$SIZE_DIFF" -gt 0 ]; then
SIZE_DIFF="+$SIZE_DIFF"
fi
@ -99,6 +104,7 @@ compare_sizes () {
echo "$PACKAGE is missing upstream"
fi
done
echo "~~~~~~~ total change ${TOTAL_DIFF}"
}
if [ "$1" = "-h" ]; then

View File

@ -1,10 +1,8 @@
config AT91_DFBOOT
bool "Build dataflashboot loader"
depends on TARGET_at91
default n
config FLEXIBITY_ROOT
bool "Build Flexibity RootFS (with embedded kernel)"
depends on TARGET_at91_flexibity
default n

View File

@ -49,7 +49,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
#ifdef CONFIG_MACB_USE_HWSTAMP
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3831,15 +3831,15 @@ static int macb_init(struct platform_dev
@@ -3824,15 +3824,15 @@ static int macb_init(struct platform_dev
if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) {
val = 0;
if (phy_interface_mode_is_rgmii(bp->phy_interface))
@ -69,7 +69,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
macb_or_gem_writel(bp, USRIO, val);
}
@@ -4357,6 +4357,13 @@ static int fu540_c000_init(struct platfo
@@ -4350,6 +4350,13 @@ static int fu540_c000_init(struct platfo
return macb_init(pdev);
}
@ -83,7 +83,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static const struct macb_config fu540_c000_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO |
MACB_CAPS_GEM_HAS_PTP,
@@ -4364,12 +4371,14 @@ static const struct macb_config fu540_c0
@@ -4357,12 +4364,14 @@ static const struct macb_config fu540_c0
.clk_init = fu540_c000_clk_init,
.init = fu540_c000_init,
.jumbo_max_len = 10240,
@ -98,7 +98,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct macb_config sama5d3macb_config = {
@@ -4377,6 +4386,7 @@ static const struct macb_config sama5d3m
@@ -4370,6 +4379,7 @@ static const struct macb_config sama5d3m
| MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
.clk_init = macb_clk_init,
.init = macb_init,
@ -106,7 +106,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct macb_config pc302gem_config = {
@@ -4384,6 +4394,7 @@ static const struct macb_config pc302gem
@@ -4377,6 +4387,7 @@ static const struct macb_config pc302gem
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
@ -114,7 +114,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct macb_config sama5d2_config = {
@@ -4391,6 +4402,7 @@ static const struct macb_config sama5d2_
@@ -4384,6 +4395,7 @@ static const struct macb_config sama5d2_
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
@ -122,7 +122,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct macb_config sama5d3_config = {
@@ -4400,6 +4412,7 @@ static const struct macb_config sama5d3_
@@ -4393,6 +4405,7 @@ static const struct macb_config sama5d3_
.clk_init = macb_clk_init,
.init = macb_init,
.jumbo_max_len = 10240,
@ -130,7 +130,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct macb_config sama5d4_config = {
@@ -4407,18 +4420,21 @@ static const struct macb_config sama5d4_
@@ -4400,18 +4413,21 @@ static const struct macb_config sama5d4_
.dma_burst_length = 4,
.clk_init = macb_clk_init,
.init = macb_init,
@ -152,7 +152,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct macb_config zynqmp_config = {
@@ -4429,6 +4445,7 @@ static const struct macb_config zynqmp_c
@@ -4422,6 +4438,7 @@ static const struct macb_config zynqmp_c
.clk_init = macb_clk_init,
.init = macb_init,
.jumbo_max_len = 10240,
@ -160,7 +160,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct macb_config zynq_config = {
@@ -4437,6 +4454,7 @@ static const struct macb_config zynq_con
@@ -4430,6 +4447,7 @@ static const struct macb_config zynq_con
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
@ -168,7 +168,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct of_device_id macb_dt_ids[] = {
@@ -4557,6 +4575,8 @@ static int macb_probe(struct platform_de
@@ -4550,6 +4568,8 @@ static int macb_probe(struct platform_de
bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;
device_set_wakeup_capable(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);

View File

@ -14,7 +14,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3606,6 +3606,20 @@ static void macb_probe_queues(void __iom
@@ -3599,6 +3599,20 @@ static void macb_probe_queues(void __iom
*num_queues = hweight32(*queue_mask);
}
@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
struct clk **hclk, struct clk **tx_clk,
struct clk **rx_clk, struct clk **tsu_clk)
@@ -4668,11 +4682,7 @@ err_out_free_netdev:
@@ -4661,11 +4675,7 @@ err_out_free_netdev:
free_netdev(dev);
err_disable_clocks:
@ -48,7 +48,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
@@ -4697,11 +4707,8 @@ static int macb_remove(struct platform_d
@@ -4690,11 +4700,8 @@ static int macb_remove(struct platform_d
pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
if (!pm_runtime_suspended(&pdev->dev)) {
@ -62,7 +62,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
pm_runtime_set_suspended(&pdev->dev);
}
phylink_destroy(bp->phylink);
@@ -4880,13 +4887,10 @@ static int __maybe_unused macb_runtime_s
@@ -4873,13 +4880,10 @@ static int __maybe_unused macb_runtime_s
struct net_device *netdev = dev_get_drvdata(dev);
struct macb *bp = netdev_priv(netdev);

View File

@ -14,7 +14,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4338,8 +4338,10 @@ static int fu540_c000_clk_init(struct pl
@@ -4331,8 +4331,10 @@ static int fu540_c000_clk_init(struct pl
return err;
mgmt = devm_kzalloc(&pdev->dev, sizeof(*mgmt), GFP_KERNEL);
@ -27,7 +27,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
init.name = "sifive-gemgxl-mgmt";
init.ops = &fu540_c000_ops;
@@ -4350,16 +4352,26 @@ static int fu540_c000_clk_init(struct pl
@@ -4343,16 +4345,26 @@ static int fu540_c000_clk_init(struct pl
mgmt->hw.init = &init;
*tx_clk = devm_clk_register(&pdev->dev, &mgmt->hw);

View File

@ -14,7 +14,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4390,6 +4390,14 @@ static const struct macb_usrio_config ma
@@ -4383,6 +4383,14 @@ static const struct macb_usrio_config ma
.refclk = MACB_BIT(CLKEN),
};
@ -29,7 +29,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static const struct macb_config fu540_c000_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO |
MACB_CAPS_GEM_HAS_PTP,
@@ -4483,6 +4491,14 @@ static const struct macb_config zynq_con
@@ -4476,6 +4484,14 @@ static const struct macb_config zynq_con
.usrio = &macb_default_usrio,
};
@ -44,7 +44,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,at32ap7000-macb" },
{ .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config },
@@ -4500,6 +4516,7 @@ static const struct of_device_id macb_dt
@@ -4493,6 +4509,7 @@ static const struct of_device_id macb_dt
{ .compatible = "cdns,zynqmp-gem", .data = &zynqmp_config},
{ .compatible = "cdns,zynq-gem", .data = &zynq_config },
{ .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config },

View File

@ -14,7 +14,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4499,6 +4499,14 @@ static const struct macb_config sama7g5_
@@ -4492,6 +4492,14 @@ static const struct macb_config sama7g5_
.usrio = &sama7g5_usrio,
};
@ -29,7 +29,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,at32ap7000-macb" },
{ .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config },
@@ -4517,6 +4525,7 @@ static const struct of_device_id macb_dt
@@ -4510,6 +4518,7 @@ static const struct of_device_id macb_dt
{ .compatible = "cdns,zynq-gem", .data = &zynq_config },
{ .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config },
{ .compatible = "microchip,sama7g5-gem", .data = &sama7g5_gem_config },

View File

@ -20,7 +20,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3868,6 +3868,13 @@ static int macb_init(struct platform_dev
@@ -3861,6 +3861,13 @@ static int macb_init(struct platform_dev
return 0;
}
@ -34,7 +34,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
#if defined(CONFIG_OF)
/* 1518 rounded up */
#define AT91ETHER_MAX_RBUFF_SZ 0x600
@@ -4383,13 +4390,6 @@ static int fu540_c000_init(struct platfo
@@ -4376,13 +4383,6 @@ static int fu540_c000_init(struct platfo
return macb_init(pdev);
}
@ -48,7 +48,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static const struct macb_usrio_config sama7g5_usrio = {
.mii = 0,
.rmii = 1,
@@ -4538,6 +4538,7 @@ static const struct macb_config default_
@@ -4531,6 +4531,7 @@ static const struct macb_config default_
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,

View File

@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
ARCH:=mips
BOARD:=ath25
BOARDNAME:=Atheros AR231x/AR5312
FEATURES:=squashfs low_mem small_flash
FEATURES:=squashfs low_mem small_flash source-only
SUBTARGETS:=generic
KERNEL_PATCHVER:=5.10

View File

@ -10,14 +10,12 @@ if AG71XX
config AG71XX_DEBUG
bool "Atheros AR71xx built-in ethernet driver debugging"
default n
help
Atheros AR71xx built-in ethernet driver debugging messages.
config AG71XX_DEBUG_FS
bool "Atheros AR71xx built-in ethernet driver debugfs support"
depends on DEBUG_FS
default n
help
Say Y, if you need access to various statistics provided by
the ag71xx driver.

View File

@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -761,7 +761,7 @@ static int spidev_probe(struct spi_devic
@@ -759,7 +759,7 @@ static int spidev_probe(struct spi_devic
* compatible string, it is a Linux implementation thing
* rather than a description of the hardware.
*/

View File

@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
#define USB_VENDOR_ID_BELKIN 0x050d
#define USB_DEVICE_ID_FLIP_KVM 0x3201
@@ -1316,6 +1319,9 @@
@@ -1315,6 +1318,9 @@
#define USB_VENDOR_ID_XAT 0x2505
#define USB_DEVICE_ID_XAT_CSR 0x0220
@ -53,7 +53,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL },
@@ -198,6 +199,7 @@ static const struct hid_device_id hid_qu
@@ -197,6 +198,7 @@ static const struct hid_device_id hid_qu
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET },

View File

@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -680,6 +680,7 @@ static const struct file_operations spid
@@ -678,6 +678,7 @@ static const struct file_operations spid
static struct class *spidev_class;
static const struct spi_device_id spidev_spi_ids[] = {

View File

@ -11,6 +11,7 @@ FEATURES:=squashfs usb
SUBTARGETS:=generic mips74k legacy
KERNEL_PATCHVER:=5.10
KERNEL_TESTING_PATCHVER:=5.15
define Target/Description
Build firmware images for Broadcom based BCM47xx/53xx routers with MIPS CPU, *not* ARM.

View File

@ -0,0 +1,177 @@
CONFIG_ADM6996_PHY=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_BCM47XX=y
CONFIG_BCM47XX_BCMA=y
CONFIG_BCM47XX_NVRAM=y
CONFIG_BCM47XX_SPROM=y
CONFIG_BCM47XX_SSB=y
CONFIG_BCM47XX_WDT=y
CONFIG_BCMA=y
CONFIG_BCMA_BLOCKIO=y
CONFIG_BCMA_DEBUG=y
CONFIG_BCMA_DRIVER_GMAC_CMN=y
CONFIG_BCMA_DRIVER_GPIO=y
CONFIG_BCMA_DRIVER_MIPS=y
CONFIG_BCMA_DRIVER_PCI=y
CONFIG_BCMA_DRIVER_PCI_HOSTMODE=y
CONFIG_BCMA_HOST_PCI=y
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
CONFIG_BCMA_HOST_SOC=y
CONFIG_BCMA_NFLASH=y
CONFIG_BCMA_PFLASH=y
CONFIG_BCMA_SFLASH=y
# CONFIG_BGMAC_BCMA is not set
CONFIG_BLK_MQ_PCI=y
CONFIG_CEVT_R4K=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="noinitrd console=ttyS0,115200"
CONFIG_CMDLINE_BOOL=y
# CONFIG_CMDLINE_OVERRIDE is not set
# CONFIG_COMMON_CLK is not set
CONFIG_COMPAT_32BIT_TIME=y
# CONFIG_CPU_BMIPS is not set
CONFIG_CPU_GENERIC_DUMP_TLB=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
CONFIG_CPU_MIPSR1=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
CONFIG_CRYPTO_RNG2=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_NONCOHERENT=y
# CONFIG_EARLY_PRINTK is not set
CONFIG_FIXED_PHY=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_LIB_ASHLDI3=y
CONFIG_GENERIC_LIB_ASHRDI3=y
CONFIG_GENERIC_LIB_CMPDI2=y
CONFIG_GENERIC_LIB_LSHRDI3=y
CONFIG_GENERIC_LIB_UCMPDI2=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_WDT=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HW_RANDOM=y
CONFIG_HZ_PERIODIC=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_LEDS_GPIO_REGISTER=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEMFD_CREATE=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
CONFIG_MIPS_CLOCK_VSYSCALL=y
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
CONFIG_MIPS_EBPF_JIT=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_LD_CAN_LINK_VDSO=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_BCM47XXSFLASH=y
CONFIG_MTD_BCM47XX_PARTS=y
CONFIG_MTD_NAND_BCM47XXNFLASH=y
CONFIG_MTD_NAND_BRCMNAND=y
CONFIG_MTD_NAND_BRCMNAND_BCMA=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_PARSER_TRX=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_RAW_NAND=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NET_SELFTESTS=y
CONFIG_NO_EXCEPT_FILL=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
# CONFIG_OF is not set
CONFIG_PCI=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SRCU=y
CONFIG_SSB=y
CONFIG_SSB_B43_PCI_BRIDGE=y
CONFIG_SSB_BLOCKIO=y
CONFIG_SSB_DRIVER_EXTIF=y
CONFIG_SSB_DRIVER_GIGE=y
CONFIG_SSB_DRIVER_GPIO=y
CONFIG_SSB_DRIVER_MIPS=y
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_EMBEDDED=y
CONFIG_SSB_HOST_SOC=y
CONFIG_SSB_PCICORE_HOSTMODE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_SERIAL=y
CONFIG_SSB_SFLASH=y
CONFIG_SSB_SPROM=y
CONFIG_SWCONFIG=y
CONFIG_SWCONFIG_B53=y
CONFIG_SWCONFIG_B53_PHY_DRIVER=y
CONFIG_SWCONFIG_B53_PHY_FIXUP=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_BMIPS=y
CONFIG_SYS_HAS_CPU_BMIPS32_3300=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_HIGHMEM=y
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_SYS_SUPPORTS_MIPS16=y
CONFIG_SYS_SUPPORTS_ZBOOT=y
CONFIG_TARGET_ISA_REV=1
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_SRCU=y
CONFIG_USB_SUPPORT=y
CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
CONFIG_WATCHDOG_CORE=y

View File

@ -0,0 +1,33 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible
Date: Fri, 07 Jan 2022 10:46:06 -0800
Content-Type: text/plain; charset="utf-8"
In order to key off the brcmnand_probe() code in subsequent changes
depending upon ctrl->soc, assign that variable as early as possible,
instead of much later when we have checked that it is non-NULL.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2998,6 +2998,7 @@ int brcmnand_probe(struct platform_devic
dev_set_drvdata(dev, ctrl);
ctrl->dev = dev;
+ ctrl->soc = soc;
init_completion(&ctrl->done);
init_completion(&ctrl->dma_done);
@@ -3138,8 +3139,6 @@ int brcmnand_probe(struct platform_devic
* interesting ways
*/
if (soc) {
- ctrl->soc = soc;
-
ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
DRV_NAME, ctrl);

View File

@ -0,0 +1,150 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations
Date: Fri, 07 Jan 2022 10:46:07 -0800
Content-Type: text/plain; charset="utf-8"
Allow a brcmnand_soc instance to provide a custom set of I/O operations
which we will require when using this driver on a BCMA bus which is not
directly memory mapped I/O. Update the nand_{read,write}_reg accordingly
to use the SoC operations if provided.
To minimize the penalty on other SoCs which do support standard MMIO
accesses, we use a static key which is disabled by default and gets
enabled if a soc implementation does provide I/O operations.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 28 +++++++++++++++++++++--
drivers/mtd/nand/raw/brcmnand/brcmnand.h | 29 ++++++++++++++++++++++++
2 files changed, 55 insertions(+), 2 deletions(-)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -25,6 +25,7 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
+#include <linux/static_key.h>
#include <linux/list.h>
#include <linux/log2.h>
@@ -207,6 +208,8 @@ enum {
struct brcmnand_host;
+static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key);
+
struct brcmnand_controller {
struct device *dev;
struct nand_controller controller;
@@ -592,15 +595,25 @@ enum {
INTFC_CTLR_READY = BIT(31),
};
+static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
+{
+ return static_branch_unlikely(&brcmnand_soc_has_ops_key);
+}
+
static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)
{
+ if (brcmnand_non_mmio_ops(ctrl))
+ return brcmnand_soc_read(ctrl->soc, offs);
return brcmnand_readl(ctrl->nand_base + offs);
}
static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs,
u32 val)
{
- brcmnand_writel(val, ctrl->nand_base + offs);
+ if (brcmnand_non_mmio_ops(ctrl))
+ brcmnand_soc_write(ctrl->soc, val, offs);
+ else
+ brcmnand_writel(val, ctrl->nand_base + offs);
}
static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
@@ -766,13 +779,18 @@ static inline void brcmnand_rmw_reg(stru
static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word)
{
+ if (brcmnand_non_mmio_ops(ctrl))
+ return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR);
return __raw_readl(ctrl->nand_fc + word * 4);
}
static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl,
int word, u32 val)
{
- __raw_writel(val, ctrl->nand_fc + word * 4);
+ if (brcmnand_non_mmio_ops(ctrl))
+ brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR);
+ else
+ __raw_writel(val, ctrl->nand_fc + word * 4);
}
static inline void edu_writel(struct brcmnand_controller *ctrl,
@@ -3000,6 +3018,12 @@ int brcmnand_probe(struct platform_devic
ctrl->dev = dev;
ctrl->soc = soc;
+ /* Enable the static key if the soc provides I/O operations indicating
+ * that a non-memory mapped IO access path must be used
+ */
+ if (brcmnand_soc_has_ops(ctrl->soc))
+ static_branch_enable(&brcmnand_soc_has_ops_key);
+
init_completion(&ctrl->done);
init_completion(&ctrl->dma_done);
init_completion(&ctrl->edu_done);
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -11,12 +11,25 @@
struct platform_device;
struct dev_pm_ops;
+struct brcmnand_io_ops;
+
+/* Special register offset constant to intercept a non-MMIO access
+ * to the flash cache register space. This is intentionally large
+ * not to overlap with an existing offset.
+ */
+#define BRCMNAND_NON_MMIO_FC_ADDR 0xffffffff
struct brcmnand_soc {
bool (*ctlrdy_ack)(struct brcmnand_soc *soc);
void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
bool is_param);
+ const struct brcmnand_io_ops *ops;
+};
+
+struct brcmnand_io_ops {
+ u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset);
+ void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset);
};
static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc,
@@ -58,6 +71,22 @@ static inline void brcmnand_writel(u32 v
writel_relaxed(val, addr);
}
+static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc)
+{
+ return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg;
+}
+
+static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset)
+{
+ return soc->ops->read_reg(soc, offset);
+}
+
+static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val,
+ u32 offset)
+{
+ soc->ops->write_reg(soc, val, offset);
+}
+
int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc);
int brcmnand_remove(struct platform_device *pdev);

View File

@ -0,0 +1,52 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 3/9] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs()
Date: Fri, 07 Jan 2022 10:46:08 -0800
Content-Type: text/plain; charset="utf-8"
In preparation for encapsulating more of what the loop calling
brcmnand_init_cs() does, avoid using platform_device when it is the
device behind platform_device that we are using for printing errors.
No functional changes introduced.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2771,7 +2771,7 @@ static const struct nand_controller_ops
static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
{
struct brcmnand_controller *ctrl = host->ctrl;
- struct platform_device *pdev = host->pdev;
+ struct device *dev = ctrl->dev;
struct mtd_info *mtd;
struct nand_chip *chip;
int ret;
@@ -2779,7 +2779,7 @@ static int brcmnand_init_cs(struct brcmn
ret = of_property_read_u32(dn, "reg", &host->cs);
if (ret) {
- dev_err(&pdev->dev, "can't get chip-select\n");
+ dev_err(dev, "can't get chip-select\n");
return -ENXIO;
}
@@ -2788,13 +2788,13 @@ static int brcmnand_init_cs(struct brcmn
nand_set_flash_node(chip, dn);
nand_set_controller_data(chip, host);
- mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d",
+ mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d",
host->cs);
if (!mtd->name)
return -ENOMEM;
mtd->owner = THIS_MODULE;
- mtd->dev.parent = &pdev->dev;
+ mtd->dev.parent = dev;
chip->legacy.cmd_ctrl = brcmnand_cmd_ctrl;
chip->legacy.cmdfunc = brcmnand_cmdfunc;

View File

@ -0,0 +1,63 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 4/9] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs()
Date: Fri, 07 Jan 2022 10:46:09 -0800
Content-Type: text/plain; charset="utf-8"
In order to initialize a given chip select object for use by the
brcmnand driver, move all of the Device Tree specific routines outside
of brcmnand_init_cs() in order to make it usable in a platform data
configuration which will be necessary for supporting BCMA chips.
No functional changes introduced.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2768,7 +2768,7 @@ static const struct nand_controller_ops
.attach_chip = brcmnand_attach_chip,
};
-static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
+static int brcmnand_init_cs(struct brcmnand_host *host)
{
struct brcmnand_controller *ctrl = host->ctrl;
struct device *dev = ctrl->dev;
@@ -2777,16 +2777,9 @@ static int brcmnand_init_cs(struct brcmn
int ret;
u16 cfg_offs;
- ret = of_property_read_u32(dn, "reg", &host->cs);
- if (ret) {
- dev_err(dev, "can't get chip-select\n");
- return -ENXIO;
- }
-
mtd = nand_to_mtd(&host->chip);
chip = &host->chip;
- nand_set_flash_node(chip, dn);
nand_set_controller_data(chip, host);
mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d",
host->cs);
@@ -3193,7 +3186,16 @@ int brcmnand_probe(struct platform_devic
host->pdev = pdev;
host->ctrl = ctrl;
- ret = brcmnand_init_cs(host, child);
+ ret = of_property_read_u32(child, "reg", &host->cs);
+ if (ret) {
+ dev_err(dev, "can't get chip-select\n");
+ devm_kfree(dev, host);
+ continue;
+ }
+
+ nand_set_flash_node(&host->chip, child);
+
+ ret = brcmnand_init_cs(host);
if (ret) {
devm_kfree(dev, host);
continue; /* Try all chip-selects */

View File

@ -0,0 +1,91 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 5/9] mtd: rawnand: brcmnand: Allow working without interrupts
Date: Fri, 07 Jan 2022 10:46:10 -0800
Content-Type: text/plain; charset="utf-8"
The BCMA devices include the brcmnand controller but they do not wire up
any interrupt line, allow the main interrupt to be optional and update
the completion path to also check for the lack of an interrupt line.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 52 +++++++++++-------------
1 file changed, 24 insertions(+), 28 deletions(-)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -216,7 +216,7 @@ struct brcmnand_controller {
void __iomem *nand_base;
void __iomem *nand_fc; /* flash cache */
void __iomem *flash_dma_base;
- unsigned int irq;
+ int irq;
unsigned int dma_irq;
int nand_version;
@@ -1610,7 +1610,7 @@ static bool brcmstb_nand_wait_for_comple
bool err = false;
int sts;
- if (mtd->oops_panic_write) {
+ if (mtd->oops_panic_write || ctrl->irq < 0) {
/* switch to interrupt polling and PIO mode */
disable_ctrl_irqs(ctrl);
sts = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY,
@@ -3144,33 +3144,29 @@ int brcmnand_probe(struct platform_devic
}
/* IRQ */
- ctrl->irq = platform_get_irq(pdev, 0);
- if ((int)ctrl->irq < 0) {
- dev_err(dev, "no IRQ defined\n");
- ret = -ENODEV;
- goto err;
- }
-
- /*
- * Some SoCs integrate this controller (e.g., its interrupt bits) in
- * interesting ways
- */
- if (soc) {
- ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
- DRV_NAME, ctrl);
-
- /* Enable interrupt */
- ctrl->soc->ctlrdy_ack(ctrl->soc);
- ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
- } else {
- /* Use standard interrupt infrastructure */
- ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
- DRV_NAME, ctrl);
- }
- if (ret < 0) {
- dev_err(dev, "can't allocate IRQ %d: error %d\n",
- ctrl->irq, ret);
- goto err;
+ ctrl->irq = platform_get_irq_optional(pdev, 0);
+ if (ctrl->irq > 0) {
+ /*
+ * Some SoCs integrate this controller (e.g., its interrupt bits) in
+ * interesting ways
+ */
+ if (soc) {
+ ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
+ DRV_NAME, ctrl);
+
+ /* Enable interrupt */
+ ctrl->soc->ctlrdy_ack(ctrl->soc);
+ ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
+ } else {
+ /* Use standard interrupt infrastructure */
+ ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
+ DRV_NAME, ctrl);
+ }
+ if (ret < 0) {
+ dev_err(dev, "can't allocate IRQ %d: error %d\n",
+ ctrl->irq, ret);
+ goto err;
+ }
}
for_each_available_child_of_node(dn, child) {

View File

@ -0,0 +1,115 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 6/9] mtd: rawnand: brcmnand: Add platform data structure for BCMA
Date: Fri, 07 Jan 2022 10:46:11 -0800
Content-Type: text/plain; charset="utf-8"
Update the BCMA's chipcommon nand flash driver to detect which
chip-select is used and pass that information via platform data to the
brcmnand driver. Make sure that the brcmnand platform data structure is
always at the beginning of the platform data of the "nflash" device
created by BCMA to allow brcmnand to safely de-reference it.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
MAINTAINERS | 1 +
drivers/bcma/driver_chipcommon_nflash.c | 20 +++++++++++++++++++-
include/linux/bcma/bcma_driver_chipcommon.h | 5 +++++
include/linux/platform_data/brcmnand.h | 12 ++++++++++++
4 files changed, 37 insertions(+), 1 deletion(-)
create mode 100644 include/linux/platform_data/brcmnand.h
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3900,6 +3900,7 @@ L: linux-mtd@lists.infradead.org
L: bcm-kernel-feedback-list@broadcom.com
S: Maintained
F: drivers/mtd/nand/raw/brcmnand/
+F: include/linux/platform_data/brcmnand.h
BROADCOM STB PCIE DRIVER
M: Jim Quinlan <jim2101024@gmail.com>
--- a/drivers/bcma/driver_chipcommon_nflash.c
+++ b/drivers/bcma/driver_chipcommon_nflash.c
@@ -7,18 +7,28 @@
#include "bcma_private.h"
+#include <linux/bitops.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/brcmnand.h>
#include <linux/bcma/bcma.h>
+/* Alternate NAND controller driver name in order to allow both bcm47xxnflash
+ * and bcma_brcmnand to be built into the same kernel image.
+ */
+static const char *bcma_nflash_alt_name = "bcma_brcmnand";
+
struct platform_device bcma_nflash_dev = {
.name = "bcma_nflash",
.num_resources = 0,
};
+static const char *probes[] = { "bcm47xxpart", NULL };
+
/* Initialize NAND flash access */
int bcma_nflash_init(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
+ u32 reg;
if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
cc->core->id.rev != 38) {
@@ -33,8 +43,16 @@ int bcma_nflash_init(struct bcma_drv_cc
cc->nflash.present = true;
if (cc->core->id.rev == 38 &&
- (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT))
+ (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) {
cc->nflash.boot = true;
+ /* Determine the chip select that is being used */
+ reg = bcma_cc_read32(cc, BCMA_CC_NAND_CS_NAND_SELECT) & 0xff;
+ cc->nflash.brcmnand_info.chip_select = ffs(reg) - 1;
+ cc->nflash.brcmnand_info.part_probe_types = probes;
+ cc->nflash.brcmnand_info.ecc_stepsize = 512;
+ cc->nflash.brcmnand_info.ecc_strength = 1;
+ bcma_nflash_dev.name = bcma_nflash_alt_name;
+ }
/* Prepare platform device, but don't register it yet. It's too early,
* malloc (required by device_private_init) is not available yet. */
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -3,6 +3,7 @@
#define LINUX_BCMA_DRIVER_CC_H_
#include <linux/platform_device.h>
+#include <linux/platform_data/brcmnand.h>
#include <linux/gpio.h>
/** ChipCommon core registers. **/
@@ -599,6 +600,10 @@ struct bcma_sflash {
#ifdef CONFIG_BCMA_NFLASH
struct bcma_nflash {
+ /* Must be the fist member for the brcmnand driver to
+ * de-reference that structure.
+ */
+ struct brcmnand_platform_data brcmnand_info;
bool present;
bool boot; /* This is the flash the SoC boots from */
};
--- /dev/null
+++ b/include/linux/platform_data/brcmnand.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef BRCMNAND_PLAT_DATA_H
+#define BRCMNAND_PLAT_DATA_H
+
+struct brcmnand_platform_data {
+ int chip_select;
+ const char * const *part_probe_types;
+ unsigned int ecc_stepsize;
+ unsigned int ecc_strength;
+};
+
+#endif /* BRCMNAND_PLAT_DATA_H */

View File

@ -0,0 +1,124 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 7/9] mtd: rawnand: brcmnand: Allow platform data instantation
Date: Fri, 07 Jan 2022 10:46:12 -0800
Content-Type: text/plain; charset="utf-8"
Make use of the recently refactored code in brcmnand_init_cs() and
derive the chip-select from the platform data that is supplied. Update
the various code paths to avoid relying on possibly non-existent
resources, too.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 45 ++++++++++++++++++------
1 file changed, 35 insertions(+), 10 deletions(-)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/brcmnand.h>
#include <linux/err.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
@@ -2768,7 +2769,8 @@ static const struct nand_controller_ops
.attach_chip = brcmnand_attach_chip,
};
-static int brcmnand_init_cs(struct brcmnand_host *host)
+static int brcmnand_init_cs(struct brcmnand_host *host,
+ const char * const *part_probe_types)
{
struct brcmnand_controller *ctrl = host->ctrl;
struct device *dev = ctrl->dev;
@@ -2821,7 +2823,7 @@ static int brcmnand_init_cs(struct brcmn
if (ret)
return ret;
- ret = mtd_device_register(mtd, NULL, 0);
+ ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0);
if (ret)
nand_cleanup(chip);
@@ -2990,17 +2992,15 @@ static int brcmnand_edu_setup(struct pla
int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
{
+ struct brcmnand_platform_data *pd = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev;
struct device_node *dn = dev->of_node, *child;
struct brcmnand_controller *ctrl;
+ struct brcmnand_host *host;
struct resource *res;
int ret;
- /* We only support device-tree instantiation */
- if (!dn)
- return -ENODEV;
-
- if (!of_match_node(brcmnand_of_match, dn))
+ if (dn && !of_match_node(brcmnand_of_match, dn))
return -ENODEV;
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
@@ -3027,7 +3027,7 @@ int brcmnand_probe(struct platform_devic
/* NAND register range */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ctrl->nand_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(ctrl->nand_base))
+ if (IS_ERR(ctrl->nand_base) && !brcmnand_soc_has_ops(soc))
return PTR_ERR(ctrl->nand_base);
/* Enable clock before using NAND registers */
@@ -3171,7 +3171,6 @@ int brcmnand_probe(struct platform_devic
for_each_available_child_of_node(dn, child) {
if (of_device_is_compatible(child, "brcm,nandcs")) {
- struct brcmnand_host *host;
host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
if (!host) {
@@ -3191,7 +3190,7 @@ int brcmnand_probe(struct platform_devic
nand_set_flash_node(&host->chip, child);
- ret = brcmnand_init_cs(host);
+ ret = brcmnand_init_cs(host, NULL);
if (ret) {
devm_kfree(dev, host);
continue; /* Try all chip-selects */
@@ -3201,6 +3200,32 @@ int brcmnand_probe(struct platform_devic
}
}
+ if (!list_empty(&ctrl->host_list))
+ return 0;
+
+ if (!pd) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ /* If we got there we must have been probing via platform data */
+ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+ if (!host) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ host->pdev = pdev;
+ host->ctrl = ctrl;
+ host->cs = pd->chip_select;
+ host->chip.ecc.size = pd->ecc_stepsize;
+ host->chip.ecc.strength = pd->ecc_strength;
+
+ ret = brcmnand_init_cs(host, pd->part_probe_types);
+ if (ret)
+ goto err;
+
+ list_add_tail(&host->node, &ctrl->host_list);
+
/* No chip-selects could initialize properly */
if (list_empty(&ctrl->host_list)) {
ret = -ENODEV;

View File

@ -0,0 +1,29 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 8/9] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0
Date: Fri, 07 Jan 2022 10:46:13 -0800
Content-Type: text/plain; charset="utf-8"
For some odd and unexplained reason the BCMA NAND controller, albeit
revision 3.4 uses a command shift of 0 instead of 24 as it should be,
quirk that.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -916,6 +916,12 @@ static void brcmnand_wr_corr_thresh(stru
static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl)
{
+ /* Kludge for the BCMA-based NAND controller which does not actually
+ * shift the command
+ */
+ if (ctrl->nand_version == 0x0304 && brcmnand_non_mmio_ops(ctrl))
+ return 0;
+
if (ctrl->nand_version < 0x0602)
return 24;
return 0;

View File

@ -0,0 +1,201 @@
From: Florian Fainelli <f.fainelli@gmail.com>
Subject: [PATCH v3 9/9] mtd: rawnand: brcmnand: Add BCMA shim
Date: Fri, 07 Jan 2022 10:46:14 -0800
Content-Type: text/plain; charset="utf-8"
Add a BCMA shim to allow us to register the brcmnand driver using the
BCMA bus which provides indirect memory mapped access to SoC registers.
There are a number of registers that need to be byte swapped because
they are natively big endian, coming directly from the NAND chip, and
there is no bus interface unlike the iProc or STB platforms that
performs the byte swapping for us.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mtd/nand/raw/Kconfig | 13 +++
drivers/mtd/nand/raw/brcmnand/Makefile | 2 +
drivers/mtd/nand/raw/brcmnand/bcma_nand.c | 132 ++++++++++++++++++++++
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 +
4 files changed, 151 insertions(+)
create mode 100644 drivers/mtd/nand/raw/brcmnand/bcma_nand.c
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -208,6 +208,19 @@ config MTD_NAND_BRCMNAND
originally designed for Set-Top Box but is used on various BCM7xxx,
BCM3xxx, BCM63xxx, iProc/Cygnus and more.
+if MTD_NAND_BRCMNAND
+
+config MTD_NAND_BRCMNAND_BCMA
+ tristate "Broadcom BCMA NAND controller"
+ depends on BCMA_NFLASH
+ depends on BCMA
+ help
+ Enables the BRCMNAND controller over BCMA on BCM47186/BCM5358 SoCs.
+ The glue driver will take care of performing the low-level I/O
+ operations to interface the BRCMNAND controller over the BCMA bus.
+
+endif # MTD_NAND_BRCMNAND
+
config MTD_NAND_BCM47XXNFLASH
tristate "BCM4706 BCMA NAND controller"
depends on BCMA_NFLASH
--- a/drivers/mtd/nand/raw/brcmnand/Makefile
+++ b/drivers/mtd/nand/raw/brcmnand/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6
obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6368_nand.o
obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o
obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o
+
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMA) += bcma_nand.o
--- /dev/null
+++ b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright © 2021 Broadcom
+ */
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_driver_chipcommon.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "brcmnand.h"
+
+struct brcmnand_bcma_soc {
+ struct brcmnand_soc soc;
+ struct bcma_drv_cc *cc;
+};
+
+static inline bool brcmnand_bcma_needs_swapping(u32 offset)
+{
+ switch (offset) {
+ case BCMA_CC_NAND_SPARE_RD0:
+ case BCMA_CC_NAND_SPARE_RD4:
+ case BCMA_CC_NAND_SPARE_RD8:
+ case BCMA_CC_NAND_SPARE_RD12:
+ case BCMA_CC_NAND_SPARE_WR0:
+ case BCMA_CC_NAND_SPARE_WR4:
+ case BCMA_CC_NAND_SPARE_WR8:
+ case BCMA_CC_NAND_SPARE_WR12:
+ case BCMA_CC_NAND_DEVID:
+ case BCMA_CC_NAND_DEVID_X:
+ case BCMA_CC_NAND_SPARE_RD16:
+ case BCMA_CC_NAND_SPARE_RD20:
+ case BCMA_CC_NAND_SPARE_RD24:
+ case BCMA_CC_NAND_SPARE_RD28:
+ return true;
+ }
+
+ return false;
+}
+
+static inline struct brcmnand_bcma_soc *to_bcma_soc(struct brcmnand_soc *soc)
+{
+ return container_of(soc, struct brcmnand_bcma_soc, soc);
+}
+
+static u32 brcmnand_bcma_read_reg(struct brcmnand_soc *soc, u32 offset)
+{
+ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);
+ u32 val;
+
+ /* Offset into the NAND block and deal with the flash cache separately */
+ if (offset == BRCMNAND_NON_MMIO_FC_ADDR)
+ offset = BCMA_CC_NAND_CACHE_DATA;
+ else
+ offset += BCMA_CC_NAND_REVISION;
+
+ val = bcma_cc_read32(sc->cc, offset);
+
+ /* Swap if necessary */
+ if (brcmnand_bcma_needs_swapping(offset))
+ val = be32_to_cpu(val);
+ return val;
+}
+
+static void brcmnand_bcma_write_reg(struct brcmnand_soc *soc, u32 val,
+ u32 offset)
+{
+ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);
+
+ /* Offset into the NAND block */
+ if (offset == BRCMNAND_NON_MMIO_FC_ADDR)
+ offset = BCMA_CC_NAND_CACHE_DATA;
+ else
+ offset += BCMA_CC_NAND_REVISION;
+
+ /* Swap if necessary */
+ if (brcmnand_bcma_needs_swapping(offset))
+ val = cpu_to_be32(val);
+
+ bcma_cc_write32(sc->cc, offset, val);
+}
+
+static struct brcmnand_io_ops brcmnand_bcma_io_ops = {
+ .read_reg = brcmnand_bcma_read_reg,
+ .write_reg = brcmnand_bcma_write_reg,
+};
+
+static void brcmnand_bcma_prepare_data_bus(struct brcmnand_soc *soc, bool prepare,
+ bool is_param)
+{
+ struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);
+
+ /* Reset the cache address to ensure we are already accessing the
+ * beginning of a sub-page.
+ */
+ bcma_cc_write32(sc->cc, BCMA_CC_NAND_CACHE_ADDR, 0);
+}
+
+static int brcmnand_bcma_nand_probe(struct platform_device *pdev)
+{
+ struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
+ struct brcmnand_bcma_soc *soc;
+
+ soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
+ if (!soc)
+ return -ENOMEM;
+
+ soc->cc = container_of(nflash, struct bcma_drv_cc, nflash);
+ soc->soc.prepare_data_bus = brcmnand_bcma_prepare_data_bus;
+ soc->soc.ops = &brcmnand_bcma_io_ops;
+
+ if (soc->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
+ dev_err(&pdev->dev, "Use bcm47xxnflash for 4706!\n");
+ return -ENODEV;
+ }
+
+ return brcmnand_probe(pdev, &soc->soc);
+}
+
+static struct platform_driver brcmnand_bcma_nand_driver = {
+ .probe = brcmnand_bcma_nand_probe,
+ .remove = brcmnand_remove,
+ .driver = {
+ .name = "bcma_brcmnand",
+ .pm = &brcmnand_pm_ops,
+ }
+};
+module_platform_driver(brcmnand_bcma_nand_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Broadcom");
+MODULE_DESCRIPTION("NAND controller driver glue for BCMA chips");
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -598,7 +598,11 @@ enum {
static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
{
+#if IS_ENABLED(CONFIG_MTD_NAND_BRCMNAND_BCMA)
return static_branch_unlikely(&brcmnand_soc_has_ops_key);
+#else
+ return false;
+#endif
}
static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)

View File

@ -0,0 +1,484 @@
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -27,6 +27,38 @@
extern void (*r4k_blast_dcache)(void);
extern void (*r4k_blast_icache)(void);
+#if defined(CONFIG_BCM47XX) && !defined(CONFIG_CPU_MIPS32_R2)
+#include <asm/paccess.h>
+#include <linux/ssb/ssb.h>
+#define BCM4710_DUMMY_RREG() bcm4710_dummy_rreg()
+
+static inline unsigned long bcm4710_dummy_rreg(void)
+{
+ return *(volatile unsigned long *)(KSEG1ADDR(SSB_ENUM_BASE));
+}
+
+#define BCM4710_FILL_TLB(addr) bcm4710_fill_tlb((void *)(addr))
+
+static inline unsigned long bcm4710_fill_tlb(void *addr)
+{
+ return *(unsigned long *)addr;
+}
+
+#define BCM4710_PROTECTED_FILL_TLB(addr) bcm4710_protected_fill_tlb((void *)(addr))
+
+static inline void bcm4710_protected_fill_tlb(void *addr)
+{
+ unsigned long x;
+ get_dbe(x, (unsigned long *)addr);;
+}
+
+#else
+#define BCM4710_DUMMY_RREG()
+
+#define BCM4710_FILL_TLB(addr)
+#define BCM4710_PROTECTED_FILL_TLB(addr)
+#endif
+
/*
* This macro return a properly sign-extended address suitable as base address
* for indexed cache operations. Two issues here:
@@ -60,6 +92,7 @@ static inline void flush_icache_line_ind
static inline void flush_dcache_line_indexed(unsigned long addr)
{
+ BCM4710_DUMMY_RREG();
cache_op(Index_Writeback_Inv_D, addr);
}
@@ -83,11 +116,13 @@ static inline void flush_icache_line(uns
static inline void flush_dcache_line(unsigned long addr)
{
+ BCM4710_DUMMY_RREG();
cache_op(Hit_Writeback_Inv_D, addr);
}
static inline void invalidate_dcache_line(unsigned long addr)
{
+ BCM4710_DUMMY_RREG();
cache_op(Hit_Invalidate_D, addr);
}
@@ -160,6 +195,7 @@ static inline int protected_flush_icache
return protected_cache_op(Hit_Invalidate_I_Loongson2, addr);
default:
+ BCM4710_DUMMY_RREG();
return protected_cache_op(Hit_Invalidate_I, addr);
}
}
@@ -172,6 +208,7 @@ static inline int protected_flush_icache
*/
static inline int protected_writeback_dcache_line(unsigned long addr)
{
+ BCM4710_DUMMY_RREG();
return protected_cache_op(Hit_Writeback_Inv_D, addr);
}
@@ -193,8 +230,51 @@ static inline void invalidate_tcache_pag
unroll(times, _cache_op, insn, op, (addr) + (i++ * (lsize))); \
} while (0)
+static inline void blast_dcache(void)
+{
+ unsigned long start = KSEG0;
+ unsigned long dcache_size = current_cpu_data.dcache.waysize * current_cpu_data.dcache.ways;
+ unsigned long end = (start + dcache_size);
+
+ do {
+ BCM4710_DUMMY_RREG();
+ cache_op(Index_Writeback_Inv_D, start);
+ start += current_cpu_data.dcache.linesz;
+ } while(start < end);
+}
+
+static inline void blast_dcache_page(unsigned long page)
+{
+ unsigned long start = page;
+ unsigned long end = start + PAGE_SIZE;
+
+ BCM4710_FILL_TLB(start);
+ do {
+ BCM4710_DUMMY_RREG();
+ cache_op(Hit_Writeback_Inv_D, start);
+ start += current_cpu_data.dcache.linesz;
+ } while(start < end);
+}
+
+static inline void blast_dcache_page_indexed(unsigned long page)
+{
+ unsigned long start = page;
+ unsigned long end = start + PAGE_SIZE;
+ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
+ unsigned long ws_end = current_cpu_data.dcache.ways <<
+ current_cpu_data.dcache.waybit;
+ unsigned long ws, addr;
+ for (ws = 0; ws < ws_end; ws += ws_inc) {
+ start = page + ws;
+ for (addr = start; addr < end; addr += current_cpu_data.dcache.linesz) {
+ BCM4710_DUMMY_RREG();
+ cache_op(Index_Writeback_Inv_D, addr);
+ }
+ }
+}
+
/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
-#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra) \
+#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra, war) \
static inline void extra##blast_##pfx##cache##lsize(void) \
{ \
unsigned long start = INDEX_BASE; \
@@ -204,6 +284,7 @@ static inline void extra##blast_##pfx##c
current_cpu_data.desc.waybit; \
unsigned long ws, addr; \
\
+ war \
for (ws = 0; ws < ws_end; ws += ws_inc) \
for (addr = start; addr < end; addr += lsize * 32) \
cache_unroll(32, kernel_cache, indexop, \
@@ -215,6 +296,7 @@ static inline void extra##blast_##pfx##c
unsigned long start = page; \
unsigned long end = page + PAGE_SIZE; \
\
+ war \
do { \
cache_unroll(32, kernel_cache, hitop, start, lsize); \
start += lsize * 32; \
@@ -231,32 +313,33 @@ static inline void extra##blast_##pfx##c
current_cpu_data.desc.waybit; \
unsigned long ws, addr; \
\
+ war \
for (ws = 0; ws < ws_end; ws += ws_inc) \
for (addr = start; addr < end; addr += lsize * 32) \
cache_unroll(32, kernel_cache, indexop, \
addr | ws, lsize); \
}
-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, )
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, )
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, )
-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, )
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, )
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_)
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, )
-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, )
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, )
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, )
-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, )
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, )
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, )
-
-__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, )
-__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, )
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, )
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, )
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, )
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, )
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, , )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, , BCM4710_FILL_TLB(start);)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, , )
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, , )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, , BCM4710_FILL_TLB(start);)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_, BCM4710_FILL_TLB(start);)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, , )
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, , )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, , BCM4710_FILL_TLB(start);)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, , )
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, , )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, , )
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, , )
+
+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, , )
+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, , )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, , )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, , )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, , )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, , )
#define __BUILD_BLAST_USER_CACHE(pfx, desc, indexop, hitop, lsize) \
static inline void blast_##pfx##cache##lsize##_user_page(unsigned long page) \
@@ -281,65 +364,36 @@ __BUILD_BLAST_USER_CACHE(d, dcache, Inde
__BUILD_BLAST_USER_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
/* build blast_xxx_range, protected_blast_xxx_range */
-#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra) \
+#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra, war, war2) \
static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, \
unsigned long end) \
{ \
unsigned long lsize = cpu_##desc##_line_size(); \
- unsigned long lsize_2 = lsize * 2; \
- unsigned long lsize_3 = lsize * 3; \
- unsigned long lsize_4 = lsize * 4; \
- unsigned long lsize_5 = lsize * 5; \
- unsigned long lsize_6 = lsize * 6; \
- unsigned long lsize_7 = lsize * 7; \
- unsigned long lsize_8 = lsize * 8; \
unsigned long addr = start & ~(lsize - 1); \
- unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \
- int lines = (aend - addr) / lsize; \
- \
- while (lines >= 8) { \
- prot##cache_op(hitop, addr); \
- prot##cache_op(hitop, addr + lsize); \
- prot##cache_op(hitop, addr + lsize_2); \
- prot##cache_op(hitop, addr + lsize_3); \
- prot##cache_op(hitop, addr + lsize_4); \
- prot##cache_op(hitop, addr + lsize_5); \
- prot##cache_op(hitop, addr + lsize_6); \
- prot##cache_op(hitop, addr + lsize_7); \
- addr += lsize_8; \
- lines -= 8; \
- } \
+ unsigned long aend = (end - 1) & ~(lsize - 1); \
\
- if (lines & 0x4) { \
- prot##cache_op(hitop, addr); \
- prot##cache_op(hitop, addr + lsize); \
- prot##cache_op(hitop, addr + lsize_2); \
- prot##cache_op(hitop, addr + lsize_3); \
- addr += lsize_4; \
- } \
- \
- if (lines & 0x2) { \
- prot##cache_op(hitop, addr); \
- prot##cache_op(hitop, addr + lsize); \
- addr += lsize_2; \
- } \
+ war \
\
- if (lines & 0x1) { \
+ while (1) { \
+ war2 \
prot##cache_op(hitop, addr); \
+ if (addr == aend) \
+ break; \
+ addr += lsize; \
} \
}
-__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, )
-__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, )
-__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, )
+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, , BCM4710_PROTECTED_FILL_TLB(addr); BCM4710_PROTECTED_FILL_TLB(aend);, BCM4710_DUMMY_RREG();)
+__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, , , )
+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, , , )
__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I_Loongson2, \
- protected_, loongson2_)
-__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , )
-__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, , )
-__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , )
+ protected_, loongson2_, , )
+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , , BCM4710_FILL_TLB(addr); BCM4710_FILL_TLB(aend);, BCM4710_DUMMY_RREG();)
+__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, , , , )
+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , , , )
/* blast_inv_dcache_range */
-__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , )
-__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , )
+__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , , , BCM4710_DUMMY_RREG();)
+__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , , , )
/* Currently, this is very specific to Loongson-3 */
#define __BUILD_BLAST_CACHE_NODE(pfx, desc, indexop, hitop, lsize) \
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -429,6 +429,10 @@
#else
.set push
.set arch=r4000
+#ifdef CONFIG_BCM47XX
+ nop
+ nop
+#endif
eret
.set pop
#endif
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -22,6 +22,19 @@
#include <asm/war.h>
#include <asm/thread_info.h>
+#ifdef CONFIG_BCM47XX
+# ifdef eret
+# undef eret
+# endif
+# define eret \
+ .set push; \
+ .set noreorder; \
+ nop; \
+ nop; \
+ eret; \
+ .set pop;
+#endif
+
__INIT
/*
@@ -33,6 +46,9 @@
NESTED(except_vec3_generic, 0, sp)
.set push
.set noat
+#ifdef CONFIG_BCM47XX
+ nop
+#endif
mfc0 k1, CP0_CAUSE
andi k1, k1, 0x7c
#ifdef CONFIG_64BIT
@@ -53,6 +69,9 @@ NESTED(except_vec3_r4000, 0, sp)
.set push
.set arch=r4000
.set noat
+#ifdef CONFIG_BCM47XX
+ nop
+#endif
mfc0 k1, CP0_CAUSE
li k0, 31<<2
andi k1, k1, 0x7c
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -38,6 +38,9 @@
#include <asm/traps.h>
#include <asm/mips-cps.h>
+/* For enabling BCM4710 cache workarounds */
+static int bcm4710 = 0;
+
/*
* Bits describing what cache ops an SMP callback function may perform.
*
@@ -190,6 +193,9 @@ static void r4k_blast_dcache_user_page_s
{
unsigned long dc_lsize = cpu_dcache_line_size();
+ if (bcm4710)
+ r4k_blast_dcache_page = blast_dcache_page;
+ else
if (dc_lsize == 0)
r4k_blast_dcache_user_page = (void *)cache_noop;
else if (dc_lsize == 16)
@@ -208,6 +214,9 @@ static void r4k_blast_dcache_page_indexe
{
unsigned long dc_lsize = cpu_dcache_line_size();
+ if (bcm4710)
+ r4k_blast_dcache_page_indexed = blast_dcache_page_indexed;
+ else
if (dc_lsize == 0)
r4k_blast_dcache_page_indexed = (void *)cache_noop;
else if (dc_lsize == 16)
@@ -227,6 +236,9 @@ static void r4k_blast_dcache_setup(void)
{
unsigned long dc_lsize = cpu_dcache_line_size();
+ if (bcm4710)
+ r4k_blast_dcache = blast_dcache;
+ else
if (dc_lsize == 0)
r4k_blast_dcache = (void *)cache_noop;
else if (dc_lsize == 16)
@@ -1817,6 +1829,17 @@ static void coherency_setup(void)
* silly idea of putting something else there ...
*/
switch (current_cpu_type()) {
+ case CPU_BMIPS3300:
+ {
+ u32 cm;
+ cm = read_c0_diag();
+ /* Enable icache */
+ cm |= (1 << 31);
+ /* Enable dcache */
+ cm |= (1 << 30);
+ write_c0_diag(cm);
+ }
+ break;
case CPU_R4000PC:
case CPU_R4000SC:
case CPU_R4000MC:
@@ -1863,6 +1886,15 @@ void r4k_cache_init(void)
extern void build_copy_page(void);
struct cpuinfo_mips *c = &current_cpu_data;
+ /* Check if special workarounds are required */
+#if defined(CONFIG_BCM47XX) && !defined(CONFIG_CPU_MIPS32_R2)
+ if (current_cpu_data.cputype == CPU_BMIPS32 && (current_cpu_data.processor_id & 0xff) == 0) {
+ printk("Enabling BCM4710A0 cache workarounds.\n");
+ bcm4710 = 1;
+ } else
+#endif
+ bcm4710 = 0;
+
probe_pcache();
probe_vcache();
setup_scache();
@@ -1935,7 +1967,15 @@ void r4k_cache_init(void)
*/
local_r4k___flush_cache_all(NULL);
+#ifdef CONFIG_BCM47XX
+ {
+ static void (*_coherency_setup)(void);
+ _coherency_setup = (void (*)(void)) KSEG1ADDR(coherency_setup);
+ _coherency_setup();
+ }
+#else
coherency_setup();
+#endif
board_cache_error_setup = r4k_cache_error_setup;
/*
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -985,6 +985,9 @@ void build_get_pgde32(u32 **p, unsigned
uasm_i_srl(p, ptr, ptr, SMP_CPUID_PTRSHIFT);
uasm_i_addu(p, ptr, tmp, ptr);
#else
+#ifdef CONFIG_BCM47XX
+ uasm_i_nop(p);
+#endif
UASM_i_LA_mostly(p, ptr, pgdc);
#endif
uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
@@ -1347,6 +1350,9 @@ static void build_r4000_tlb_refill_handl
#ifdef CONFIG_64BIT
build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
#else
+# ifdef CONFIG_BCM47XX
+ uasm_i_nop(&p);
+# endif
build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
#endif
@@ -1358,6 +1364,9 @@ static void build_r4000_tlb_refill_handl
build_update_entries(&p, K0, K1);
build_tlb_write_entry(&p, &l, &r, tlb_random);
uasm_l_leave(&l, p);
+#ifdef CONFIG_BCM47XX
+ uasm_i_nop(&p);
+#endif
uasm_i_eret(&p); /* return from trap */
}
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
@@ -2059,6 +2068,9 @@ build_r4000_tlbchange_handler_head(u32 *
#ifdef CONFIG_64BIT
build_get_pmde64(p, l, r, wr.r1, wr.r2); /* get pmd in ptr */
#else
+# ifdef CONFIG_BCM47XX
+ uasm_i_nop(p);
+# endif
build_get_pgde32(p, wr.r1, wr.r2); /* get pgd in ptr */
#endif
@@ -2105,6 +2117,9 @@ build_r4000_tlbchange_handler_tail(u32 *
build_tlb_write_entry(p, l, r, tlb_indexed);
uasm_l_leave(l, *p);
build_restore_work_registers(p);
+#ifdef CONFIG_BCM47XX
+ uasm_i_nop(p);
+#endif
uasm_i_eret(p); /* return from trap */
#ifdef CONFIG_64BIT

View File

@ -0,0 +1,78 @@
From: Jeff Hansen <jhansen@cardaccess-inc.com>
Subject: [PATCH] kmap_coherent
On ASUS WL-500gP there are some "Data bus error"s when executing simple
commands liks "ps" or "cat /proc/1/cmdline".
This fixes OpenWrt ticket #1485: https://dev.openwrt.org/ticket/1485
---
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -240,6 +240,9 @@
#ifndef cpu_has_pindexed_dcache
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
#endif
+#ifndef cpu_use_kmap_coherent
+#define cpu_use_kmap_coherent 1
+#endif
/*
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
--- a/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
@@ -80,4 +80,6 @@
#define cpu_scache_line_size() 0
#define cpu_has_vz 0
+#define cpu_use_kmap_coherent 0
+
#endif /* __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H */
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -699,7 +699,7 @@ static inline void local_r4k_flush_cache
map_coherent = (cpu_has_dc_aliases &&
page_mapcount(page) &&
!Page_dcache_dirty(page));
- if (map_coherent)
+ if (map_coherent && cpu_use_kmap_coherent)
vaddr = kmap_coherent(page, addr);
else
vaddr = kmap_atomic(page);
@@ -721,7 +721,7 @@ static inline void local_r4k_flush_cache
}
if (vaddr) {
- if (map_coherent)
+ if (map_coherent && cpu_use_kmap_coherent)
kunmap_coherent();
else
kunmap_atomic(vaddr);
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -172,7 +172,7 @@ void copy_user_highpage(struct page *to,
void *vfrom, *vto;
vto = kmap_atomic(to);
- if (cpu_has_dc_aliases &&
+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
page_mapcount(from) && !Page_dcache_dirty(from)) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
@@ -194,7 +194,7 @@ void copy_to_user_page(struct vm_area_st
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (cpu_has_dc_aliases &&
+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
page_mapcount(page) && !Page_dcache_dirty(page)) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
@@ -212,7 +212,7 @@ void copy_from_user_page(struct vm_area_
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (cpu_has_dc_aliases &&
+ if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
page_mapcount(page) && !Page_dcache_dirty(page)) {
void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);

View File

@ -0,0 +1,121 @@
From b36f694256f41bc71571f467646d015dda128d14 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 9 Nov 2013 17:03:59 +0100
Subject: [PATCH 210/210] b44: register adm switch
---
drivers/net/ethernet/broadcom/b44.c | 57 +++++++++++++++++++++++++++++++++++
drivers/net/ethernet/broadcom/b44.h | 3 ++
2 files changed, 60 insertions(+)
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -31,6 +31,8 @@
#include <linux/ssb/ssb.h>
#include <linux/slab.h>
#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/adm6996-gpio.h>
#include <linux/uaccess.h>
#include <asm/io.h>
@@ -2243,6 +2245,69 @@ static void b44_adjust_link(struct net_d
}
}
+#ifdef CONFIG_BCM47XX
+static int b44_register_adm_switch(struct b44 *bp)
+{
+ int gpio;
+ struct platform_device *pdev;
+ struct adm6996_gpio_platform_data adm_data = {0};
+ struct platform_device_info info = {0};
+
+ adm_data.model = ADM6996L;
+ gpio = bcm47xx_nvram_gpio_pin("adm_eecs");
+ if (gpio >= 0)
+ adm_data.eecs = gpio;
+ else
+ adm_data.eecs = 2;
+
+ gpio = bcm47xx_nvram_gpio_pin("adm_eesk");
+ if (gpio >= 0)
+ adm_data.eesk = gpio;
+ else
+ adm_data.eesk = 3;
+
+ gpio = bcm47xx_nvram_gpio_pin("adm_eedi");
+ if (gpio >= 0)
+ adm_data.eedi = gpio;
+ else
+ adm_data.eedi = 4;
+
+ /*
+ * We ignore the "adm_rc" GPIO here. The driver does not use it,
+ * and it conflicts with the Reset button GPIO on the Linksys WRT54GSv1.
+ */
+
+ info.parent = bp->sdev->dev;
+ info.name = "adm6996_gpio";
+ info.id = -1;
+ info.data = &adm_data;
+ info.size_data = sizeof(adm_data);
+
+ if (!bp->adm_switch) {
+ pdev = platform_device_register_full(&info);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ bp->adm_switch = pdev;
+ }
+ return 0;
+}
+static void b44_unregister_adm_switch(struct b44 *bp)
+{
+ if (bp->adm_switch)
+ platform_device_unregister(bp->adm_switch);
+}
+#else
+static int b44_register_adm_switch(struct b44 *bp)
+{
+ return 0;
+}
+static void b44_unregister_adm_switch(struct b44 *bp)
+{
+
+}
+#endif /* CONFIG_BCM47XX */
+
static int b44_register_phy_one(struct b44 *bp)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
@@ -2279,6 +2344,9 @@ static int b44_register_phy_one(struct b
if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
(sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
+ if (sprom->boardflags_lo & B44_BOARDFLAG_ADM)
+ b44_register_adm_switch(bp);
+
dev_info(sdev->dev,
"could not find PHY at %i, use fixed one\n",
bp->phy_addr);
@@ -2473,6 +2541,7 @@ static void b44_remove_one(struct ssb_de
unregister_netdev(dev);
if (bp->flags & B44_FLAG_EXTERNAL_PHY)
b44_unregister_phy_one(bp);
+ b44_unregister_adm_switch(bp);
ssb_device_disable(sdev, 0);
ssb_bus_may_powerdown(sdev->bus);
netif_napi_del(&bp->napi);
--- a/drivers/net/ethernet/broadcom/b44.h
+++ b/drivers/net/ethernet/broadcom/b44.h
@@ -408,6 +408,9 @@ struct b44 {
struct mii_bus *mii_bus;
int old_link;
struct mii_if_info mii_if;
+
+ /* platform device for associated switch */
+ struct platform_device *adm_switch;
};
#endif /* _B44_H */

View File

@ -0,0 +1,54 @@
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -429,10 +429,34 @@ static void b44_wap54g10_workaround(stru
error:
pr_warn("PHY: cannot reset MII transceiver isolate bit\n");
}
+
+static void b44_bcm47xx_workarounds(struct b44 *bp)
+{
+ char buf[20];
+ struct ssb_device *sdev = bp->sdev;
+
+ /* Toshiba WRC-1000, Siemens SE505 v1, Askey RT-210W, RT-220W */
+ if (sdev->bus->sprom.board_num == 100) {
+ bp->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY;
+ } else {
+ /* WL-HDD */
+ if (bcm47xx_nvram_getenv("hardware_version", buf, sizeof(buf)) >= 0 &&
+ !strncmp(buf, "WL300-", strlen("WL300-"))) {
+ if (sdev->bus->sprom.et0phyaddr == 0 &&
+ sdev->bus->sprom.et1phyaddr == 1)
+ bp->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY;
+ }
+ }
+ return;
+}
#else
static inline void b44_wap54g10_workaround(struct b44 *bp)
{
}
+
+static inline void b44_bcm47xx_workarounds(struct b44 *bp)
+{
+}
#endif
static int b44_setup_phy(struct b44 *bp)
@@ -441,6 +465,7 @@ static int b44_setup_phy(struct b44 *bp)
int err;
b44_wap54g10_workaround(bp);
+ b44_bcm47xx_workarounds(bp);
if (bp->flags & B44_FLAG_EXTERNAL_PHY)
return 0;
@@ -2173,6 +2198,8 @@ static int b44_get_invariants(struct b44
* valid PHY address. */
bp->phy_addr &= 0x1F;
+ b44_bcm47xx_workarounds(bp);
+
memcpy(bp->dev->dev_addr, addr, ETH_ALEN);
if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){

View File

@ -0,0 +1,25 @@
This prevents the options from being delete with make kernel_oldconfig.
---
drivers/ssb/Kconfig | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -32,6 +32,7 @@ config BCMA_HOST_PCI
config BCMA_HOST_SOC
bool "Support for BCMA in a SoC"
depends on HAS_IOMEM
+ select USB_HCD_BCMA if USB_EHCI_HCD || USB_OHCI_HCD
help
Host interface for a Broadcom AIX bus directly mapped into
the memory. This only works with the Broadcom SoCs from the
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -136,6 +136,7 @@ config SSB_SFLASH
config SSB_EMBEDDED
bool
depends on SSB_DRIVER_MIPS && SSB_PCICORE_HOSTMODE
+ select USB_HCD_SSB if USB_EHCI_HCD || USB_OHCI_HCD
default y
config SSB_DRIVER_EXTIF

View File

@ -0,0 +1,21 @@
From: Wolfram Joost <dbox2@frokaschwei.de>
Subject: [PATCH] fork_cacheflush
On ASUS WL-500gP there are many unexpected "Segmentation fault"s that
seem to be caused by a kernel. They can be avoided by:
1) Disabling highpage
2) Using flush_cache_mm in flush_cache_dup_mm
For details see OpenWrt ticket #2035 https://dev.openwrt.org/ticket/2035
---
--- a/arch/mips/include/asm/cacheflush.h
+++ b/arch/mips/include/asm/cacheflush.h
@@ -46,7 +46,7 @@
extern void (*flush_cache_all)(void);
extern void (*__flush_cache_all)(void);
extern void (*flush_cache_mm)(struct mm_struct *mm);
-#define flush_cache_dup_mm(mm) do { (void) (mm); } while (0)
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
extern void (*flush_cache_range)(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);

View File

@ -0,0 +1,74 @@
From: Jeff Hansen <jhansen@cardaccess-inc.com>
Subject: [PATCH] no highpage
On ASUS WL-500gP there are many unexpected "Segmentation fault"s that
seem to be caused by a kernel. They can be avoided by:
1) Disabling highpage
2) Using flush_cache_mm in flush_cache_dup_mm
For details see OpenWrt ticket #2035 https://dev.openwrt.org/ticket/2035
---
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -71,6 +71,7 @@ static inline unsigned int page_size_ftl
#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
#include <linux/pfn.h>
+#include <asm/cpu-features.h>
extern void build_clear_page(void);
extern void build_copy_page(void);
@@ -110,11 +111,16 @@ static inline void clear_user_page(void
flush_data_cache_page((unsigned long)addr);
}
-struct vm_area_struct;
-extern void copy_user_highpage(struct page *to, struct page *from,
- unsigned long vaddr, struct vm_area_struct *vma);
+static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+ struct page *to)
+{
+ extern void (*flush_data_cache_page)(unsigned long addr);
-#define __HAVE_ARCH_COPY_USER_HIGHPAGE
+ copy_page(vto, vfrom);
+ if (!cpu_has_ic_fills_f_dc ||
+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+ flush_data_cache_page((unsigned long)vto);
+}
/*
* These are used to make use of C type-checking..
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -166,30 +166,6 @@ void kunmap_coherent(void)
preempt_enable();
}
-void copy_user_highpage(struct page *to, struct page *from,
- unsigned long vaddr, struct vm_area_struct *vma)
-{
- void *vfrom, *vto;
-
- vto = kmap_atomic(to);
- if (cpu_has_dc_aliases && cpu_use_kmap_coherent &&
- page_mapcount(from) && !Page_dcache_dirty(from)) {
- vfrom = kmap_coherent(from, vaddr);
- copy_page(vto, vfrom);
- kunmap_coherent();
- } else {
- vfrom = kmap_atomic(from);
- copy_page(vto, vfrom);
- kunmap_atomic(vfrom);
- }
- if ((!cpu_has_ic_fills_f_dc) ||
- pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
- flush_data_cache_page((unsigned long)vto);
- kunmap_atomic(vto);
- /* Make sure this page is cleared on other CPU's too before using it */
- smp_wmb();
-}
-
void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)

View File

@ -0,0 +1,89 @@
From 3829e4f10a232964cc728c0479c8097922e5e073 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 6 Jan 2022 19:51:38 -0800
Subject: [PATCH] MIPS: BCM47XX: Add board entry for Linksys WRT320N v1
This router is based on a Broadcom BCM4717A1 chipset and supports
802.11n Wi-Fi. Add a board entry for that router and register LEDs and
buttons accordingly.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/bcm47xx/board.c | 1 +
arch/mips/bcm47xx/buttons.c | 9 +++++++++
arch/mips/bcm47xx/leds.c | 10 ++++++++++
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | 1 +
4 files changed, 21 insertions(+)
--- a/arch/mips/bcm47xx/board.c
+++ b/arch/mips/bcm47xx/board.c
@@ -141,6 +141,7 @@ struct bcm47xx_board_type_list2 bcm47xx_
{{BCM47XX_BOARD_LINKSYS_WRT300NV11, "Linksys WRT300N V1.1"}, "WRT300N", "1.1"},
{{BCM47XX_BOARD_LINKSYS_WRT310NV1, "Linksys WRT310N V1"}, "WRT310N", "1.0"},
{{BCM47XX_BOARD_LINKSYS_WRT310NV2, "Linksys WRT310N V2"}, "WRT310N", "2.0"},
+ {{BCM47XX_BOARD_LINKSYS_WRT320N_V1, "Linksys WRT320N V1"}, "WRT320N", "1.0"},
{{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"},
{{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"},
{{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"},
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -277,6 +277,12 @@ bcm47xx_buttons_linksys_wrt310nv1[] __in
};
static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt320n_v1[] __initconst = {
+ BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
+ BCM47XX_GPIO_KEY(8, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = {
BCM47XX_GPIO_KEY(5, KEY_WIMAX),
BCM47XX_GPIO_KEY(6, KEY_RESTART),
@@ -608,6 +614,9 @@ int __init bcm47xx_buttons_register(void
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
break;
+ case BCM47XX_BOARD_LINKSYS_WRT320N_V1:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt320n_v1);
+ break;
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2);
break;
--- a/arch/mips/bcm47xx/leds.c
+++ b/arch/mips/bcm47xx/leds.c
@@ -314,6 +314,13 @@ bcm47xx_leds_linksys_wrt310nv1[] __initc
};
static const struct gpio_led
+bcm47xx_leds_linksys_wrt320n_v1[] __initconst = {
+ BCM47XX_GPIO_LED(1, "blue", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(2, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(4, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
bcm47xx_leds_linksys_wrt54g_generic[] __initconst = {
BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
@@ -689,6 +696,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
break;
+ case BCM47XX_BOARD_LINKSYS_WRT320N_V1:
+ bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt320n_v1);
+ break;
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2);
break;
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
@@ -72,6 +72,7 @@ enum bcm47xx_board {
BCM47XX_BOARD_LINKSYS_WRT300NV11,
BCM47XX_BOARD_LINKSYS_WRT310NV1,
BCM47XX_BOARD_LINKSYS_WRT310NV2,
+ BCM47XX_BOARD_LINKSYS_WRT320N_V1,
BCM47XX_BOARD_LINKSYS_WRT54G3GV2,
BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101,
BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467,

View File

@ -0,0 +1,60 @@
From 15e690af5cc3cd8f5d14ee2aa3a093f80196110e Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 6 Jan 2022 19:51:40 -0800
Subject: [PATCH] MIPS: BCM47XX: Add support for Netgear R6300 v1
Add support for the Netgear R6300 v1 Wi-Fi router using a Broadcom
BCM4706 chipset and supporting 802.11n and 802.11ac.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/bcm47xx/board.c | 1 +
arch/mips/bcm47xx/buttons.c | 8 ++++++++
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | 1 +
3 files changed, 10 insertions(+)
--- a/arch/mips/bcm47xx/board.c
+++ b/arch/mips/bcm47xx/board.c
@@ -162,6 +162,7 @@ struct bcm47xx_board_type_list1 bcm47xx_
{{BCM47XX_BOARD_LUXUL_XWR_600_V1, "Luxul XWR-600 V1"}, "luxul_xwr600_v1"},
{{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"},
{{BCM47XX_BOARD_NETGEAR_R6200_V1, "Netgear R6200 V1"}, "U12H192T00_NETGEAR"},
+ {{BCM47XX_BOARD_NETGEAR_R6300_V1, "Netgear R6300 V1"}, "U12H218T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"},
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -398,6 +398,11 @@ bcm47xx_buttons_netgear_r6200_v1[] __ini
};
static const struct gpio_keys_button
+bcm47xx_buttons_netgear_r6300_v1[] __initconst = {
+ BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
BCM47XX_GPIO_KEY(4, KEY_RESTART),
BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
@@ -683,6 +688,9 @@ int __init bcm47xx_buttons_register(void
case BCM47XX_BOARD_NETGEAR_R6200_V1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_r6200_v1);
break;
+ case BCM47XX_BOARD_NETGEAR_R6300_V1:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_r6300_v1);
+ break;
case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
break;
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
@@ -100,6 +100,7 @@ enum bcm47xx_board {
BCM47XX_BOARD_MOTOROLA_WR850GV2V3,
BCM47XX_BOARD_NETGEAR_R6200_V1,
+ BCM47XX_BOARD_NETGEAR_R6300_V1,
BCM47XX_BOARD_NETGEAR_WGR614V8,
BCM47XX_BOARD_NETGEAR_WGR614V9,
BCM47XX_BOARD_NETGEAR_WGR614_V10,

View File

@ -0,0 +1,63 @@
From 4da27b6d550427a0560a15df36de99cb17629216 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 6 Jan 2022 19:51:41 -0800
Subject: [PATCH] MIPS: BCM47XX: Add support for Netgear WN2500RP v1 & v2
Add support for the Netgear WN2500 RP v1 and v2 Wi-Fi range extenders
based on the BCM5357 chipset and supporting 802.11n and 802.11ac.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/bcm47xx/board.c | 2 ++
arch/mips/bcm47xx/buttons.c | 9 +++++++++
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | 2 ++
3 files changed, 13 insertions(+)
--- a/arch/mips/bcm47xx/board.c
+++ b/arch/mips/bcm47xx/board.c
@@ -166,6 +166,8 @@ struct bcm47xx_board_type_list1 bcm47xx_
{{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"},
+ {{BCM47XX_BOARD_NETGEAR_WN2500RP_V1, "Netgear WN2500RP V1"}, "U12H197T00_NETGEAR"},
+ {{BCM47XX_BOARD_NETGEAR_WN2500RP_V2, "Netgear WN2500RP V2"}, "U12H294T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNDR3300, "Netgear WNDR3300"}, "U12H093T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNDR3400V1, "Netgear WNDR3400 V1"}, "U12H155T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNDR3400V2, "Netgear WNDR3400 V2"}, "U12H187T00_NETGEAR"},
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -403,6 +403,12 @@ bcm47xx_buttons_netgear_r6300_v1[] __ini
};
static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wn2500rp_v1[] __initconst = {
+ BCM47XX_GPIO_KEY(12, KEY_RESTART),
+ BCM47XX_GPIO_KEY(31, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
BCM47XX_GPIO_KEY(4, KEY_RESTART),
BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
@@ -691,6 +697,9 @@ int __init bcm47xx_buttons_register(void
case BCM47XX_BOARD_NETGEAR_R6300_V1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_r6300_v1);
break;
+ case BCM47XX_BOARD_NETGEAR_WN2500RP_V1:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wn2500rp_v1);
+ break;
case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
break;
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
@@ -104,6 +104,8 @@ enum bcm47xx_board {
BCM47XX_BOARD_NETGEAR_WGR614V8,
BCM47XX_BOARD_NETGEAR_WGR614V9,
BCM47XX_BOARD_NETGEAR_WGR614_V10,
+ BCM47XX_BOARD_NETGEAR_WN2500RP_V1,
+ BCM47XX_BOARD_NETGEAR_WN2500RP_V2,
BCM47XX_BOARD_NETGEAR_WNDR3300,
BCM47XX_BOARD_NETGEAR_WNDR3400V1,
BCM47XX_BOARD_NETGEAR_WNDR3400V2,

View File

@ -0,0 +1,109 @@
From c022e87162219d67d687df22c977d1c2fc95fb42 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 14 Jul 2022 14:13:01 -0700
Subject: [PATCH] MIPS: BCM47XX: Add support for Netgear WNR3500L v2
Add support for the Netgear WNR3500L v2 router based on the BCM47186
chipset and supporting 802.11n Wi-Fi.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/bcm47xx/board.c | 2 ++
arch/mips/bcm47xx/buttons.c | 10 ++++++++++
arch/mips/bcm47xx/leds.c | 11 +++++++++++
arch/mips/bcm47xx/workarounds.c | 1 +
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | 1 +
5 files changed, 25 insertions(+)
--- a/arch/mips/bcm47xx/board.c
+++ b/arch/mips/bcm47xx/board.c
@@ -181,6 +181,7 @@ struct bcm47xx_board_type_list1 bcm47xx_
{{BCM47XX_BOARD_NETGEAR_WNR1000_V3, "Netgear WNR1000 V3"}, "U12H139T50_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNR2000, "Netgear WNR2000"}, "U12H114T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "U12H136T99_NETGEAR"},
+ {{BCM47XX_BOARD_NETGEAR_WNR3500L_V2, "Netgear WNR3500L V2"}, "U12H172T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNR3500U, "Netgear WNR3500U"}, "U12H136T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"},
{{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"},
@@ -195,6 +196,7 @@ struct bcm47xx_board_type_list3 bcm47xx_
{{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
{{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
{{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"},
+ {{BCM47XX_BOARD_NETGEAR_WNR3500L_V2, "Netgear WNR3500L V2"}, "0x052b", "3500L", "02"},
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"},
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"},
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"},
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -448,6 +448,13 @@ bcm47xx_buttons_netgear_wnr3500lv1[] __i
};
static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wnr3500lv2[] __initconst = {
+ BCM47XX_GPIO_KEY(4, KEY_RESTART),
+ BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
+ BCM47XX_GPIO_KEY(8, KEY_RFKILL),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
BCM47XX_GPIO_KEY(6, KEY_RESTART),
};
@@ -718,6 +725,9 @@ int __init bcm47xx_buttons_register(void
case BCM47XX_BOARD_NETGEAR_WNR3500L:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv1);
break;
+ case BCM47XX_BOARD_NETGEAR_WNR3500L_V2:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv2);
+ break;
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
break;
--- a/arch/mips/bcm47xx/leds.c
+++ b/arch/mips/bcm47xx/leds.c
@@ -520,6 +520,14 @@ bcm47xx_leds_netgear_wnr3500lv1[] __init
};
static const struct gpio_led
+bcm47xx_leds_netgear_wnr3500lv2[] __initconst = {
+ BCM47XX_GPIO_LED(0, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(1, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
bcm47xx_leds_netgear_wnr834bv2[] __initconst = {
BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
@@ -780,6 +788,9 @@ void __init bcm47xx_leds_register(void)
case BCM47XX_BOARD_NETGEAR_WNR3500L:
bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv1);
break;
+ case BCM47XX_BOARD_NETGEAR_WNR3500L_V2:
+ bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv2);
+ break;
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
break;
--- a/arch/mips/bcm47xx/workarounds.c
+++ b/arch/mips/bcm47xx/workarounds.c
@@ -22,6 +22,7 @@ void __init bcm47xx_workarounds(void)
switch (board) {
case BCM47XX_BOARD_NETGEAR_WNR3500L:
+ case BCM47XX_BOARD_NETGEAR_WNR3500L_V2:
bcm47xx_workarounds_enable_usb_power(12);
break;
case BCM47XX_BOARD_NETGEAR_WNDR3400V2:
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
@@ -118,6 +118,7 @@ enum bcm47xx_board {
BCM47XX_BOARD_NETGEAR_WNR1000_V3,
BCM47XX_BOARD_NETGEAR_WNR2000,
BCM47XX_BOARD_NETGEAR_WNR3500L,
+ BCM47XX_BOARD_NETGEAR_WNR3500L_V2,
BCM47XX_BOARD_NETGEAR_WNR3500U,
BCM47XX_BOARD_NETGEAR_WNR3500V2,
BCM47XX_BOARD_NETGEAR_WNR3500V2VC,

View File

@ -0,0 +1,67 @@
From aecf89f2f8e8a604c33085c230a1f04ea325de64 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 6 Jan 2022 19:51:39 -0800
Subject: [PATCH] MIPS: BCM47XX: Add LEDs and buttons for Asus RTN-10U
Add the definitions for the buttons and LEDs used on the Asus RTN-10U
router.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/bcm47xx/buttons.c | 9 +++++++++
arch/mips/bcm47xx/leds.c | 11 +++++++++++
2 files changed, 20 insertions(+)
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -27,6 +27,12 @@
/* Asus */
static const struct gpio_keys_button
+bcm47xx_buttons_asus_rtn10u[] __initconst = {
+ BCM47XX_GPIO_KEY(20, KEY_WPS_BUTTON),
+ BCM47XX_GPIO_KEY(21, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_asus_rtn12[] __initconst = {
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
BCM47XX_GPIO_KEY(1, KEY_RESTART),
@@ -502,6 +508,9 @@ int __init bcm47xx_buttons_register(void
int err;
switch (board) {
+ case BCM47XX_BOARD_ASUS_RTN10U:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn10u);
+ break;
case BCM47XX_BOARD_ASUS_RTN12:
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn12);
break;
--- a/arch/mips/bcm47xx/leds.c
+++ b/arch/mips/bcm47xx/leds.c
@@ -30,6 +30,14 @@
/* Asus */
static const struct gpio_led
+bcm47xx_leds_asus_rtn10u[] __initconst = {
+ BCM47XX_GPIO_LED(5, "green", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(6, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+ BCM47XX_GPIO_LED(7, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
+ BCM47XX_GPIO_LED(8, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
bcm47xx_leds_asus_rtn12[] __initconst = {
BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
@@ -571,6 +579,9 @@ void __init bcm47xx_leds_register(void)
enum bcm47xx_board board = bcm47xx_board_get();
switch (board) {
+ case BCM47XX_BOARD_ASUS_RTN10U:
+ bcm47xx_set_pdata(bcm47xx_leds_asus_rtn10u);
+ break;
case BCM47XX_BOARD_ASUS_RTN12:
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12);
break;

View File

@ -0,0 +1,40 @@
From eea175eedf3e2f71b9538d21e643e7a1be4923df Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 6 Jan 2022 19:51:37 -0800
Subject: [PATCH] MIPS: BCM47XX: Define Linksys WRT310N V2 buttons
Update the buttons registration code to register the two buttons (WPS,
system rester) using the existing BCM47XX_BOARD_LINKSYS_WRT310NV2 board
entry.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/bcm47xx/buttons.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/arch/mips/bcm47xx/buttons.c
+++ b/arch/mips/bcm47xx/buttons.c
@@ -289,6 +289,12 @@ bcm47xx_buttons_linksys_wrt320n_v1[] __i
};
static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt310n_v2[] __initconst = {
+ BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
+ BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = {
BCM47XX_GPIO_KEY(5, KEY_WIMAX),
BCM47XX_GPIO_KEY(6, KEY_RESTART),
@@ -644,6 +650,9 @@ int __init bcm47xx_buttons_register(void
case BCM47XX_BOARD_LINKSYS_WRT320N_V1:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt320n_v1);
break;
+ case BCM47XX_BOARD_LINKSYS_WRT310NV2:
+ err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310n_v2);
+ break;
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2);
break;

View File

@ -0,0 +1,34 @@
--- a/drivers/mtd/parsers/bcm47xxpart.c
+++ b/drivers/mtd/parsers/bcm47xxpart.c
@@ -98,6 +98,7 @@ static int bcm47xxpart_parse(struct mtd_
int trx_num = 0; /* Number of found TRX partitions */
int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
int err;
+ bool found_nvram = false;
/*
* Some really old flashes (like AT45DB*) had smaller erasesize-s, but
@@ -279,12 +280,23 @@ static int bcm47xxpart_parse(struct mtd_
if (buf[0] == NVRAM_HEADER) {
bcm47xxpart_add_part(&parts[curr_part++], "nvram",
master->size - blocksize, 0);
+ found_nvram = true;
break;
}
}
kfree(buf);
+ if (!found_nvram) {
+ pr_err("can not find a nvram partition reserve last block\n");
+ bcm47xxpart_add_part(&parts[curr_part++], "nvram_guess",
+ master->size - blocksize * 2, MTD_WRITEABLE);
+ for (i = 0; i < curr_part; i++) {
+ if (parts[i].size + parts[i].offset == master->size)
+ parts[i].offset -= blocksize * 2;
+ }
+ }
+
/*
* Assume that partitions end at the beginning of the one they are
* followed by.

View File

@ -0,0 +1,42 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Sun, 7 Nov 2021 14:20:40 +0100
Subject: [PATCH] net: bgmac: connect to PHY even if it is BGMAC_PHY_NOREGS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Recent bgmac change was meant to just fix a race between "Generic PHY"
and "bcm53xx" drivers after -EPROBE_DEFER. It modified bgmac to use
phy_connect() only if there is a real PHY device connected.
That change broke bgmac on bcm47xx. bcma_phy_connect() now registers a
fixed PHY with the bgmac_phy_connect_direct(). That fails as another
fixed PHY (also using address 0) is already registered - by bcm47xx arch
code bcm47xx_register_bus_complete().
This change brings origial behaviour. It connects Ethernet interface
with pseudo-PHY (switch device) and adjusts Ethernet interface link to
match connected switch.
This fixes:
[ 2.548098] bgmac_bcma bcma0:1: Failed to register fixed PHY device
[ 2.554584] bgmac_bcma bcma0:1: Cannot connect to phy
Fixes: b5375509184d ("net: bgmac: improve handling PHY")
Link: https://lore.kernel.org/netdev/3639116e-9292-03ca-b9d9-d741118a4541@gmail.com/T/#u
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/net/ethernet/broadcom/bgmac-bcma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -94,7 +94,7 @@ static int bcma_phy_connect(struct bgmac
return 0;
/* Connect to the PHY */
- if (bgmac->mii_bus && bgmac->phyaddr != BGMAC_PHY_NOREGS) {
+ if (bgmac->mii_bus) {
snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
bgmac->phyaddr);
phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,

View File

@ -0,0 +1,17 @@
When the Ethernet controller is powered down and someone wants to
access the mdio bus like the witch driver (b53) the system crashed if
PCI_D3hot was set before. This patch deactivates this power sawing mode
when a switch driver is in use.
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -4267,7 +4267,8 @@ static int tg3_power_down_prepare(struct
static void tg3_power_down(struct tg3 *tp)
{
pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
- pci_set_power_state(tp->pdev, PCI_D3hot);
+ if (!tg3_flag(tp, ROBOSWITCH))
+ pci_set_power_state(tp->pdev, PCI_D3hot);
}
static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u32 *speed, u8 *duplex)

View File

@ -0,0 +1,73 @@
From 597715c61ae75a05ab3310a34ff3857a006f0f63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Thu, 20 Nov 2014 21:32:42 +0100
Subject: [PATCH] bcma: add table of serial flashes with smaller blocks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/bcma/driver_chipcommon_sflash.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
--- a/drivers/bcma/driver_chipcommon_sflash.c
+++ b/drivers/bcma/driver_chipcommon_sflash.c
@@ -9,6 +9,7 @@
#include <linux/platform_device.h>
#include <linux/bcma/bcma.h>
+#include <bcm47xx_board.h>
static struct resource bcma_sflash_resource = {
.name = "bcma_sflash",
@@ -42,6 +43,13 @@ static const struct bcma_sflash_tbl_e bc
{ NULL },
};
+/* Some devices use smaller blocks (and have more of them) */
+static const struct bcma_sflash_tbl_e bcma_sflash_st_shrink_tbl[] = {
+ { "M25P16", 0x14, 0x1000, 512, },
+ { "M25P32", 0x15, 0x1000, 1024, },
+ { NULL },
+};
+
static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
{ "SST25WF512", 1, 0x1000, 16, },
{ "SST25VF512", 0x48, 0x1000, 16, },
@@ -85,6 +93,24 @@ static void bcma_sflash_cmd(struct bcma_
bcma_err(cc->core->bus, "SFLASH control command failed (timeout)!\n");
}
+const struct bcma_sflash_tbl_e *bcma_sflash_shrink_flash(u32 id)
+{
+ enum bcm47xx_board board = bcm47xx_board_get();
+ const struct bcma_sflash_tbl_e *e;
+
+ switch (board) {
+ case BCM47XX_BOARD_NETGEAR_WGR614_V10:
+ case BCM47XX_BOARD_NETGEAR_WNR1000_V3:
+ for (e = bcma_sflash_st_shrink_tbl; e->name; e++) {
+ if (e->id == id)
+ return e;
+ }
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
/* Initialize serial flash access */
int bcma_sflash_init(struct bcma_drv_cc *cc)
{
@@ -115,6 +141,10 @@ int bcma_sflash_init(struct bcma_drv_cc
case 0x13:
return -ENOTSUPP;
default:
+ e = bcma_sflash_shrink_flash(id);
+ if (e)
+ break;
+
for (e = bcma_sflash_st_tbl; e->name; e++) {
if (e->id == id)
break;

View File

@ -0,0 +1,296 @@
The Netgear wgt634u uses a different format for storing the
configuration. This patch is needed to read out the correct
configuration. The cfe_env.c file uses a different method way to read
out the configuration than the in kernel cfe config reader.
--- a/drivers/firmware/broadcom/Makefile
+++ b/drivers/firmware/broadcom/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o
+obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o cfe_env.o
obj-$(CONFIG_BCM47XX_SPROM) += bcm47xx_sprom.o
obj-$(CONFIG_TEE_BNXT_FW) += tee_bnxt_fw.o
--- /dev/null
+++ b/drivers/firmware/broadcom/cfe_env.c
@@ -0,0 +1,228 @@
+/*
+ * CFE environment variable access
+ *
+ * Copyright 2001-2003, Broadcom Corporation
+ * Copyright 2006, Felix Fietkau <nbd@nbd.name>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/io.h>
+#include <linux/uaccess.h>
+
+#define NVRAM_SIZE (0x1ff0)
+static char _nvdata[NVRAM_SIZE];
+static char _valuestr[256];
+
+/*
+ * TLV types. These codes are used in the "type-length-value"
+ * encoding of the items stored in the NVRAM device (flash or EEPROM)
+ *
+ * The layout of the flash/nvram is as follows:
+ *
+ * <type> <length> <data ...> <type> <length> <data ...> <type_end>
+ *
+ * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
+ * The "length" field marks the length of the data section, not
+ * including the type and length fields.
+ *
+ * Environment variables are stored as follows:
+ *
+ * <type_env> <length> <flags> <name> = <value>
+ *
+ * If bit 0 (low bit) is set, the length is an 8-bit value.
+ * If bit 0 (low bit) is clear, the length is a 16-bit value
+ *
+ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still
+ * indicates the size of the length field.
+ *
+ * Flags are from the constants below:
+ *
+ */
+#define ENV_LENGTH_16BITS 0x00 /* for low bit */
+#define ENV_LENGTH_8BITS 0x01
+
+#define ENV_TYPE_USER 0x80
+
+#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
+#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
+
+/*
+ * The actual TLV types we support
+ */
+
+#define ENV_TLV_TYPE_END 0x00
+#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
+
+/*
+ * Environment variable flags
+ */
+
+#define ENV_FLG_NORMAL 0x00 /* normal read/write */
+#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */
+#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */
+
+#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */
+#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */
+
+
+/* *********************************************************************
+ * _nvram_read(buffer,offset,length)
+ *
+ * Read data from the NVRAM device
+ *
+ * Input parameters:
+ * buffer - destination buffer
+ * offset - offset of data to read
+ * length - number of bytes to read
+ *
+ * Return value:
+ * number of bytes read, or <0 if error occured
+ ********************************************************************* */
+static int
+_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
+{
+ int i;
+ if (offset > NVRAM_SIZE)
+ return -1;
+
+ for ( i = 0; i < length; i++) {
+ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
+ }
+ return length;
+}
+
+
+static char*
+_strnchr(const char *dest,int c,size_t cnt)
+{
+ while (*dest && (cnt > 0)) {
+ if (*dest == c) return (char *) dest;
+ dest++;
+ cnt--;
+ }
+ return NULL;
+}
+
+
+
+/*
+ * Core support API: Externally visible.
+ */
+
+/*
+ * Get the value of an NVRAM variable
+ * @param name name of variable to get
+ * @return value of variable or NULL if undefined
+ */
+
+char *cfe_env_get(unsigned char *nv_buf, const char *name)
+{
+ int size;
+ unsigned char *buffer;
+ unsigned char *ptr;
+ unsigned char *envval;
+ unsigned int reclen;
+ unsigned int rectype;
+ int offset;
+ int flg;
+
+ if (!strcmp(name, "nvram_type"))
+ return "cfe";
+
+ size = NVRAM_SIZE;
+ buffer = &_nvdata[0];
+
+ ptr = buffer;
+ offset = 0;
+
+ /* Read the record type and length */
+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
+ goto error;
+ }
+
+ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
+
+ /* Adjust pointer for TLV type */
+ rectype = *(ptr);
+ offset++;
+ size--;
+
+ /*
+ * Read the length. It can be either 1 or 2 bytes
+ * depending on the code
+ */
+ if (rectype & ENV_LENGTH_8BITS) {
+ /* Read the record type and length - 8 bits */
+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
+ goto error;
+ }
+ reclen = *(ptr);
+ size--;
+ offset++;
+ }
+ else {
+ /* Read the record type and length - 16 bits, MSB first */
+ if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
+ goto error;
+ }
+ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
+ size -= 2;
+ offset += 2;
+ }
+
+ if (reclen > size)
+ break; /* should not happen, bad NVRAM */
+
+ switch (rectype) {
+ case ENV_TLV_TYPE_ENV:
+ /* Read the TLV data */
+ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
+ goto error;
+ flg = *ptr++;
+ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
+ if (envval) {
+ *envval++ = '\0';
+ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
+ _valuestr[(reclen-1)-(envval-ptr)] = '\0';
+#if 0
+ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
+#endif
+ if(!strcmp(ptr, name)){
+ return _valuestr;
+ }
+ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
+ return _valuestr;
+ }
+ break;
+
+ default:
+ /* Unknown TLV type, skip it. */
+ break;
+ }
+
+ /*
+ * Advance to next TLV
+ */
+
+ size -= (int)reclen;
+ offset += reclen;
+
+ /* Read the next record type */
+ ptr = buffer;
+ if (_nvram_read(nv_buf, ptr,offset,1) != 1)
+ goto error;
+ }
+
+error:
+ return NULL;
+
+}
+
--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
@@ -33,6 +33,8 @@ struct nvram_header {
static char nvram_buf[NVRAM_SPACE];
static size_t nvram_len;
static const u32 nvram_sizes[] = {0x6000, 0x8000, 0xF000, 0x10000};
+static int cfe_env;
+extern char *cfe_env_get(char *nv_buf, const char *name);
/**
* bcm47xx_nvram_is_valid - check for a valid NVRAM at specified memory
@@ -80,6 +82,26 @@ static int bcm47xx_nvram_find_and_copy(v
return -EEXIST;
}
+ cfe_env = 0;
+
+ /* XXX: hack for supporting the CFE environment stuff on WGT634U */
+ if (res_size >= 8 * 1024 * 1024) {
+ u32 *src = (u32 *)(flash_start + 8 * 1024 * 1024 - 0x2000);
+ u32 *dst = (u32 *)nvram_buf;
+
+ if ((*src & 0xff00ff) == 0x000001) {
+ printk("early_nvram_init: WGT634U NVRAM found.\n");
+
+ for (i = 0; i < 0x1ff0; i++) {
+ if (*src == 0xFFFFFFFF)
+ break;
+ *dst++ = *src++;
+ }
+ cfe_env = 1;
+ return 0;
+ }
+ }
+
/* TODO: when nvram is on nand flash check for bad blocks first. */
/* Try every possible flash size and check for NVRAM at its end */
@@ -172,6 +194,13 @@ int bcm47xx_nvram_getenv(const char *nam
if (!name)
return -EINVAL;
+ if (cfe_env) {
+ value = cfe_env_get(nvram_buf, name);
+ if (!value)
+ return -ENOENT;
+ return snprintf(val, val_len, "%s", value);
+ }
+
if (!nvram_len) {
err = nvram_init();
if (err)

View File

@ -0,0 +1,101 @@
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -37,6 +37,7 @@
#include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_embedded.h>
#include <linux/bcma/bcma_soc.h>
+#include <linux/old_gpio_wdt.h>
#include <asm/bootinfo.h>
#include <asm/idle.h>
#include <asm/prom.h>
@@ -254,6 +255,33 @@ static struct fixed_phy_status bcm47xx_f
.duplex = DUPLEX_FULL,
};
+static struct gpio_wdt_platform_data gpio_wdt_data;
+
+static struct platform_device gpio_wdt_device = {
+ .name = "gpio-wdt",
+ .id = 0,
+ .dev = {
+ .platform_data = &gpio_wdt_data,
+ },
+};
+
+static int __init bcm47xx_register_gpio_watchdog(void)
+{
+ enum bcm47xx_board board = bcm47xx_board_get();
+
+ switch (board) {
+ case BCM47XX_BOARD_HUAWEI_E970:
+ pr_info("bcm47xx: detected Huawei E970 or similar, starting early gpio_wdt timer\n");
+ gpio_wdt_data.gpio = 7;
+ gpio_wdt_data.interval = HZ;
+ gpio_wdt_data.first_interval = HZ / 5;
+ return platform_device_register(&gpio_wdt_device);
+ default:
+ /* Nothing to do */
+ return 0;
+ }
+}
+
static int __init bcm47xx_register_bus_complete(void)
{
switch (bcm47xx_bus_type) {
@@ -275,6 +303,7 @@ static int __init bcm47xx_register_bus_c
bcm47xx_workarounds();
fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
+ bcm47xx_register_gpio_watchdog();
return 0;
}
device_initcall(bcm47xx_register_bus_complete);
--- a/arch/mips/configs/bcm47xx_defconfig
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -63,6 +63,7 @@ CONFIG_HW_RANDOM=y
CONFIG_GPIO_SYSFS=y
CONFIG_WATCHDOG=y
CONFIG_BCM47XX_WDT=y
+CONFIG_GPIO_WDT=y
CONFIG_SSB_DRIVER_GIGE=y
CONFIG_BCMA_DRIVER_GMAC_CMN=y
CONFIG_USB=y
--- a/drivers/ssb/embedded.c
+++ b/drivers/ssb/embedded.c
@@ -34,11 +34,36 @@ int ssb_watchdog_timer_set(struct ssb_bu
}
EXPORT_SYMBOL(ssb_watchdog_timer_set);
+#ifdef CONFIG_BCM47XX
+#include <bcm47xx_board.h>
+
+static bool ssb_watchdog_supported(void)
+{
+ enum bcm47xx_board board = bcm47xx_board_get();
+
+ /* The Huawei E970 has a hardware watchdog using a GPIO */
+ switch (board) {
+ case BCM47XX_BOARD_HUAWEI_E970:
+ return false;
+ default:
+ return true;
+ }
+}
+#else
+static bool ssb_watchdog_supported(void)
+{
+ return true;
+}
+#endif
+
int ssb_watchdog_register(struct ssb_bus *bus)
{
struct bcm47xx_wdt wdt = {};
struct platform_device *pdev;
+ if (!ssb_watchdog_supported())
+ return 0;
+
if (ssb_chipco_available(&bus->chipco)) {
wdt.driver_data = &bus->chipco;
wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt;

View File

@ -0,0 +1,360 @@
This generic GPIO watchdog is used on Huawei E970 (bcm47xx)
Signed-off-by: Mathias Adam <m.adam--openwrt@adamis.de>
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1664,6 +1664,15 @@ config WDT_MTX1
Hardware driver for the MTX-1 boards. This is a watchdog timer that
will reboot the machine after a 100 seconds timer expired.
+config GPIO_WDT
+ tristate "GPIO Hardware Watchdog"
+ help
+ Hardware driver for GPIO-controlled watchdogs. GPIO pin and
+ toggle interval settings are platform-specific. The driver
+ will stop toggling the GPIO (i.e. machine reboots) after a
+ 100 second timer expired and no process has written to
+ /dev/watchdog during that time.
+
config SIBYTE_WDOG
tristate "Sibyte SoC hardware watchdog"
depends on CPU_SB1
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_RC32434_WDT) += rc32434_wdt
obj-$(CONFIG_INDYDOG) += indydog.o
obj-$(CONFIG_JZ4740_WDT) += jz4740_wdt.o
obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
+obj-$(CONFIG_GPIO_WDT) += old_gpio_wdt.o
obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
--- /dev/null
+++ b/drivers/watchdog/old_gpio_wdt.c
@@ -0,0 +1,301 @@
+/*
+ * Driver for GPIO-controlled Hardware Watchdogs.
+ *
+ * Copyright (C) 2013 Mathias Adam <m.adam--linux@adamis.de>
+ *
+ * Replaces mtx1_wdt (driver for the MTX-1 Watchdog):
+ *
+ * (C) Copyright 2005 4G Systems <info@4g-systems.biz>,
+ * All Rights Reserved.
+ * http://www.4g-systems.biz
+ *
+ * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Neither Michael Stickel nor 4G Systems admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
+ *
+ * (c) Copyright 2005 4G Systems <info@4g-systems.biz>
+ *
+ * Release 0.01.
+ * Author: Michael Stickel michael.stickel@4g-systems.biz
+ *
+ * Release 0.02.
+ * Author: Florian Fainelli florian@openwrt.org
+ * use the Linux watchdog/timer APIs
+ *
+ * Release 0.03.
+ * Author: Mathias Adam <m.adam--linux@adamis.de>
+ * make it a generic gpio watchdog driver
+ *
+ * The Watchdog is configured to reset the MTX-1
+ * if it is not triggered for 100 seconds.
+ * It should not be triggered more often than 1.6 seconds.
+ *
+ * A timer triggers the watchdog every 5 seconds, until
+ * it is opened for the first time. After the first open
+ * it MUST be triggered every 2..95 seconds.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/jiffies.h>
+#include <linux/watchdog.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/gpio.h>
+#include <linux/old_gpio_wdt.h>
+
+static int ticks = 100 * HZ;
+
+static struct {
+ struct completion stop;
+ spinlock_t lock;
+ int running;
+ struct timer_list timer;
+ int queue;
+ int default_ticks;
+ unsigned long inuse;
+ unsigned gpio;
+ unsigned int gstate;
+ int interval;
+ int first_interval;
+} gpio_wdt_device;
+
+static void gpio_wdt_trigger(struct timer_list *unused)
+{
+ spin_lock(&gpio_wdt_device.lock);
+ if (gpio_wdt_device.running && ticks > 0)
+ ticks -= gpio_wdt_device.interval;
+
+ /* toggle wdt gpio */
+ gpio_wdt_device.gstate = !gpio_wdt_device.gstate;
+ gpio_set_value(gpio_wdt_device.gpio, gpio_wdt_device.gstate);
+
+ if (gpio_wdt_device.queue && ticks > 0)
+ mod_timer(&gpio_wdt_device.timer, jiffies + gpio_wdt_device.interval);
+ else
+ complete(&gpio_wdt_device.stop);
+ spin_unlock(&gpio_wdt_device.lock);
+}
+
+static void gpio_wdt_reset(void)
+{
+ ticks = gpio_wdt_device.default_ticks;
+}
+
+
+static void gpio_wdt_start(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_wdt_device.lock, flags);
+ if (!gpio_wdt_device.queue) {
+ gpio_wdt_device.queue = 1;
+ gpio_wdt_device.gstate = 1;
+ gpio_set_value(gpio_wdt_device.gpio, 1);
+ mod_timer(&gpio_wdt_device.timer, jiffies + gpio_wdt_device.first_interval);
+ }
+ gpio_wdt_device.running++;
+ spin_unlock_irqrestore(&gpio_wdt_device.lock, flags);
+}
+
+static int gpio_wdt_stop(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_wdt_device.lock, flags);
+ if (gpio_wdt_device.queue) {
+ gpio_wdt_device.queue = 0;
+ gpio_wdt_device.gstate = 0;
+ gpio_set_value(gpio_wdt_device.gpio, 0);
+ }
+ ticks = gpio_wdt_device.default_ticks;
+ spin_unlock_irqrestore(&gpio_wdt_device.lock, flags);
+ return 0;
+}
+
+/* Filesystem functions */
+
+static int gpio_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(0, &gpio_wdt_device.inuse))
+ return -EBUSY;
+ return nonseekable_open(inode, file);
+}
+
+
+static int gpio_wdt_release(struct inode *inode, struct file *file)
+{
+ clear_bit(0, &gpio_wdt_device.inuse);
+ return 0;
+}
+
+static long gpio_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = (int __user *)argp;
+ unsigned int value;
+ static const struct watchdog_info ident = {
+ .options = WDIOF_CARDRESET,
+ .identity = "GPIO WDT",
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &ident, sizeof(ident)))
+ return -EFAULT;
+ break;
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ put_user(0, p);
+ break;
+ case WDIOC_SETOPTIONS:
+ if (get_user(value, p))
+ return -EFAULT;
+ if (value & WDIOS_ENABLECARD)
+ gpio_wdt_start();
+ else if (value & WDIOS_DISABLECARD)
+ gpio_wdt_stop();
+ else
+ return -EINVAL;
+ return 0;
+ case WDIOC_KEEPALIVE:
+ gpio_wdt_reset();
+ break;
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+
+static ssize_t gpio_wdt_write(struct file *file, const char *buf,
+ size_t count, loff_t *ppos)
+{
+ if (!count)
+ return -EIO;
+ gpio_wdt_reset();
+ return count;
+}
+
+static const struct file_operations gpio_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .unlocked_ioctl = gpio_wdt_ioctl,
+ .open = gpio_wdt_open,
+ .write = gpio_wdt_write,
+ .release = gpio_wdt_release,
+};
+
+
+static struct miscdevice gpio_wdt_misc = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &gpio_wdt_fops,
+};
+
+
+static int gpio_wdt_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct gpio_wdt_platform_data *gpio_wdt_data = pdev->dev.platform_data;
+
+ gpio_wdt_device.gpio = gpio_wdt_data->gpio;
+ gpio_wdt_device.interval = gpio_wdt_data->interval;
+ gpio_wdt_device.first_interval = gpio_wdt_data->first_interval;
+ if (gpio_wdt_device.first_interval <= 0) {
+ gpio_wdt_device.first_interval = gpio_wdt_device.interval;
+ }
+
+ ret = gpio_request(gpio_wdt_device.gpio, "gpio-wdt");
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request gpio");
+ return ret;
+ }
+
+ spin_lock_init(&gpio_wdt_device.lock);
+ init_completion(&gpio_wdt_device.stop);
+ gpio_wdt_device.queue = 0;
+ clear_bit(0, &gpio_wdt_device.inuse);
+ timer_setup(&gpio_wdt_device.timer, gpio_wdt_trigger, 0L);
+ gpio_wdt_device.default_ticks = ticks;
+
+ gpio_wdt_start();
+ dev_info(&pdev->dev, "GPIO Hardware Watchdog driver (gpio=%i interval=%i/%i)\n",
+ gpio_wdt_data->gpio, gpio_wdt_data->first_interval, gpio_wdt_data->interval);
+ return 0;
+}
+
+static int gpio_wdt_remove(struct platform_device *pdev)
+{
+ /* FIXME: do we need to lock this test ? */
+ if (gpio_wdt_device.queue) {
+ gpio_wdt_device.queue = 0;
+ wait_for_completion(&gpio_wdt_device.stop);
+ }
+
+ gpio_free(gpio_wdt_device.gpio);
+ misc_deregister(&gpio_wdt_misc);
+ return 0;
+}
+
+static struct platform_driver gpio_wdt_driver = {
+ .probe = gpio_wdt_probe,
+ .remove = gpio_wdt_remove,
+ .driver.name = "gpio-wdt",
+ .driver.owner = THIS_MODULE,
+};
+
+static int __init gpio_wdt_init(void)
+{
+ return platform_driver_register(&gpio_wdt_driver);
+}
+arch_initcall(gpio_wdt_init);
+
+/*
+ * We do wdt initialization in two steps: arch_initcall probes the wdt
+ * very early to start pinging the watchdog (misc devices are not yet
+ * available), and later module_init() just registers the misc device.
+ */
+static int gpio_wdt_init_late(void)
+{
+ int ret;
+
+ ret = misc_register(&gpio_wdt_misc);
+ if (ret < 0) {
+ pr_err("GPIO_WDT: failed to register misc device\n");
+ return ret;
+ }
+ return 0;
+}
+#ifndef MODULE
+module_init(gpio_wdt_init_late);
+#endif
+
+static void __exit gpio_wdt_exit(void)
+{
+ platform_driver_unregister(&gpio_wdt_driver);
+}
+module_exit(gpio_wdt_exit);
+
+MODULE_AUTHOR("Michael Stickel, Florian Fainelli, Mathias Adam");
+MODULE_DESCRIPTION("Driver for GPIO hardware watchdogs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:gpio-wdt");
--- /dev/null
+++ b/include/linux/old_gpio_wdt.h
@@ -0,0 +1,21 @@
+/*
+ * Definitions for the GPIO watchdog driver
+ *
+ * Copyright (C) 2013 Mathias Adam <m.adam--linux@adamis.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _GPIO_WDT_H_
+#define _GPIO_WDT_H_
+
+struct gpio_wdt_platform_data {
+ int gpio; /* GPIO line number */
+ int interval; /* watchdog reset interval in system ticks */
+ int first_interval; /* first wd reset interval in system ticks */
+};
+
+#endif /* _GPIO_WDT_H_ */

View File

@ -0,0 +1,30 @@
From 5c81397a0147ea59c778d1de14ef54e2268221f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Wed, 8 Apr 2015 06:58:11 +0200
Subject: [PATCH] ssb: reject PCI writes setting CardBus bridge resources
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If SoC has a CardBus we can set resources of device at slot 1 only. It's
impossigle to set bridge resources as it simply overwrites device 1
configuration and usually results in Data bus error-s.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/ssb/driver_pcicore.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -165,6 +165,10 @@ static int ssb_extpci_write_config(struc
WARN_ON(!pc->hostmode);
if (unlikely(len != 1 && len != 2 && len != 4))
goto out;
+ /* CardBus SoCs allow configuring dev 1 resources only */
+ if (extpci_core->cardbusmode && dev != 1 &&
+ off >= PCI_BASE_ADDRESS_0 && off <= PCI_BASE_ADDRESS_5)
+ goto out;
addr = get_cfgspace_addr(pc, bus, dev, func, off);
if (unlikely(!addr))
goto out;

View File

@ -0,0 +1,46 @@
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -932,6 +932,8 @@ static unsigned int yenta_probe_irq(stru
* Probe for usable interrupts using the force
* register to generate bogus card status events.
*/
+#ifndef CONFIG_BCM47XX
+ /* WRT54G3G does not like this */
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
reg = exca_readb(socket, I365_CSCINT);
@@ -947,6 +949,7 @@ static unsigned int yenta_probe_irq(stru
}
cb_writel(socket, CB_SOCKET_MASK, 0);
exca_writeb(socket, I365_CSCINT, reg);
+#endif
mask = probe_irq_mask(val) & 0xffff;
@@ -1031,6 +1034,10 @@ static void yenta_get_socket_capabilitie
else
socket->socket.irq_mask = 0;
+ /* irq mask probing is broken for the WRT54G3G */
+ if (socket->socket.irq_mask == 0)
+ socket->socket.irq_mask = 0x6f8;
+
dev_info(&socket->dev->dev, "ISA IRQ mask 0x%04x, PCI irq %d\n",
socket->socket.irq_mask, socket->cb_irq);
}
@@ -1262,6 +1269,15 @@ static int yenta_probe(struct pci_dev *d
dev_info(&dev->dev, "Socket status: %08x\n",
cb_readl(socket, CB_SOCKET_STATE));
+ /* Generate an interrupt on card insert/remove */
+ config_writew(socket, CB_SOCKET_MASK, CB_CSTSMASK | CB_CDMASK);
+
+ /* Set up Multifunction Routing Status Register */
+ config_writew(socket, 0x8C, 0x1000 /* MFUNC3 to GPIO3 */ | 0x2 /* MFUNC0 to INTA */);
+
+ /* Switch interrupts to parallelized */
+ config_writeb(socket, 0x92, 0x64);
+
yenta_fixup_parent_bridge(dev->subordinate);
/* Register it with the pcmcia layer.. */

View File

@ -0,0 +1,11 @@
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -394,7 +394,7 @@ static void ssb_pcicore_init_hostmode(st
/* Give some time to the PCI controller to configure itself with the new
* values. Not waiting at this point causes crashes of the machine.
*/
- mdelay(10);
+ mdelay(300);
register_pci_controller(&ssb_pcicore_controller);
}

View File

@ -0,0 +1,24 @@
--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
@@ -30,7 +30,8 @@ struct nvram_header {
u32 config_ncdl; /* ncdl values for memc */
};
-static char nvram_buf[NVRAM_SPACE];
+char nvram_buf[NVRAM_SPACE];
+EXPORT_SYMBOL(nvram_buf);
static size_t nvram_len;
static const u32 nvram_sizes[] = {0x6000, 0x8000, 0xF000, 0x10000};
static int cfe_env;
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -63,6 +63,9 @@ void (*_dma_cache_wback_inv)(unsigned lo
void (*_dma_cache_wback)(unsigned long start, unsigned long size);
void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+EXPORT_SYMBOL(_dma_cache_wback_inv);
+EXPORT_SYMBOL(_dma_cache_inv);
+
#endif /* CONFIG_DMA_NONCOHERENT */
/*

View File

@ -33,7 +33,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
enum udp_conntrack {
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1447,6 +1447,11 @@ void nf_conntrack_tcp_init_net(struct ne
@@ -1457,6 +1457,11 @@ void nf_conntrack_tcp_init_net(struct ne
tn->tcp_loose = nf_ct_tcp_loose;
tn->tcp_be_liberal = nf_ct_tcp_be_liberal;
tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
@ -58,7 +58,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
NF_SYSCTL_CT_PROTO_TCP_LOOSE,
NF_SYSCTL_CT_PROTO_TCP_LIBERAL,
NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS,
@@ -758,6 +762,20 @@ static struct ctl_table nf_ct_sysctl_tab
@@ -757,6 +761,20 @@ static struct ctl_table nf_ct_sysctl_tab
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
@ -79,7 +79,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
[NF_SYSCTL_CT_PROTO_TCP_LOOSE] = {
.procname = "nf_conntrack_tcp_loose",
.maxlen = sizeof(int),
@@ -967,6 +985,12 @@ static void nf_conntrack_standalone_init
@@ -960,6 +978,12 @@ static void nf_conntrack_standalone_init
XASSIGN(LIBERAL, &tn->tcp_be_liberal);
XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans);
#undef XASSIGN

View File

@ -58,7 +58,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP,
NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6,
#ifdef CONFIG_NF_CT_PROTO_SCTP
@@ -810,6 +814,20 @@ static struct ctl_table nf_ct_sysctl_tab
@@ -809,6 +813,20 @@ static struct ctl_table nf_ct_sysctl_tab
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
@ -79,7 +79,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP] = {
.procname = "nf_conntrack_icmp_timeout",
.maxlen = sizeof(unsigned int),
@@ -1078,6 +1096,10 @@ static int nf_conntrack_standalone_init_
@@ -1070,6 +1088,10 @@ static int nf_conntrack_standalone_init_
table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6].data = &nf_icmpv6_pernet(net)->timeout;
table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP].data = &un->timeouts[UDP_CT_UNREPLIED];
table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM].data = &un->timeouts[UDP_CT_REPLIED];

View File

@ -73,7 +73,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1450,7 +1450,6 @@ void nf_conntrack_tcp_init_net(struct ne
@@ -1460,7 +1460,6 @@ void nf_conntrack_tcp_init_net(struct ne
#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
tn->offload_timeout = 30 * HZ;
@ -109,7 +109,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
#endif
NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP,
NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6,
@@ -773,12 +771,6 @@ static struct ctl_table nf_ct_sysctl_tab
@@ -772,12 +770,6 @@ static struct ctl_table nf_ct_sysctl_tab
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
@ -122,7 +122,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
#endif
[NF_SYSCTL_CT_PROTO_TCP_LOOSE] = {
.procname = "nf_conntrack_tcp_loose",
@@ -821,12 +813,6 @@ static struct ctl_table nf_ct_sysctl_tab
@@ -820,12 +812,6 @@ static struct ctl_table nf_ct_sysctl_tab
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
@ -135,7 +135,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
#endif
[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP] = {
.procname = "nf_conntrack_icmp_timeout",
@@ -1006,7 +992,6 @@ static void nf_conntrack_standalone_init
@@ -999,7 +985,6 @@ static void nf_conntrack_standalone_init
#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
table[NF_SYSCTL_CT_PROTO_TIMEOUT_TCP_OFFLOAD].data = &tn->offload_timeout;
@ -143,7 +143,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
#endif
}
@@ -1098,7 +1083,6 @@ static int nf_conntrack_standalone_init_
@@ -1090,7 +1075,6 @@ static int nf_conntrack_standalone_init_
table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM].data = &un->timeouts[UDP_CT_REPLIED];
#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD].data = &un->offload_timeout;

View File

@ -423,7 +423,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
if (bgmac->irq < 0)
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4487,7 +4487,6 @@ static int macb_probe(struct platform_de
@@ -4480,7 +4480,6 @@ static int macb_probe(struct platform_de
struct net_device *dev;
struct resource *regs;
void __iomem *mem;
@ -431,7 +431,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
struct macb *bp;
int err, val;
@@ -4600,15 +4599,11 @@ static int macb_probe(struct platform_de
@@ -4593,15 +4592,11 @@ static int macb_probe(struct platform_de
if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
bp->rx_intr_mask |= MACB_BIT(RXUBR);
@ -1360,7 +1360,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
int irq;
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5008,7 +5008,7 @@ int stmmac_dvr_probe(struct device *devi
@@ -5013,7 +5013,7 @@ int stmmac_dvr_probe(struct device *devi
priv->wol_irq = res->wol_irq;
priv->lpi_irq = res->lpi_irq;

View File

@ -37,8 +37,8 @@ Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
--- a/Makefile
+++ b/Makefile
@@ -432,7 +432,8 @@ HOSTCXX = g++
endif
@@ -433,7 +433,8 @@ endif
HOSTPKG_CONFIG = pkg-config
export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
- -O2 -fomit-frame-pointer -std=gnu89

View File

@ -49,7 +49,7 @@ Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
--- a/Makefile
+++ b/Makefile
@@ -516,7 +516,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror
@@ -517,7 +517,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror
-fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \
-Werror=implicit-function-declaration -Werror=implicit-int \
-Werror=return-type -Wno-format-security \

View File

@ -32,8 +32,8 @@ Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
--- a/Makefile
+++ b/Makefile
@@ -432,7 +432,7 @@ HOSTCXX = g++
endif
@@ -433,7 +433,7 @@ endif
HOSTPKG_CONFIG = pkg-config
export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
- -O2 -fomit-frame-pointer -std=gnu89 \

View File

@ -287,7 +287,7 @@ Change-Id: I25d9eda8c6bdc7c3653b9f210a159d6c247c81e8
struct pglist_data *pgdat;
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -422,6 +422,7 @@ assign_new_owner:
@@ -469,6 +469,7 @@ assign_new_owner:
goto retry;
}
WRITE_ONCE(mm->owner, c);

View File

@ -0,0 +1,98 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 17 Nov 2022 00:35:04 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: do not overwrite mtu
configuration running reset routine
Restore user configured MTU running mtk_hw_init() during tx timeout routine
since it will be overwritten after a hw reset.
Reported-by: Felix Fietkau <nbd@nbd.name>
Fixes: 9ea4d311509f ("net: ethernet: mediatek: add the whole ethernet reset into the reset process")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3175,6 +3175,30 @@ static void mtk_dim_tx(struct work_struc
dim->state = DIM_START_MEASURE;
}
+static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val)
+{
+ struct mtk_eth *eth = mac->hw;
+ u32 mcr_cur, mcr_new;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+ return;
+
+ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+ mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
+
+ if (val <= 1518)
+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
+ else if (val <= 1536)
+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
+ else if (val <= 1552)
+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
+ else
+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
+
+ if (mcr_new != mcr_cur)
+ mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
+}
+
static int mtk_hw_init(struct mtk_eth *eth)
{
u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
@@ -3249,8 +3273,16 @@ static int mtk_hw_init(struct mtk_eth *e
* up with the more appropriate value when mtk_mac_config call is being
* invoked.
*/
- for (i = 0; i < MTK_MAC_COUNT; i++)
+ for (i = 0; i < MTK_MAC_COUNT; i++) {
+ struct net_device *dev = eth->netdev[i];
+
mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
+ if (dev) {
+ struct mtk_mac *mac = netdev_priv(dev);
+
+ mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
+ }
+ }
/* Indicates CDM to parse the MTK special tag from CPU
* which also is working out for untag packets.
@@ -3366,7 +3398,6 @@ static int mtk_change_mtu(struct net_dev
int length = new_mtu + MTK_RX_ETH_HLEN;
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
- u32 mcr_cur, mcr_new;
if (rcu_access_pointer(eth->prog) &&
length > MTK_PP_MAX_BUF_SIZE) {
@@ -3374,23 +3405,7 @@ static int mtk_change_mtu(struct net_dev
return -EINVAL;
}
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
- mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
-
- if (length <= 1518)
- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
- else if (length <= 1536)
- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
- else if (length <= 1552)
- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
- else
- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
-
- if (mcr_new != mcr_cur)
- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
- }
-
+ mtk_set_mcr_max_rx(mac, length);
dev->mtu = new_mtu;
return 0;

View File

@ -0,0 +1,36 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 17 Nov 2022 00:58:46 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in
mtk_pending_work
Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is
set only in mtk_pending_work() and it runs holding rtnl lock
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3436,11 +3436,8 @@ static void mtk_pending_work(struct work
rtnl_lock();
dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
+ set_bit(MTK_RESETTING, &eth->state);
- while (test_and_set_bit_lock(MTK_RESETTING, &eth->state))
- cpu_relax();
-
- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__);
/* stop all devices to make sure that dma is properly shut down */
for (i = 0; i < MTK_MAC_COUNT; i++) {
if (!eth->netdev[i])
@@ -3474,7 +3471,7 @@ static void mtk_pending_work(struct work
dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
- clear_bit_unlock(MTK_RESETTING, &eth->state);
+ clear_bit(MTK_RESETTING, &eth->state);
rtnl_unlock();
}

View File

@ -0,0 +1,63 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 17 Nov 2022 15:29:53 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix RSTCTRL_PPE{0,1} definitions
Fix RSTCTRL_PPE0 and RSTCTRL_PPE1 register mask definitions for
MTK_NETSYS_V2.
Remove duplicated definitions.
Fixes: 160d3a9b1929 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3238,16 +3238,17 @@ static int mtk_hw_init(struct mtk_eth *e
return 0;
}
- val = RSTCTRL_FE | RSTCTRL_PPE;
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-
- val |= RSTCTRL_ETH;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
- val |= RSTCTRL_PPE1;
+ val = RSTCTRL_PPE0_V2;
+ } else {
+ val = RSTCTRL_PPE0;
}
- ethsys_reset(eth, val);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= RSTCTRL_PPE1;
+
+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -444,18 +444,14 @@
/* ethernet reset control register */
#define ETHSYS_RSTCTRL 0x34
#define RSTCTRL_FE BIT(6)
-#define RSTCTRL_PPE BIT(31)
-#define RSTCTRL_PPE1 BIT(30)
+#define RSTCTRL_PPE0 BIT(31)
+#define RSTCTRL_PPE0_V2 BIT(30)
+#define RSTCTRL_PPE1 BIT(31)
#define RSTCTRL_ETH BIT(23)
/* ethernet reset check idle register */
#define ETHSYS_FE_RST_CHK_IDLE_EN 0x28
-/* ethernet reset control register */
-#define ETHSYS_RSTCTRL 0x34
-#define RSTCTRL_FE BIT(6)
-#define RSTCTRL_PPE BIT(31)
-
/* ethernet dma channel agent map */
#define ETHSYS_DMA_AG_MAP 0x408
#define ETHSYS_DMA_AG_MAP_PDMA BIT(0)

View File

@ -0,0 +1,80 @@
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Thu, 24 Nov 2022 11:18:14 +0800
Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed
v1
All wed versions should enable the wcid overwritten feature,
since the wcid size is controlled by the wlan driver.
Tested-by: Sujuan Chen <sujuan.chen@mediatek.com>
Co-developed-by: Bo Jiao <bo.jiao@mediatek.com>
Signed-off-by: Bo Jiao <bo.jiao@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic
MTK_WED_WPDMA_RX_D_RX_DRV_EN);
wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-
- mtk_wed_set_512_support(dev, false);
}
+
+ mtk_wed_set_512_support(dev, false);
}
static void
@@ -1297,9 +1297,10 @@ mtk_wed_start(struct mtk_wed_device *dev
if (mtk_wed_rro_cfg(dev))
return;
- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
}
+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
+
mtk_wed_dma_enable(dev);
dev->running = true;
}
@@ -1365,11 +1366,13 @@ mtk_wed_attach(struct mtk_wed_device *de
}
mtk_wed_hw_init_early(dev);
- if (hw->version == 1)
+ if (hw->version == 1) {
regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
BIT(hw->index), 0);
- else
+ } else {
+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
ret = mtk_wed_wo_init(hw);
+ }
out:
if (ret)
mtk_wed_detach(dev);
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
@@ -20,6 +20,8 @@ struct mtk_wdma_desc {
__le32 info;
} __packed __aligned(4);
+#define MTK_WED_REV_ID 0x004
+
#define MTK_WED_RESET 0x008
#define MTK_WED_RESET_TX_BM BIT(0)
#define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -85,6 +85,9 @@ struct mtk_wed_device {
int irq;
u8 version;
+ /* used by wlan driver */
+ u32 rev_id;
+
struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
struct mtk_wed_ring txfree_ring;

View File

@ -0,0 +1,85 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:51 +0100
Subject: [PATCH] net: ethernet: mtk_wed: return status value in
mtk_wdma_rx_reset
Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine.
Increase poll timeout to 10ms in order to be aligned with vendor sdk.
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic
return wdma_r32(dev, MTK_WDMA_GLO_CFG);
}
-static void
+static int
mtk_wdma_rx_reset(struct mtk_wed_device *dev)
{
u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
- int i;
+ int i, ret;
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
- !(status & mask), 0, 1000))
+ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
+ !(status & mask), 0, 10000);
+ if (ret)
dev_err(dev->hw->dev, "rx reset failed\n");
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
if (dev->rx_wdma[i].desc)
continue;
@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device
wdma_w32(dev,
MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
}
+
+ return ret;
}
static void
@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de
mtk_wed_stop(dev);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
+ mtk_wdma_rx_reset(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
if (mtk_wed_get_rx_capa(dev)) {
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de
mtk_wed_wo_reset(dev);
mtk_wed_free_rx_rings(dev);
mtk_wed_wo_deinit(hw);
- mtk_wdma_rx_reset(dev);
}
if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
@@ -1006,11 +1009,7 @@ mtk_wed_reset_dma(struct mtk_wed_device
wed_w32(dev, MTK_WED_RESET_IDX, 0);
}
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
- if (mtk_wed_get_rx_capa(dev))
- mtk_wdma_rx_reset(dev);
+ mtk_wdma_rx_reset(dev);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);

View File

@ -0,0 +1,52 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:52 +0100
Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX
configuration in mtk_wdma_tx_reset
Remove duplicated code. Increase poll timeout to 10ms in order to be
aligned with vendor sdk.
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
- !(status & mask), 0, 1000))
+ !(status & mask), 0, 10000))
dev_err(dev->hw->dev, "tx reset failed\n");
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
- if (dev->tx_wdma[i].desc)
- continue;
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
wdma_w32(dev,
MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
- }
}
static void
@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de
mtk_wdma_rx_reset(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
- if (mtk_wed_get_rx_capa(dev)) {
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
- }
-
mtk_wed_free_tx_buffer(dev);
mtk_wed_free_tx_rings(dev);

View File

@ -0,0 +1,98 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:53 +0100
Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop
Update mtk_wed_stop routine and rename old mtk_wed_stop() to
mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet
Dispatcher reset support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic
static void
mtk_wed_stop(struct mtk_wed_device *dev)
{
- mtk_wed_dma_disable(dev);
mtk_wed_set_ext_int(dev, false);
- wed_clr(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WDMA_INT_AGENT_EN |
- MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev)
wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
+}
+
+static void
+mtk_wed_deinit(struct mtk_wed_device *dev)
+{
+ mtk_wed_stop(dev);
+ mtk_wed_dma_disable(dev);
+
+ wed_clr(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_WDMA_INT_AGENT_EN |
+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
+ MTK_WED_CTRL_WED_TX_BM_EN |
+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+ if (dev->hw->version == 1)
+ return;
+
+ wed_clr(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_EN |
+ MTK_WED_CTRL_WED_RX_BM_EN |
+ MTK_WED_CTRL_RX_RRO_QM_EN);
}
static void
@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de
mutex_lock(&hw_lock);
- mtk_wed_stop(dev);
+ mtk_wed_deinit(dev);
mtk_wdma_rx_reset(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
@@ -677,7 +691,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
{
u32 mask, set;
- mtk_wed_stop(dev);
+ mtk_wed_deinit(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
mtk_wed_set_wpdma(dev);
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
(_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
(_dev)->ops->msg_update(_dev, _id, _msg, _len)
+#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
+#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
#else
static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
{
@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active
#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
+#define mtk_wed_device_stop(_dev) do {} while (0)
+#define mtk_wed_device_dma_reset(_dev) do {} while (0)
#endif
#endif

View File

@ -0,0 +1,309 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:54 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine
Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless
Ethernet Dispatcher available on MT7986 SoC.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -951,42 +951,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
}
static u32
-mtk_wed_check_busy(struct mtk_wed_device *dev)
+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
{
- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) &
- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) &
- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
- return true;
-
- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) &
- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_CTRL) &
- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY))
- return true;
-
- return false;
+ return !!(wed_r32(dev, reg) & mask);
}
static int
-mtk_wed_poll_busy(struct mtk_wed_device *dev)
+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
{
int sleep = 15000;
int timeout = 100 * sleep;
u32 val;
return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
- timeout, false, dev);
+ timeout, false, dev, reg, mask);
+}
+
+static int
+mtk_wed_rx_reset(struct mtk_wed_device *dev)
+{
+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
+ u8 val = MTK_WED_WO_STATE_SER_RESET;
+ int i, ret;
+
+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
+ sizeof(val), true);
+ if (ret)
+ return ret;
+
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
+ } else {
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
+
+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
+
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
+ }
+
+ /* reset rro qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_RRO_QM_BUSY);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM);
+ } else {
+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
+ MTK_WED_RROQM_RST_IDX_MIOD |
+ MTK_WED_RROQM_RST_IDX_FDBK);
+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
+ }
+
+ /* reset route qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
+ if (ret)
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
+ else
+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
+ MTK_WED_RTQM_Q_RST);
+
+ /* reset tx wdma */
+ mtk_wdma_tx_reset(dev);
+
+ /* reset tx wdma drv */
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
+
+ /* reset wed rx dma */
+ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
+ MTK_WED_GLO_CFG_RX_DMA_BUSY);
+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
+ } else {
+ struct mtk_eth *eth = dev->hw->eth;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ wed_set(dev, MTK_WED_RESET_IDX,
+ MTK_WED_RESET_IDX_RX_V2);
+ else
+ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+ /* reset rx bm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_WED_RX_BM_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
+
+ /* wo change to enable state */
+ val = MTK_WED_WO_STATE_ENABLE;
+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
+ sizeof(val), true);
+ if (ret)
+ return ret;
+
+ /* wed_rx_ring_reset */
+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) {
+ if (!dev->rx_ring[i].desc)
+ continue;
+
+ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE,
+ false);
+ }
+ mtk_wed_free_rx_buffer(dev);
+
+ return 0;
}
static void
@@ -1004,19 +1092,23 @@ mtk_wed_reset_dma(struct mtk_wed_device
true);
}
- if (mtk_wed_poll_busy(dev))
- busy = mtk_wed_check_busy(dev);
-
+ /* 1. reset WED tx DMA */
+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN);
+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
+ MTK_WED_GLO_CFG_TX_DMA_BUSY);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
} else {
- wed_w32(dev, MTK_WED_RESET_IDX,
- MTK_WED_RESET_IDX_TX |
- MTK_WED_RESET_IDX_RX);
+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
wed_w32(dev, MTK_WED_RESET_IDX, 0);
}
- mtk_wdma_rx_reset(dev);
+ /* 2. reset WDMA rx DMA */
+ busy = !!mtk_wdma_rx_reset(dev);
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
+ if (!busy)
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
@@ -1033,6 +1125,9 @@ mtk_wed_reset_dma(struct mtk_wed_device
MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE);
}
+ /* 3. reset WED WPDMA tx */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
for (i = 0; i < 100; i++) {
val = wed_r32(dev, MTK_WED_TX_BM_INTF);
if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
@@ -1040,8 +1135,19 @@ mtk_wed_reset_dma(struct mtk_wed_device
}
mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN);
mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
+ /* 4. reset WED WPDMA tx */
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
+ if (!busy)
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY);
+
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
@@ -1052,6 +1158,17 @@ mtk_wed_reset_dma(struct mtk_wed_device
MTK_WED_WPDMA_RESET_IDX_RX);
wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
}
+
+ dev->init_done = false;
+ if (dev->hw->version == 1)
+ return;
+
+ if (!busy) {
+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX);
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+ mtk_wed_rx_reset(dev);
}
static int
@@ -1274,6 +1391,9 @@ mtk_wed_start(struct mtk_wed_device *dev
{
int i;
+ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev))
+ return;
+
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
if (!dev->rx_wdma[i].desc)
mtk_wed_wdma_rx_ring_setup(dev, i, 16);
@@ -1362,10 +1482,6 @@ mtk_wed_attach(struct mtk_wed_device *de
goto out;
if (mtk_wed_get_rx_capa(dev)) {
- ret = mtk_wed_rx_buffer_alloc(dev);
- if (ret)
- goto out;
-
ret = mtk_wed_rro_alloc(dev);
if (ret)
goto out;
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
@@ -24,11 +24,15 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET 0x008
#define MTK_WED_RESET_TX_BM BIT(0)
+#define MTK_WED_RESET_RX_BM BIT(1)
#define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
#define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
#define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
+#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10)
#define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11)
#define MTK_WED_RESET_WED_TX_DMA BIT(12)
+#define MTK_WED_RESET_WED_RX_DMA BIT(13)
+#define MTK_WED_RESET_WDMA_TX_DRV BIT(16)
#define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
#define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
#define MTK_WED_RESET_RX_RRO_QM BIT(20)
@@ -158,6 +162,8 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET_IDX 0x20c
#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
#define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
+#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6)
+#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
#define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4)
@@ -267,6 +273,9 @@ struct mtk_wdma_desc {
#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
+#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1)
+#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3)
+#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4)
#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)
#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)

View File

@ -0,0 +1,103 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:55 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
Introduce reset parameter to mtk_wed_tx_ring_setup signature.
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -1188,7 +1188,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device
}
static int
-mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+ bool reset)
{
u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
struct mtk_wed_ring *wdma;
@@ -1197,8 +1198,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
return -EINVAL;
wdma = &dev->rx_wdma[idx];
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
- true))
+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+ desc_size, true))
return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
@@ -1396,7 +1397,7 @@ mtk_wed_start(struct mtk_wed_device *dev
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
if (!dev->rx_wdma[i].desc)
- mtk_wed_wdma_rx_ring_setup(dev, i, 16);
+ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
mtk_wed_hw_init(dev);
mtk_wed_configure_irq(dev, irq_mask);
@@ -1505,7 +1506,8 @@ unlock:
}
static int
-mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
+ bool reset)
{
struct mtk_wed_ring *ring = &dev->tx_ring[idx];
@@ -1524,11 +1526,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
return -EINVAL;
- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
- sizeof(*ring->desc), true))
+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
+ sizeof(*ring->desc), true))
return -ENOMEM;
- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
+ reset))
return -ENOMEM;
ring->reg_base = MTK_WED_RING_TX(idx);
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -158,7 +158,7 @@ struct mtk_wed_device {
struct mtk_wed_ops {
int (*attach)(struct mtk_wed_device *dev);
int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
+ void __iomem *regs, bool reset);
int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
void __iomem *regs);
int (*txfree_ring_setup)(struct mtk_wed_device *dev,
@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
#define mtk_wed_device_active(_dev) !!(_dev)->ops
#define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
#define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \
- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \
+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)
#define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
(_dev)->ops->txfree_ring_setup(_dev, _regs)
#define mtk_wed_device_reg_read(_dev, _reg) \
@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active
}
#define mtk_wed_device_detach(_dev) do {} while (0)
#define mtk_wed_device_start(_dev, _mask) do {} while (0)
-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
#define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
#define mtk_wed_device_reg_read(_dev, _reg) 0
#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)

View File

@ -0,0 +1,103 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 1 Dec 2022 16:26:53 +0100
Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in
mtk_wed_wo_queue_refill
In order to fix the following sleep while atomic bug always alloc pages
with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in
spin_lock critical section.
[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT)
[ 9.054665] Call trace:
[ 9.057096] dump_backtrace+0x0/0x154
[ 9.060751] show_stack+0x14/0x1c
[ 9.064052] dump_stack_lvl+0x64/0x7c
[ 9.067702] dump_stack+0x14/0x2c
[ 9.071001] ___might_sleep+0xec/0x120
[ 9.074736] __might_sleep+0x4c/0x9c
[ 9.078296] __alloc_pages+0x184/0x2e4
[ 9.082030] page_frag_alloc_align+0x98/0x1ac
[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234
[ 9.090974] mtk_wed_wo_init+0x174/0x2c0
[ 9.094881] mtk_wed_attach+0x7c8/0x7e0
[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e]
[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e]
[ 9.108727] pci_device_probe+0xac/0x13c
[ 9.112638] really_probe.part.0+0x98/0x2f4
[ 9.116807] __driver_probe_device+0x94/0x13c
[ 9.121147] driver_probe_device+0x40/0x114
[ 9.125314] __driver_attach+0x7c/0x180
[ 9.129133] bus_for_each_dev+0x5c/0x90
[ 9.132953] driver_attach+0x20/0x2c
[ 9.136513] bus_add_driver+0x104/0x1fc
[ 9.140333] driver_register+0x74/0x120
[ 9.144153] __pci_register_driver+0x40/0x50
[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e]
[ 9.152848] do_one_initcall+0x40/0x25c
[ 9.156669] do_init_module+0x44/0x230
[ 9.160403] load_module+0x1f30/0x2750
[ 9.164135] __do_sys_init_module+0x150/0x200
[ 9.168475] __arm64_sys_init_module+0x18/0x20
[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0
[ 9.177589] do_el0_svc+0x48/0xe0
[ 9.180889] el0_svc+0x14/0x50
[ 9.183929] el0t_64_sync_handler+0x9c/0x120
[ 9.188183] el0t_64_sync+0x158/0x15c
Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo
static int
mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
- gfp_t gfp, bool rx)
+ bool rx)
{
enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
int n_buf = 0;
spin_lock_bh(&q->lock);
while (q->queued < q->n_desc) {
- void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp);
struct mtk_wed_wo_queue_entry *entry;
dma_addr_t addr;
+ void *buf;
+ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC);
if (!buf)
break;
@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w
mtk_wed_mcu_rx_unsolicited_event(wo, skb);
}
- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) {
+ if (mtk_wed_wo_queue_refill(wo, q, true)) {
u32 index = (q->head - 1) % q->n_desc;
mtk_wed_wo_queue_kick(wo, q, index);
@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
if (ret)
goto error;
- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false);
+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false);
mtk_wed_wo_queue_reset(wo, &wo->q_tx);
regs.desc_base = MTK_WED_WO_CCIF_DUMMY5;
@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
if (ret)
goto error;
- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true);
+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true);
mtk_wed_wo_queue_reset(wo, &wo->q_rx);
/* rx queue irqmask */

View File

@ -0,0 +1,52 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 10 Jan 2023 10:31:26 +0100
Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue
Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and
mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher
MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization
and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in
mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been
disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill
routines can't run concurrently get rid of spinlock for mcu rx queue.
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
int n_buf = 0;
- spin_lock_bh(&q->lock);
while (q->queued < q->n_desc) {
struct mtk_wed_wo_queue_entry *entry;
dma_addr_t addr;
@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
q->queued++;
n_buf++;
}
- spin_unlock_bh(&q->lock);
return n_buf;
}
@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
{
struct page *page;
- spin_lock_bh(&q->lock);
for (;;) {
void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
skb_free_frag(buf);
}
- spin_unlock_bh(&q->lock);
if (!q->cache.va)
return;

View File

@ -0,0 +1,75 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 12 Jan 2023 10:21:29 +0100
Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue
Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue,
we do not need to protect WED MCU tx queue with a spin lock since
the tx queue is accessed in the two following routines:
- mtk_wed_wo_queue_tx_skb():
it is run at initialization and during mt7915 normal operation.
Moreover MCU messages are serialized through MCU mutex.
- mtk_wed_wo_queue_tx_clean():
it runs just at mt7915 driver module unload when no more messages
are sent to the MCU.
Remove tx queue spinlock.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo
int n_desc, int buf_size, int index,
struct mtk_wed_wo_queue_regs *regs)
{
- spin_lock_init(&q->lock);
q->regs = *regs;
q->n_desc = n_desc;
q->buf_size = buf_size;
@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
struct page *page;
int i;
- spin_lock_bh(&q->lock);
for (i = 0; i < q->n_desc; i++) {
struct mtk_wed_wo_queue_entry *entry = &q->entry[i];
@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
skb_free_frag(entry->buf);
entry->buf = NULL;
}
- spin_unlock_bh(&q->lock);
if (!q->cache.va)
return;
@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
int ret = 0, index;
u32 ctrl;
- spin_lock_bh(&q->lock);
-
q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx);
index = (q->head + 1) % q->n_desc;
if (q->tail == index) {
@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
mtk_wed_wo_queue_kick(wo, q, q->head);
mtk_wed_wo_kickout(wo);
out:
- spin_unlock_bh(&q->lock);
-
dev_kfree_skb(skb);
return ret;
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
@@ -211,7 +211,6 @@ struct mtk_wed_wo_queue {
struct mtk_wed_wo_queue_regs regs;
struct page_frag_cache cache;
- spinlock_t lock;
struct mtk_wed_wo_queue_desc *desc;
dma_addr_t desc_dma;

View File

@ -0,0 +1,70 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:28 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility
routine
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3199,6 +3199,27 @@ static void mtk_set_mcr_max_rx(struct mt
mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
}
+static void mtk_hw_reset(struct mtk_eth *eth)
+{
+ u32 val;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
+ val = RSTCTRL_PPE0_V2;
+ } else {
+ val = RSTCTRL_PPE0;
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= RSTCTRL_PPE1;
+
+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+ 0x3ffffff);
+}
+
static int mtk_hw_init(struct mtk_eth *eth)
{
u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
@@ -3238,22 +3259,9 @@ static int mtk_hw_init(struct mtk_eth *e
return 0;
}
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
- val = RSTCTRL_PPE0_V2;
- } else {
- val = RSTCTRL_PPE0;
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
- val |= RSTCTRL_PPE1;
-
- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+ mtk_hw_reset(eth);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
- 0x3ffffff);
-
/* Set FE to PDMAv2 if necessary */
val = mtk_r32(eth, MTK_FE_GLO_MISC);
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);

View File

@ -0,0 +1,107 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:29 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset
support
Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch
to align reset procedure to vendor sdk and avoid to power down the chip
during hw reset.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3220,7 +3220,54 @@ static void mtk_hw_reset(struct mtk_eth
0x3ffffff);
}
-static int mtk_hw_init(struct mtk_eth *eth)
+static u32 mtk_hw_reset_read(struct mtk_eth *eth)
+{
+ u32 val;
+
+ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val);
+ return val;
+}
+
+static void mtk_hw_warm_reset(struct mtk_eth *eth)
+{
+ u32 rst_mask, val;
+
+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE,
+ RSTCTRL_FE);
+ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val,
+ val & RSTCTRL_FE, 1, 1000)) {
+ dev_err(eth->dev, "warm reset failed\n");
+ mtk_hw_reset(eth);
+ return;
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
+ else
+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ rst_mask |= RSTCTRL_PPE1;
+
+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
+
+ udelay(1);
+ val = mtk_hw_reset_read(eth);
+ if (!(val & rst_mask))
+ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n",
+ val, rst_mask);
+
+ rst_mask |= RSTCTRL_FE;
+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask);
+
+ udelay(1);
+ val = mtk_hw_reset_read(eth);
+ if (val & rst_mask)
+ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n",
+ val, rst_mask);
+}
+
+static int mtk_hw_init(struct mtk_eth *eth, bool reset)
{
u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
ETHSYS_DMA_AG_MAP_PPE;
@@ -3259,7 +3306,12 @@ static int mtk_hw_init(struct mtk_eth *e
return 0;
}
- mtk_hw_reset(eth);
+ msleep(100);
+
+ if (reset)
+ mtk_hw_warm_reset(eth);
+ else
+ mtk_hw_reset(eth);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
/* Set FE to PDMAv2 if necessary */
@@ -3464,7 +3516,7 @@ static void mtk_pending_work(struct work
if (eth->dev->pins)
pinctrl_select_state(eth->dev->pins->p,
eth->dev->pins->default_state);
- mtk_hw_init(eth);
+ mtk_hw_init(eth, true);
/* restart DMA and enable IRQs */
for (i = 0; i < MTK_MAC_COUNT; i++) {
@@ -4056,7 +4108,7 @@ static int mtk_probe(struct platform_dev
eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
INIT_WORK(&eth->pending_work, mtk_pending_work);
- err = mtk_hw_init(eth);
+ err = mtk_hw_init(eth, false);
if (err)
goto err_wed_exit;

View File

@ -0,0 +1,262 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:30 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor
sdk
Avoid to power-down the ethernet chip during hw reset and align reset
procedure to vendor sdk.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2785,14 +2785,29 @@ static void mtk_dma_free(struct mtk_eth
kfree(eth->scratch_head);
}
+static bool mtk_hw_reset_check(struct mtk_eth *eth)
+{
+ u32 val = mtk_r32(eth, MTK_INT_STATUS2);
+
+ return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) ||
+ (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) ||
+ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL);
+}
+
static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
+ if (test_bit(MTK_RESETTING, &eth->state))
+ return;
+
+ if (!mtk_hw_reset_check(eth))
+ return;
+
eth->netdev[mac->id]->stats.tx_errors++;
- netif_err(eth, tx_err, dev,
- "transmit timed out\n");
+ netif_err(eth, tx_err, dev, "transmit timed out\n");
+
schedule_work(&eth->pending_work);
}
@@ -3274,15 +3289,17 @@ static int mtk_hw_init(struct mtk_eth *e
const struct mtk_reg_map *reg_map = eth->soc->reg_map;
int i, val, ret;
- if (test_and_set_bit(MTK_HW_INIT, &eth->state))
+ if (!reset && test_and_set_bit(MTK_HW_INIT, &eth->state))
return 0;
- pm_runtime_enable(eth->dev);
- pm_runtime_get_sync(eth->dev);
+ if (!reset) {
+ pm_runtime_enable(eth->dev);
+ pm_runtime_get_sync(eth->dev);
- ret = mtk_clk_enable(eth);
- if (ret)
- goto err_disable_pm;
+ ret = mtk_clk_enable(eth);
+ if (ret)
+ goto err_disable_pm;
+ }
if (eth->ethsys)
regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask,
@@ -3408,8 +3425,10 @@ static int mtk_hw_init(struct mtk_eth *e
return 0;
err_disable_pm:
- pm_runtime_put_sync(eth->dev);
- pm_runtime_disable(eth->dev);
+ if (!reset) {
+ pm_runtime_put_sync(eth->dev);
+ pm_runtime_disable(eth->dev);
+ }
return ret;
}
@@ -3488,30 +3507,53 @@ static int mtk_do_ioctl(struct net_devic
return -EOPNOTSUPP;
}
+static void mtk_prepare_for_reset(struct mtk_eth *eth)
+{
+ u32 val;
+ int i;
+
+ /* disabe FE P3 and P4 */
+ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= MTK_FE_LINK_DOWN_P4;
+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
+
+ /* adjust PPE configurations to prepare for reset */
+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
+ mtk_ppe_prepare_reset(eth->ppe[i]);
+
+ /* disable NETSYS interrupts */
+ mtk_w32(eth, 0, MTK_FE_INT_ENABLE);
+
+ /* force link down GMAC */
+ for (i = 0; i < 2; i++) {
+ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK;
+ mtk_w32(eth, val, MTK_MAC_MCR(i));
+ }
+}
+
static void mtk_pending_work(struct work_struct *work)
{
struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
- int err, i;
unsigned long restart = 0;
+ u32 val;
+ int i;
rtnl_lock();
-
- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
set_bit(MTK_RESETTING, &eth->state);
+ mtk_prepare_for_reset(eth);
+
/* stop all devices to make sure that dma is properly shut down */
for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!eth->netdev[i])
+ if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
continue;
+
mtk_stop(eth->netdev[i]);
__set_bit(i, &restart);
}
- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__);
- /* restart underlying hardware such as power, clock, pin mux
- * and the connected phy
- */
- mtk_hw_deinit(eth);
+ usleep_range(15000, 16000);
if (eth->dev->pins)
pinctrl_select_state(eth->dev->pins->p,
@@ -3522,15 +3564,19 @@ static void mtk_pending_work(struct work
for (i = 0; i < MTK_MAC_COUNT; i++) {
if (!test_bit(i, &restart))
continue;
- err = mtk_open(eth->netdev[i]);
- if (err) {
+
+ if (mtk_open(eth->netdev[i])) {
netif_alert(eth, ifup, eth->netdev[i],
- "Driver up/down cycle failed, closing device.\n");
+ "Driver up/down cycle failed\n");
dev_close(eth->netdev[i]);
}
}
- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
+ /* enabe FE P3 and P4 */
+ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val &= ~MTK_FE_LINK_DOWN_P4;
+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
clear_bit(MTK_RESETTING, &eth->state);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -72,12 +72,24 @@
#define MTK_HW_LRO_REPLACE_DELTA 1000
#define MTK_HW_LRO_SDL_REMAIN_ROOM 1522
+/* Frame Engine Global Configuration */
+#define MTK_FE_GLO_CFG 0x00
+#define MTK_FE_LINK_DOWN_P3 BIT(11)
+#define MTK_FE_LINK_DOWN_P4 BIT(12)
+
/* Frame Engine Global Reset Register */
#define MTK_RST_GL 0x04
#define RST_GL_PSE BIT(0)
/* Frame Engine Interrupt Status Register */
#define MTK_INT_STATUS2 0x08
+#define MTK_FE_INT_ENABLE 0x0c
+#define MTK_FE_INT_FQ_EMPTY BIT(8)
+#define MTK_FE_INT_TSO_FAIL BIT(12)
+#define MTK_FE_INT_TSO_ILLEGAL BIT(13)
+#define MTK_FE_INT_TSO_ALIGN BIT(14)
+#define MTK_FE_INT_RFIFO_OV BIT(18)
+#define MTK_FE_INT_RFIFO_UF BIT(19)
#define MTK_GDM1_AF BIT(28)
#define MTK_GDM2_AF BIT(29)
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -716,6 +716,33 @@ int mtk_foe_entry_idle_time(struct mtk_p
return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
}
+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
+{
+ if (!ppe)
+ return -EINVAL;
+
+ /* disable KA */
+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
+ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0);
+ usleep_range(10000, 11000);
+
+ /* set KA timer to maximum */
+ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff);
+
+ /* set KA tick select */
+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL);
+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
+ usleep_range(10000, 11000);
+
+ /* disable scan mode */
+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE);
+ usleep_range(10000, 11000);
+
+ return mtk_ppe_wait_busy(ppe);
+}
+
struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
int version, int index)
{
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
int version, int index);
void mtk_ppe_start(struct mtk_ppe *ppe);
int mtk_ppe_stop(struct mtk_ppe *ppe);
+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
@@ -58,6 +58,12 @@
#define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16)
#define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18)
#define MTK_PPE_TB_CFG_INFO_SEL BIT(20)
+#define MTK_PPE_TB_TICK_SEL BIT(24)
+
+#define MTK_PPE_BIND_LMT1 0x230
+#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16)
+
+#define MTK_PPE_KEEPALIVE 0x234
enum {
MTK_PPE_SCAN_MODE_DISABLED,

View File

@ -0,0 +1,249 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:31 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to
mtk_hw_reset_check
Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -50,6 +50,7 @@ static const struct mtk_reg_map mtk_reg_
.delay_irq = 0x0a0c,
.irq_status = 0x0a20,
.irq_mask = 0x0a28,
+ .adma_rx_dbg0 = 0x0a38,
.int_grp = 0x0a50,
},
.qdma = {
@@ -79,6 +80,8 @@ static const struct mtk_reg_map mtk_reg_
[0] = 0x2800,
[1] = 0x2c00,
},
+ .pse_iq_sta = 0x0110,
+ .pse_oq_sta = 0x0118,
};
static const struct mtk_reg_map mt7628_reg_map = {
@@ -109,6 +112,7 @@ static const struct mtk_reg_map mt7986_r
.delay_irq = 0x620c,
.irq_status = 0x6220,
.irq_mask = 0x6228,
+ .adma_rx_dbg0 = 0x6238,
.int_grp = 0x6250,
},
.qdma = {
@@ -138,6 +142,8 @@ static const struct mtk_reg_map mt7986_r
[0] = 0x4800,
[1] = 0x4c00,
},
+ .pse_iq_sta = 0x0180,
+ .pse_oq_sta = 0x01a0,
};
/* strings used by ethtool */
@@ -3282,6 +3288,102 @@ static void mtk_hw_warm_reset(struct mtk
val, rst_mask);
}
+static bool mtk_hw_check_dma_hang(struct mtk_eth *eth)
+{
+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
+ bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx;
+ bool oq_hang, cdm1_busy, adma_busy;
+ bool wtx_busy, cdm_full, oq_free;
+ u32 wdidx, val, gdm1_fc, gdm2_fc;
+ bool qfsm_hang, qfwd_hang;
+ bool ret = false;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+ return false;
+
+ /* WDMA sanity checks */
+ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc);
+
+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204);
+ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val);
+
+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230);
+ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val);
+
+ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) &&
+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) &&
+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16)));
+
+ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) {
+ if (++eth->reset.wdma_hang_count > 2) {
+ eth->reset.wdma_hang_count = 0;
+ ret = true;
+ }
+ goto out;
+ }
+
+ /* QDMA sanity checks */
+ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234);
+ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308);
+
+ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0;
+ gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0;
+ gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1;
+ gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1;
+ gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24);
+ gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64);
+
+ if (qfsm_hang && qfwd_hang &&
+ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) ||
+ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) {
+ if (++eth->reset.qdma_hang_count > 2) {
+ eth->reset.qdma_hang_count = 0;
+ ret = true;
+ }
+ goto out;
+ }
+
+ /* ADMA sanity checks */
+ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0));
+ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16));
+ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) &&
+ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6));
+
+ if (oq_hang && cdm1_busy && adma_busy) {
+ if (++eth->reset.adma_hang_count > 2) {
+ eth->reset.adma_hang_count = 0;
+ ret = true;
+ }
+ goto out;
+ }
+
+ eth->reset.wdma_hang_count = 0;
+ eth->reset.qdma_hang_count = 0;
+ eth->reset.adma_hang_count = 0;
+out:
+ eth->reset.wdidx = wdidx;
+
+ return ret;
+}
+
+static void mtk_hw_reset_monitor_work(struct work_struct *work)
+{
+ struct delayed_work *del_work = to_delayed_work(work);
+ struct mtk_eth *eth = container_of(del_work, struct mtk_eth,
+ reset.monitor_work);
+
+ if (test_bit(MTK_RESETTING, &eth->state))
+ goto out;
+
+ /* DMA stuck checks */
+ if (mtk_hw_check_dma_hang(eth))
+ schedule_work(&eth->pending_work);
+
+out:
+ schedule_delayed_work(&eth->reset.monitor_work,
+ MTK_DMA_MONITOR_TIMEOUT);
+}
+
static int mtk_hw_init(struct mtk_eth *eth, bool reset)
{
u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
@@ -3614,6 +3716,7 @@ static int mtk_cleanup(struct mtk_eth *e
mtk_unreg_dev(eth);
mtk_free_dev(eth);
cancel_work_sync(&eth->pending_work);
+ cancel_delayed_work_sync(&eth->reset.monitor_work);
return 0;
}
@@ -4041,6 +4144,7 @@ static int mtk_probe(struct platform_dev
eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
INIT_WORK(&eth->rx_dim.work, mtk_dim_rx);
+ INIT_DELAYED_WORK(&eth->reset.monitor_work, mtk_hw_reset_monitor_work);
eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
INIT_WORK(&eth->tx_dim.work, mtk_dim_tx);
@@ -4245,6 +4349,8 @@ static int mtk_probe(struct platform_dev
NAPI_POLL_WEIGHT);
platform_set_drvdata(pdev, eth);
+ schedule_delayed_work(&eth->reset.monitor_work,
+ MTK_DMA_MONITOR_TIMEOUT);
return 0;
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -256,6 +256,8 @@
#define MTK_RX_DONE_INT_V2 BIT(14)
+#define MTK_CDM_TXFIFO_RDY BIT(7)
+
/* QDMA Interrupt grouping registers */
#define MTK_RLS_DONE_INT BIT(0)
@@ -537,6 +539,17 @@
#define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c)
#define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110)
+#define MTK_FE_CDM1_FSM 0x220
+#define MTK_FE_CDM2_FSM 0x224
+#define MTK_FE_CDM3_FSM 0x238
+#define MTK_FE_CDM4_FSM 0x298
+#define MTK_FE_CDM5_FSM 0x318
+#define MTK_FE_CDM6_FSM 0x328
+#define MTK_FE_GDM1_FSM 0x228
+#define MTK_FE_GDM2_FSM 0x22C
+
+#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100))
+
struct mtk_rx_dma {
unsigned int rxd1;
unsigned int rxd2;
@@ -933,6 +946,7 @@ struct mtk_reg_map {
u32 delay_irq; /* delay interrupt */
u32 irq_status; /* interrupt status */
u32 irq_mask; /* interrupt mask */
+ u32 adma_rx_dbg0;
u32 int_grp;
} pdma;
struct {
@@ -959,6 +973,8 @@ struct mtk_reg_map {
u32 gdma_to_ppe0;
u32 ppe_base;
u32 wdma_base[2];
+ u32 pse_iq_sta;
+ u32 pse_oq_sta;
};
/* struct mtk_eth_data - This is the structure holding all differences
@@ -1001,6 +1017,8 @@ struct mtk_soc_data {
} txrx;
};
+#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
+
/* currently no SoC has more than 2 macs */
#define MTK_MAX_DEVS 2
@@ -1123,6 +1141,14 @@ struct mtk_eth {
struct rhashtable flow_table;
struct bpf_prog __rcu *prog;
+
+ struct {
+ struct delayed_work monitor_work;
+ u32 wdidx;
+ u8 wdma_hang_count;
+ u8 qdma_hang_count;
+ u8 adma_hang_count;
+ } reset;
};
/* struct mtk_mac - the structure that holds the info about the MACs of the

View File

@ -0,0 +1,124 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:32 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks
Introduce reset and reset_complete wlan callback to schedule WLAN driver
reset when ethernet/wed driver is resetting.
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3645,6 +3645,11 @@ static void mtk_pending_work(struct work
set_bit(MTK_RESETTING, &eth->state);
mtk_prepare_for_reset(eth);
+ mtk_wed_fe_reset();
+ /* Run again reset preliminary configuration in order to avoid any
+ * possible race during FE reset since it can run releasing RTNL lock.
+ */
+ mtk_prepare_for_reset(eth);
/* stop all devices to make sure that dma is properly shut down */
for (i = 0; i < MTK_MAC_COUNT; i++) {
@@ -3682,6 +3687,8 @@ static void mtk_pending_work(struct work
clear_bit(MTK_RESETTING, &eth->state);
+ mtk_wed_fe_reset_complete();
+
rtnl_unlock();
}
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device *
iounmap(reg);
}
+void mtk_wed_fe_reset(void)
+{
+ int i;
+
+ mutex_lock(&hw_lock);
+
+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+ struct mtk_wed_hw *hw = hw_list[i];
+ struct mtk_wed_device *dev = hw->wed_dev;
+ int err;
+
+ if (!dev || !dev->wlan.reset)
+ continue;
+
+ /* reset callback blocks until WLAN reset is completed */
+ err = dev->wlan.reset(dev);
+ if (err)
+ dev_err(dev->dev, "wlan reset failed: %d\n", err);
+ }
+
+ mutex_unlock(&hw_lock);
+}
+
+void mtk_wed_fe_reset_complete(void)
+{
+ int i;
+
+ mutex_lock(&hw_lock);
+
+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+ struct mtk_wed_hw *hw = hw_list[i];
+ struct mtk_wed_device *dev = hw->wed_dev;
+
+ if (!dev || !dev->wlan.reset_complete)
+ continue;
+
+ dev->wlan.reset_complete(dev);
+ }
+
+ mutex_unlock(&hw_lock);
+}
+
static struct mtk_wed_hw *
mtk_wed_assign(struct mtk_wed_device *dev)
{
--- a/drivers/net/ethernet/mediatek/mtk_wed.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node *
void mtk_wed_exit(void);
int mtk_wed_flow_add(int index);
void mtk_wed_flow_remove(int index);
+void mtk_wed_fe_reset(void);
+void mtk_wed_fe_reset_complete(void);
#else
static inline void
mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i
{
}
+static inline void mtk_wed_fe_reset(void)
+{
+}
+
+static inline void mtk_wed_fe_reset_complete(void)
+{
+}
#endif
#ifdef CONFIG_DEBUG_FS
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -151,6 +151,8 @@ struct mtk_wed_device {
void (*release_rx_buf)(struct mtk_wed_device *wed);
void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
struct mtk_wed_wo_rx_stats *stats);
+ int (*reset)(struct mtk_wed_device *wed);
+ void (*reset_complete)(struct mtk_wed_device *wed);
} wlan;
#endif
};

View File

@ -0,0 +1,106 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Mon, 5 Dec 2022 12:34:42 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback
This patch adds reset parameter to mtk_wed_rx_ring_setup signature
in order to align rx_ring_setup callback to tx_ring_setup one introduced
in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to
tx_ring_setup callback")'
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -1259,7 +1259,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
}
static int
-mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+ bool reset)
{
u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
struct mtk_wed_ring *wdma;
@@ -1268,8 +1269,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
return -EINVAL;
wdma = &dev->tx_wdma[idx];
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
- true))
+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+ desc_size, true))
return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
@@ -1279,6 +1280,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
+ if (reset)
+ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true);
+
if (!idx) {
wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
wdma->desc_phys);
@@ -1618,18 +1622,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed
}
static int
-mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
+ bool reset)
{
struct mtk_wed_ring *ring = &dev->rx_ring[idx];
if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
return -EINVAL;
- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
- sizeof(*ring->desc), false))
+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
+ sizeof(*ring->desc), false))
return -ENOMEM;
- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
+ reset))
return -ENOMEM;
ring->reg_base = MTK_WED_RING_RX_DATA(idx);
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -162,7 +162,7 @@ struct mtk_wed_ops {
int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
void __iomem *regs, bool reset);
int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
+ void __iomem *regs, bool reset);
int (*txfree_ring_setup)(struct mtk_wed_device *dev,
void __iomem *regs);
int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
(_dev)->ops->irq_get(_dev, _mask)
#define mtk_wed_device_irq_set_mask(_dev, _mask) \
(_dev)->ops->irq_set_mask(_dev, _mask)
-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset)
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
(_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
@@ -251,7 +251,7 @@ static inline bool mtk_wed_device_active
#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
#define mtk_wed_device_irq_get(_dev, _mask) 0
#define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
#define mtk_wed_device_stop(_dev) do {} while (0)

Some files were not shown because too many files have changed in this diff Show More