Merge Official Source

This commit is contained in:
AmadeusGhost 2021-01-23 16:25:16 +08:00
commit 05cb83a625
94 changed files with 3081 additions and 1009 deletions

View File

@ -12,8 +12,8 @@ include $(INCLUDE_DIR)/version.mk
include $(INCLUDE_DIR)/feeds.mk
PKG_NAME:=base-files
PKG_RELEASE:=246
PKG_FLAGS:=nonshared
PKG_RELEASE:=$(COMMITCOUNT)
PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
PKG_BUILD_DEPENDS:=usign/host ucert/host

View File

@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=uboot-envtools
PKG_DISTNAME:=u-boot
PKG_VERSION:=2020.04
PKG_RELEASE:=20
PKG_RELEASE:=$(AUTORELEASE)
PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \

View File

@ -48,6 +48,7 @@ linksys,ea7300-v2|\
linksys,ea7500-v2|\
xiaomi,mi-router-3g|\
xiaomi,mi-router-3-pro|\
xiaomi,mi-router-4|\
xiaomi,mi-router-ac2100|\
xiaomi,redmi-router-ac2100)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x20000"

View File

@ -1,68 +0,0 @@
#
# Copyright (C) 2007-2010 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=iperf
PKG_VERSION:=2.0.13
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_HASH:=c88adec966096a81136dda91b4bd19c27aae06df4d45a7f547a8e50d723778ad
PKG_SOURCE_URL:=@SF/iperf2
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=BSD-3-Clause
PKG_BUILD_PARALLEL:=1
PKG_CONFIG_DEPENDS:=CONFIG_IPERF_ENABLE_MULTICAST
include $(INCLUDE_DIR)/uclibc++.mk
include $(INCLUDE_DIR)/package.mk
define Package/iperf
SECTION:=net
CATEGORY:=Network
DEPENDS:= $(CXX_DEPENDS) +libpthread
TITLE:=Internet Protocol bandwidth measuring tool
URL:=http://sourceforge.net/projects/iperf2/
endef
define Package/iperf/description
Iperf is a modern alternative for measuring TCP and UDP bandwidth
performance, allowing the tuning of various parameters and
characteristics.
endef
define Package/iperf/config
config IPERF_ENABLE_MULTICAST
depends on PACKAGE_iperf
bool "Enable multicast support"
endef
TARGET_CFLAGS += -D_GNU_SOURCE
ifeq ($(CONFIG_IPERF_ENABLE_MULTICAST),y)
CONFIGURE_ARGS += --enable-multicast
else
CONFIGURE_ARGS += --disable-multicast
endif
ifeq ($(CONFIG_IPV6),)
CONFIGURE_ARGS += --disable-ipv6
endif
CONFIGURE_VARS += CXXFLAGS="$$$$CXXFLAGS -fno-rtti"
CONFIGURE_VARS += LIBS="-lpthread -lm"
define Package/iperf/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/iperf $(1)/usr/bin/iperf
endef
$(eval $(call BuildPackage,iperf))

View File

@ -1,20 +0,0 @@
--- a/src/Listener.cpp
+++ b/src/Listener.cpp
@@ -723,6 +723,7 @@ int Listener::L2_setup (void) {
// Now optimize packet flow up the raw socket
// Establish the flow BPF to forward up only "connected" packets to this raw socket
+#ifdef HAVE_IPV6
if (l->sa_family == AF_INET6) {
#ifdef HAVE_IPV6
struct in6_addr *v6peer = SockAddr_get_in6_addr(&server->peer);
@@ -740,6 +741,9 @@ int Listener::L2_setup (void) {
return -1;
#endif /* HAVE_IPV6 */
} else {
+#else
+ {
+#endif
rc = SockAddr_v4_Connect_BPF(server->mSock, ((struct sockaddr_in *)(l))->sin_addr.s_addr, ((struct sockaddr_in *)(p))->sin_addr.s_addr, ((struct sockaddr_in *)(l))->sin_port, ((struct sockaddr_in *)(p))->sin_port);
WARN_errno( rc == SOCKET_ERROR, "l2 connect ip bpf");
}

View File

@ -1,12 +0,0 @@
--- a/config.h.in
+++ b/config.h.in
@@ -360,7 +360,9 @@
#undef _REENTRANT
/* */
+#ifndef __cplusplus
#undef bool
+#endif
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

View File

@ -1,83 +0,0 @@
#
# Copyright (C) 2007-2010 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=iperf
PKG_VERSION:=3.9
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.es.net/pub/iperf
PKG_HASH:=24b63a26382325f759f11d421779a937b63ca1bc17c44587d2fcfedab60ac038
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=BSD-3-Clause
PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
PKG_FIXUP:=autoreconf
include $(INCLUDE_DIR)/package.mk
DISABLE_NLS:=
define Package/iperf3/default
SECTION:=net
CATEGORY:=Network
TITLE:=Internet Protocol bandwidth measuring tool
URL:=https://github.com/esnet/iperf
endef
define Package/iperf3
$(call Package/iperf3/default)
VARIANT:=nossl
endef
define Package/iperf3-ssl
$(call Package/iperf3/default)
TITLE+= with iperf_auth support
VARIANT:=ssl
DEPENDS:= +libopenssl
endef
TARGET_CFLAGS += -D_GNU_SOURCE
CONFIGURE_ARGS += --disable-shared
ifeq ($(BUILD_VARIANT),ssl)
CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr"
else
CONFIGURE_ARGS += --without-openssl
endif
MAKE_FLAGS += noinst_PROGRAMS=
define Package/iperf3/description
Iperf is a modern alternative for measuring TCP and UDP bandwidth
performance, allowing the tuning of various parameters and
characteristics.
endef
# autoreconf fails if the README file isn't present
define Build/Prepare
$(call Build/Prepare/Default)
touch $(PKG_BUILD_DIR)/README
endef
define Package/iperf3/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/
endef
define Package/iperf3-ssl/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/
endef
$(eval $(call BuildPackage,iperf3))
$(eval $(call BuildPackage,iperf3-ssl))

View File

@ -408,6 +408,32 @@ endef
# file extension
ext=$(word $(words $(subst ., ,$(1))),$(subst ., ,$(1)))
# Count Git commits of a package
# $(1) => if non-empty: count commits since last ": [uU]pdate to " or ": [bB]ump to " in commit message
define commitcount
$(shell \
if git log -1 >/dev/null 2>/dev/null; then \
if [ -n "$(1)" ]; then \
last_bump="$$(git log --pretty=format:'%h %s' . | \
grep --max-count=1 -e ': [uU]pdate to ' -e ': [bB]ump to ' | \
cut -f 1 -d ' ')"; \
fi; \
if [ -n "$$last_bump" ]; then \
echo -n $$(($$(git rev-list --count "$$last_bump..HEAD" .) + 1)); \
else \
echo -n $$(($$(git rev-list --count HEAD .) + 1)); \
fi; \
else \
secs="$$(($(SOURCE_DATE_EPOCH) % 86400))"; \
date="$$(date --utc --date="@$(SOURCE_DATE_EPOCH)" "+%y%m%d")"; \
printf '%s.%05d' "$$date" "$$secs"; \
fi; \
)
endef
COMMITCOUNT = $(if $(DUMP),,$(call commitcount))
AUTORELEASE = $(if $(DUMP),,$(call commitcount,1))
all:
FORCE: ;
.PHONY: FORCE

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
aliases {

View File

@ -22,7 +22,9 @@
partition@70000 {
label = "firmware";
reg = <0x070000 0xf80000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x33373031>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@ff0000 {

View File

@ -22,7 +22,9 @@
partition@70000 {
label = "firmware";
reg = <0x070000 0x780000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x33373030>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@7f0000 {

View File

@ -23,7 +23,9 @@
partition@70000 {
label = "firmware";
reg = <0x070000 0xf80000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x33373031>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@ff0000 {

View File

@ -23,7 +23,9 @@
partition@70000 {
label = "firmware";
reg = <0x070000 0xf80000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x33373031>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@ff0000 {

View File

@ -22,7 +22,9 @@
partition@70000 {
label = "firmware";
reg = <0x070000 0xf80000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x33373031>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@ff0000 {

View File

@ -23,7 +23,9 @@
partition@70000 {
label = "firmware";
reg = <0x070000 0xf80000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x33373031>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@ff0000 {

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "engenius,enh202-v1", "qca,ar7240";
@ -80,7 +81,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "netgear,wnr1000-v2", "qca,ar7240";
@ -158,7 +159,9 @@
partition@50000 {
label = "firmware";
reg = <0x50000 0x3a0000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x31303031>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@3f0000 {

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
aliases {
@ -89,7 +90,9 @@
};
partition@50000 {
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x32303631>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
reg = <0x50000 0x3a0000>;
label = "firmware";
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "netgear,wnr2000-v3", "qca,ar7241";
@ -161,7 +162,9 @@
partition@50000 {
label = "firmware";
reg = <0x50000 0x3a0000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x32303033>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@3f0000 {

View File

@ -22,7 +22,9 @@
partition@50000 {
label = "firmware";
reg = <0x50000 0xfa0000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x32323030>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@ff0000 {

View File

@ -22,7 +22,9 @@
partition@50000 {
label = "firmware";
reg = <0x50000 0x7a0000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x32323030>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
art: partition@7f0000 {

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
chosen {

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "engenius,eap350-v1", "qca,ar7242";
@ -59,7 +60,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "engenius,ecb350-v1", "qca,ar7242";
@ -59,7 +60,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
model = "Engenius EAP300 v2";
@ -60,7 +61,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
model = "Engenius ENS202EXT v1";
@ -70,7 +71,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
model = "PISEN WMB001N";
@ -106,7 +107,8 @@
partition@0 {
reg = <0x0 0x0>;
label = "firmware";
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
};
};
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
aliases {
@ -47,7 +48,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
chosen {
@ -161,7 +162,9 @@
partition@6c0000 {
label = "firmware";
reg = <0x6c0000 0x1900000>;
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x33373033>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};
partition@1fc0000 {

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "engenius,enstationac-v1", "qca,qca9557";
@ -70,7 +71,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
aliases {
@ -85,7 +86,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -48,17 +48,23 @@ CONFIG_BLK_PM=y
CONFIG_CAVIUM_TX2_ERRATUM_219=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640"
CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640 console=ttyS0,115200"
CONFIG_CMDLINE_FORCE=y
CONFIG_COMMON_CLK=y
CONFIG_CPU_RMAP=y
CONFIG_CRC16=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_NULL2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_REMAP=y
@ -114,10 +120,13 @@ CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
# CONFIG_JFFS2_FS is not set
CONFIG_LEDS_GPIO=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BCM_UNIMAC=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
@ -129,6 +138,12 @@ CONFIG_MTD_NAND_BRCMNAND=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPLIT_CFE_BOOTFS=y
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
@ -180,6 +195,7 @@ CONFIG_RWSEM_SPIN_ON_OWNER=y
# CONFIG_SERIAL_8250 is not set
CONFIG_SERIAL_BCM63XX=y
CONFIG_SERIAL_BCM63XX_CONSOLE=y
CONFIG_SGL_ALLOC=y
CONFIG_SMP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
@ -194,8 +210,18 @@ CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UBIFS_FS_ZSTD=y
CONFIG_UNMAP_KERNEL_AT_EL0=y
CONFIG_USB_SUPPORT=y
CONFIG_VMAP_STACK=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y

View File

@ -13,6 +13,26 @@ define Build/bcm4908kernel
mv $@.new $@
endef
define Build/bcm4908img
rm -fr $@-bootfs
mkdir -p $@-bootfs
cp -r $(DEVICE_NAME)/* $@-bootfs/
touch $@-bootfs/1-dummy
cp $(DTS_DIR)/$(firstword $(DEVICE_DTS)).dtb $@-bootfs/94908.dtb
cp $(KDIR)/bcm63xx-cfe/$(subst _,$(comma),$(DEVICE_NAME))/cferam.000 $@-bootfs/
cp $(IMAGE_KERNEL) $@-bootfs/vmlinux.lz
$(STAGING_DIR_HOST)/bin/mkfs.jffs2 --pad --little-endian --squash-uids -v -e 128KiB -o $@-bootfs.jffs2 -d $@-bootfs -m none -n
$(STAGING_DIR_HOST)/bin/bcm4908img create $@.new -f $@-bootfs.jffs2 -a 0x20000 -f $@
mv $@.new $@
endef
define Build/bcm4908asus
$(STAGING_DIR_HOST)/bin/bcm4908asus create -i $@ -p $(ASUS_PRODUCTID) -b $(ASUS_BUILD_NO) -f $(ASUS_FW_REV) -e $(ASUS_EXT_NO)
endef
DEVICE_VARS += ASUS_PRODUCTID ASUS_BUILD_NO ASUS_FW_REV ASUS_EXT_NO
define Device/Default
KERNEL := kernel-bin | bcm4908lzma | bcm4908kernel
KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
@ -30,6 +50,11 @@ define Device/asus_gt-ac5300
DEVICE_MODEL := GT-AC5300
DEVICE_DTS := broadcom/bcm4908/bcm4908-asus-gt-ac5300
IMAGES := bin
IMAGE/bin := append-ubi | bcm4908img | bcm4908asus
ASUS_PRODUCTID := GT-AC5300
ASUS_BUILD_NO := 384
ASUS_FW_REV := 3.0.0.4
ASUS_EXT_NO := 21140
endef
TARGET_DEVICES += asus_gt-ac5300
@ -38,6 +63,7 @@ define Device/netgear_r8000p
DEVICE_MODEL := R8000P
DEVICE_DTS := broadcom/bcm4908/bcm4906-netgear-r8000p
IMAGES := bin
IMAGE/bin := append-ubi | bcm4908img
endef
TARGET_DEVICES += netgear_r8000p

View File

@ -0,0 +1,2 @@
@(#) $imageversion: HND1731918 $
@(#) $imageversion: HND1731918 $

View File

@ -0,0 +1 @@
HND1731918

View File

@ -0,0 +1,4 @@
@(#) $imageversion: 5024HNDrc11R8000P2602103 $
@(#) $imageversion: 5024HNDrc11R8000P2602103 $
@(#) $changelist: Changelist: REL_502HND04rc11_BISON04T_REL_7_14_170_34Revision: 765096 $
@(#) $changelist: Changelist: REL_502HND04rc11_BISON04T_REL_7_14_170_34Revision: 765096 $

View File

@ -0,0 +1 @@
5024HNDrc11R8000P2602103

View File

@ -1,6 +1,6 @@
From 12cda92893ea57cdd84a8ccfcc05946d7f3a1cd7 Mon Sep 17 00:00:00 2001
From 961c38974fa5b34d6232d7485120e4392d279ab4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 12 Jan 2021 12:56:58 +0100
Date: Wed, 13 Jan 2021 12:14:06 +0100
Subject: [PATCH] arm64: dts: broadcom: bcm4908: describe internal switch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
@ -15,6 +15,7 @@ internal MDIO.
CPU port and Ethernet interface remain to be documented.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../bcm4908/bcm4908-asus-gt-ac5300.dts | 51 +++++++++++
.../boot/dts/broadcom/bcm4908/bcm4908.dtsi | 85 ++++++++++++++++++-
@ -97,7 +98,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
};
+
+ switch@80000 {
+ compatible = "simple-mfd";
+ compatible = "simple-bus";
+ #size-cells = <1>;
+ #address-cells = <1>;
+ ranges = <0 0x80000 0x50000>;

View File

@ -1,6 +1,6 @@
From 11a7fb140af5cfa706a8d9c0a309247f020a8d0c Mon Sep 17 00:00:00 2001
From edcf90801c8e58bd6306d85a4e714a6f09f452df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Mon, 11 Jan 2021 08:15:35 +0100
Date: Wed, 13 Jan 2021 12:15:47 +0100
Subject: [PATCH] arm64: dts: broadcom: bcm4908: describe PMB block
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
@ -10,10 +10,7 @@ PMB (Power Management Bus) controls powering connected devices (e.g.
PCIe, USB, SATA). In BCM4908 it's a part of the PROCMON block.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
Florian: this patch is based on top of the
[PATCH] arm64: dts: broadcom: bcm4908: describe internal switch
one. Both modify "ranges".
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
.../boot/dts/broadcom/bcm4908/bcm4908.dtsi | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
@ -35,7 +32,7 @@ one. Both modify "ranges".
};
+
+ procmon: syscon@280000 {
+ compatible = "simple-mfd";
+ compatible = "simple-bus";
+ reg = <0x280000 0x1000>;
+ ranges;
+

View File

@ -1,7 +1,10 @@
From c149974b2ae2e2296c66262a4ee797c06c39982b Mon Sep 17 00:00:00 2001
From 149ae80b1d50e7db5ac7df1cdf0820017b70e716 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 14 Jan 2021 11:33:01 +0100
Subject: [PATCH] soc: brcmstb: add stubs for getting platform IDs
Date: Thu, 14 Jan 2021 11:53:18 +0100
Subject: [PATCH] soc: bcm: brcmstb: add stubs for getting platform IDs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some brcmstb drivers may be shared with other SoC families. E.g. the
same USB PHY block is shared by brcmstb and BCM4908.
@ -14,27 +17,38 @@ stubs for:
With this change PHY_BRCM_USB will not have to unconditionally select
SOC_BRCMSTB anymore.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/linux/soc/brcmstb/brcmstb.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--- a/include/linux/soc/brcmstb/brcmstb.h
+++ b/include/linux/soc/brcmstb/brcmstb.h
@@ -12,6 +12,8 @@ static inline u32 BRCM_REV(u32 reg)
@@ -2,6 +2,8 @@
#ifndef __BRCMSTB_SOC_H
#define __BRCMSTB_SOC_H
+#include <linux/kconfig.h>
+
static inline u32 BRCM_ID(u32 reg)
{
return reg >> 28 ? reg >> 16 : reg >> 8;
@@ -12,6 +14,8 @@ static inline u32 BRCM_REV(u32 reg)
return reg & 0xff;
}
+#ifdef CONFIG_SOC_BRCMSTB
+#if IS_ENABLED(CONFIG_SOC_BRCMSTB)
+
/*
* Helper functions for getting family or product id from the
* SoC driver.
@@ -19,4 +21,18 @@ static inline u32 BRCM_REV(u32 reg)
@@ -19,4 +23,16 @@ static inline u32 BRCM_REV(u32 reg)
u32 brcmstb_get_family_id(void);
u32 brcmstb_get_product_id(void);
+#else
+
+static inline u32 brcmstb_get_family_id(void)
+{
+ return 0;
@ -44,7 +58,6 @@ SOC_BRCMSTB anymore.
+{
+ return 0;
+}
+
+#endif
+
#endif /* __BRCMSTB_SOC_H */

View File

@ -0,0 +1,113 @@
From 4fdbaa5a3dbe761b231c13feaa53242aae3306cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Fri, 15 Jan 2021 15:23:02 +0100
Subject: [PATCH 1/3] dt-bindings: mtd: move partition binding to its own file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Single partition binding is quite common and may be:
1. Used by multiple parsers
2. Extended for more specific cases
Move it to separated file to avoid code duplication.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
.../mtd/partitions/fixed-partitions.yaml | 33 +------------
.../bindings/mtd/partitions/partition.yaml | 47 +++++++++++++++++++
2 files changed, 48 insertions(+), 32 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mtd/partitions/partition.yaml
--- a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
+++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
@@ -27,38 +27,7 @@ properties:
patternProperties:
"@[0-9a-f]+$":
- description: node describing a single flash partition
- type: object
-
- properties:
- reg:
- description: partition's offset and size within the flash
- maxItems: 1
-
- label:
- description: The label / name for this partition. If omitted, the label
- is taken from the node name (excluding the unit address).
-
- read-only:
- description: This parameter, if present, is a hint that this partition
- should only be mounted read-only. This is usually used for flash
- partitions containing early-boot firmware images or data which should
- not be clobbered.
- type: boolean
-
- lock:
- description: Do not unlock the partition at initialization time (not
- supported on all devices)
- type: boolean
-
- slc-mode:
- description: This parameter, if present, allows one to emulate SLC mode
- on a partition attached to an MLC NAND thus making this partition
- immune to paired-pages corruptions
- type: boolean
-
- required:
- - reg
+ $ref: "partition.yaml#"
required:
- "#address-cells"
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/partitions/partition.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Partition
+
+description: |
+ This binding describes a single flash partition. Each partition must have its
+ relative offset and size specified. Depending on partition function extra
+ properties can be used.
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+properties:
+ reg:
+ description: partition's offset and size within the flash
+ maxItems: 1
+
+ label:
+ description: The label / name for this partition. If omitted, the label
+ is taken from the node name (excluding the unit address).
+
+ read-only:
+ description: This parameter, if present, is a hint that this partition
+ should only be mounted read-only. This is usually used for flash
+ partitions containing early-boot firmware images or data which should
+ not be clobbered.
+ type: boolean
+
+ lock:
+ description: Do not unlock the partition at initialization time (not
+ supported on all devices)
+ type: boolean
+
+ slc-mode:
+ description: This parameter, if present, allows one to emulate SLC mode
+ on a partition attached to an MLC NAND thus making this partition
+ immune to paired-pages corruptions
+ type: boolean
+
+required:
+ - reg
+
+additionalProperties: true

View File

@ -0,0 +1,89 @@
From 4f740351484e88bcea3776578288b6ec400829c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Fri, 15 Jan 2021 16:01:04 +0100
Subject: [PATCH 2/3] dt-bindings: mtd: add binding from BCM4908 partitions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BCM4908 uses fixed partitions layout but function of some partitions may
vary. Some devices use multiple firmware partitions and those should be
marked to let system discover their purpose.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
.../partitions/brcm,bcm4908-partitions.yaml | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/partitions/brcm,bcm4908-partitions.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM4908 partitioning
+
+description: |
+ Broadcom BCM4908 CFE bootloader supports two firmware partitions. One is used
+ for regular booting, the other is treated as fallback.
+
+ This binding allows defining all fixed partitions and marking those containing
+ firmware. System can use that information e.g. for booting or flashing
+ purposes.
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+properties:
+ compatible:
+ const: brcm,bcm4908-partitions
+
+ "#address-cells": true
+
+ "#size-cells": true
+
+patternProperties:
+ "@[0-9a-f]+$":
+ allOf:
+ - $ref: "partition.yaml#"
+ - properties:
+ compatible:
+ const: brcm,bcm4908-firmware
+
+required:
+ - "#address-cells"
+ - "#size-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ partitions {
+ compatible = "brcm,bcm4908-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "cferom";
+ reg = <0x0 0x100000>;
+ };
+
+ partition@100000 {
+ compatible = "brcm,bcm4908-firmware";
+ reg = <0x100000 0xf00000>;
+ };
+
+ partition@1000000 {
+ compatible = "brcm,bcm4908-firmware";
+ reg = <0x1000000 0xf00000>;
+ };
+
+ partition@1f00000 {
+ label = "calibration";
+ reg = <0x1f00000 0x100000>;
+ };
+ };

View File

@ -0,0 +1,191 @@
From db18357719613cc40234300b10e28e4dfa075375 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Fri, 15 Jan 2021 16:23:01 +0100
Subject: [PATCH 3/3] mtd: parsers: ofpart: support BCM4908 fixed partitions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BCM4908 partitioning is based on fixed layout but allows specifying
multiple firmware partitions. It requires detecting which firmware
partition was used for booting current kernel.
To support such cases without duplicating a lot of code (without copying
most of the ofpart.c code) support for post-parsing callback was added.
BCM4908 callback simply reads offset of currently used firmware
partition from the DT. Bootloader specifies it using the "brcm_blparms"
property.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/mtd/parsers/Makefile | 1 +
drivers/mtd/parsers/bcm4908-partitions.c | 62 ++++++++++++++++++++++++
drivers/mtd/parsers/bcm4908-partitions.h | 7 +++
drivers/mtd/parsers/ofpart.c | 28 ++++++++++-
4 files changed, 96 insertions(+), 2 deletions(-)
create mode 100644 drivers/mtd/parsers/bcm4908-partitions.c
create mode 100644 drivers/mtd/parsers/bcm4908-partitions.h
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm6
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
+obj-$(CONFIG_MTD_OF_PARTS) += bcm4908-partitions.o
obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
--- /dev/null
+++ b/drivers/mtd/parsers/bcm4908-partitions.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
+#include <linux/mtd/partitions.h>
+
+#define BLPARAMS_FW_OFFSET "NAND_RFS_OFS"
+
+static long long bcm4908_partitions_fw_offset(void)
+{
+ struct device_node *root;
+ struct property *prop;
+ const char *s;
+
+ root = of_find_node_by_path("/");
+ if (!root)
+ return -ENOENT;
+
+ of_property_for_each_string(root, "brcm_blparms", prop, s) {
+ size_t len = strlen(BLPARAMS_FW_OFFSET);
+ unsigned long offset;
+ int err;
+
+ if (strncmp(s, BLPARAMS_FW_OFFSET, len) || s[len] != '=')
+ continue;
+
+ err = kstrtoul(s + len + 1, 0, &offset);
+ if (err) {
+ pr_err("failed to parse %s\n", s + len + 1);
+ return err;
+ }
+
+ return offset << 10;
+ }
+
+ return -ENOENT;
+}
+
+int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts)
+{
+ long long fw_offset;
+ int i;
+
+ fw_offset = bcm4908_partitions_fw_offset();
+
+ for (i = 0; i < nr_parts; i++) {
+ if (of_device_is_compatible(parts[i].of_node, "brcm,bcm4908-firmware")) {
+ if (fw_offset < 0 || parts[i].offset == fw_offset)
+ parts[i].name = "firmware";
+ else
+ parts[i].name = "backup";
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+++ b/drivers/mtd/parsers/bcm4908-partitions.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __BCM4908_PARTITIONS_H
+#define __BCM4908_PARTITIONS_H
+
+int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
+
+#endif
--- a/drivers/mtd/parsers/ofpart.c
+++ b/drivers/mtd/parsers/ofpart.c
@@ -16,6 +16,18 @@
#include <linux/slab.h>
#include <linux/mtd/partitions.h>
+#include "bcm4908-partitions.h"
+
+struct fixed_partitions_quirks {
+ int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
+};
+
+struct fixed_partitions_quirks bcm4908_partitions_quirks = {
+ .post_parse = bcm4908_partitions_post_parse,
+};
+
+static const struct of_device_id parse_ofpart_match_table[];
+
static bool node_has_compatible(struct device_node *pp)
{
return of_get_property(pp, "compatible", NULL);
@@ -25,6 +37,8 @@ static int parse_fixed_partitions(struct
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
+ const struct fixed_partitions_quirks *quirks;
+ const struct of_device_id *of_id;
struct mtd_partition *parts;
struct device_node *mtd_node;
struct device_node *ofpart_node;
@@ -33,7 +47,6 @@ static int parse_fixed_partitions(struct
int nr_parts, i, ret = 0;
bool dedicated = true;
-
/* Pull of_node from the master device node */
mtd_node = mtd_get_of_node(master);
if (!mtd_node)
@@ -50,11 +63,16 @@ static int parse_fixed_partitions(struct
master->name, mtd_node);
ofpart_node = mtd_node;
dedicated = false;
- } else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) {
+ }
+
+ of_id = of_match_node(parse_ofpart_match_table, ofpart_node);
+ if (dedicated && !of_id) {
/* The 'partitions' subnode might be used by another parser */
return 0;
}
+ quirks = of_id ? of_id->data : NULL;
+
/* First count the subnodes */
nr_parts = 0;
for_each_child_of_node(ofpart_node, pp) {
@@ -123,6 +141,9 @@ static int parse_fixed_partitions(struct
if (!nr_parts)
goto ofpart_none;
+ if (quirks && quirks->post_parse)
+ quirks->post_parse(master, parts, nr_parts);
+
*pparts = parts;
return nr_parts;
@@ -137,7 +158,10 @@ ofpart_none:
}
static const struct of_device_id parse_ofpart_match_table[] = {
+ /* Generic */
{ .compatible = "fixed-partitions" },
+ /* Customized */
+ { .compatible = "brcm,bcm4908-partitions", .data = &bcm4908_partitions_quirks, },
{},
};
MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);

View File

@ -0,0 +1,132 @@
From 28d11220a92e9fc4d7d1b8e52dc1c48980e336a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Wed, 20 Jan 2021 20:34:00 +0100
Subject: [PATCH] arm64: dts: broadcom: bcm4908: describe USB PHY
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BCM4908 uses slightly modified STB family USB PHY. It handles OHCI/EHCI
and XHCI. It requires powering up using the PMB.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
.../bcm4908/bcm4906-netgear-r8000p.dts | 17 +++++++++++++
.../bcm4908/bcm4908-asus-gt-ac5300.dts | 16 ++++++++++++
.../boot/dts/broadcom/bcm4908/bcm4908.dtsi | 25 ++++++++++++++++---
3 files changed, 54 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts
@@ -26,6 +26,23 @@
};
};
+&usb_phy {
+ brcm,ioc = <1>;
+ status = "okay";
+};
+
+&ehci {
+ status = "okay";
+};
+
+&ohci {
+ status = "okay";
+};
+
+&xhci {
+ status = "okay";
+};
+
&nandcs {
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts
@@ -44,6 +44,22 @@
};
};
+&usb_phy {
+ status = "okay";
+};
+
+&ehci {
+ status = "okay";
+};
+
+&ohci {
+ status = "okay";
+};
+
+&xhci {
+ status = "okay";
+};
+
&ports {
port@0 {
label = "lan2";
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
@@ -2,6 +2,8 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/soc/bcm-pmb.h>
/dts-v1/;
@@ -110,24 +112,39 @@
#size-cells = <1>;
ranges = <0x00 0x00 0x80000000 0x281000>;
- usb@c300 {
+ usb_phy: usb-phy@c200 {
+ compatible = "brcm,bcm4908-usb-phy";
+ reg = <0xc200 0x100>;
+ reg-names = "crtl";
+ power-domains = <&pmb BCM_PMB_HOST_USB>;
+ dr_mode = "host";
+ brcm,has-xhci;
+ brcm,has-eohci;
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
+ ehci: usb@c300 {
compatible = "generic-ehci";
reg = <0xc300 0x100>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb_phy PHY_TYPE_USB2>;
status = "disabled";
};
- usb@c400 {
+ ohci: usb@c400 {
compatible = "generic-ohci";
reg = <0xc400 0x100>;
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb_phy PHY_TYPE_USB2>;
status = "disabled";
};
- usb@d000 {
+ xhci: usb@d000 {
compatible = "generic-xhci";
reg = <0xd000 0x8c8>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usb_phy PHY_TYPE_USB3>;
status = "disabled";
};
@@ -222,7 +239,7 @@
#address-cells = <1>;
#size-cells = <1>;
- power-controller@2800c0 {
+ pmb: power-controller@2800c0 {
compatible = "brcm,bcm4908-pmb";
reg = <0x2800c0 0x40>;
#power-domain-cells = <1>;

View File

@ -0,0 +1,69 @@
From e401e6fe9195eabfc6c81d8aed920a75b5d7987b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Wed, 20 Jan 2021 20:53:35 +0100
Subject: [PATCH] arm64: dts: broadcom: bcm4908: improve partitions description
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. Use proper bindings
2. Add missing partitions
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
.../bcm4908/bcm4906-netgear-r8000p.dts | 1 +
.../bcm4908/bcm4908-asus-gt-ac5300.dts | 27 ++++++++++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4906-netgear-r8000p.dts
@@ -62,6 +62,7 @@
};
partition@100000 {
+ compatible = "brcm,bcm4908-firmware";
label = "firmware";
reg = <0x100000 0x4400000>;
};
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts
@@ -121,7 +121,7 @@
#size-cells = <0>;
partitions {
- compatible = "fixed-partitions";
+ compatible = "brcm,bcm4908-partitions";
#address-cells = <1>;
#size-cells = <1>;
@@ -129,5 +129,30 @@
label = "cferom";
reg = <0x0 0x100000>;
};
+
+ partition@100000 {
+ compatible = "brcm,bcm4908-firmware";
+ reg = <0x100000 0x5700000>;
+ };
+
+ partition@5800000 {
+ compatible = "brcm,bcm4908-firmware";
+ reg = <0x5800000 0x5700000>;
+ };
+
+ partition@af00000 {
+ label = "misc1";
+ reg = <0xaf00000 0x800000>;
+ };
+
+ partition@b700000 {
+ label = "misc2";
+ reg = <0xb700000 0x4000000>;
+ };
+
+ partition@f700000 {
+ label = "data";
+ reg = <0xf700000 0x800000>;
+ };
};
};

View File

@ -0,0 +1,34 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Jan 2021 10:44:53 +0100
Subject: [PATCH] mtd: rawnand: brcmnand: disable WP on BCM4908
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BCM4908 contains NAND controller version 0x0701 (v7.1). It means that
NAND_WP should be available.
For some reason setting #WP on doesn't result in clearing NAND_STATUS_WP
status bit:
[ 1.077857] bcm63138_nand ff801800.nand: timeout on status poll (expected c0000040 got c00000c0)
[ 1.086832] bcm63138_nand ff801800.nand: nand #WP expected on
For now try working without touching #WP.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -38,7 +38,11 @@
* 1: NAND_WP is set by default, cleared for erase/write operations
* 2: NAND_WP is always cleared
*/
+#if IS_ENABLED(CONFIG_ARCH_BCM4908)
+static int wp_on = 0;
+#else
static int wp_on = 1;
+#endif
module_param(wp_on, int, 0444);
/***********************************************************************

View File

@ -1,9 +1,9 @@
From 1606f78dc82e4f311ca5844a0605a62cd141a072 Mon Sep 17 00:00:00 2001
From 9cbfea02c1dbee0afb9128f065e6e793672b9ff7 Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Mon, 30 Nov 2020 11:07:47 +0800
Subject: [PATCH] bcm63xx: batch process RX path
Date: Wed, 6 Jan 2021 22:42:02 +0800
Subject: [PATCH 1/7] bcm63xx_enet: batch process rx path
Use netif_receive_skb_list to batch process skb in RX.
Use netif_receive_skb_list to batch process rx skb.
Tested on BCM6328 320 MHz using iperf3 -M 512, increasing performance
by 12.5%.
@ -18,26 +18,28 @@ After:
[ 4] 0.00-30.00 sec 135 MBytes 37.7 Mbits/sec receiver
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -301,10 +301,12 @@ static int bcm_enet_receive_queue(struct
@@ -298,10 +298,12 @@ static void bcm_enet_refill_rx_timer(str
static int bcm_enet_receive_queue(struct net_device *dev, int budget)
{
struct bcm_enet_priv *priv;
+ struct list_head rx_list;
struct device *kdev;
int processed;
+ struct list_head rx_list;
priv = netdev_priv(dev);
+ INIT_LIST_HEAD(&rx_list);
kdev = &priv->pdev->dev;
processed = 0;
+ INIT_LIST_HEAD(&rx_list);
/* don't scan ring further than number of refilled
* descriptor */
@@ -393,10 +395,12 @@ static int bcm_enet_receive_queue(struct
@@ -392,10 +394,12 @@ static int bcm_enet_receive_queue(struct
skb->protocol = eth_type_trans(skb, dev);
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;

View File

@ -0,0 +1,68 @@
From 4c59b0f5543db80abbbe9efdd9b25e7899501db5 Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Wed, 6 Jan 2021 22:42:03 +0800
Subject: [PATCH 2/7] bcm63xx_enet: add BQL support
Add Byte Queue Limits support to reduce/remove bufferbloat in
bcm63xx_enet.
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -418,9 +418,11 @@ static int bcm_enet_receive_queue(struct
static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
{
struct bcm_enet_priv *priv;
+ unsigned int bytes;
int released;
priv = netdev_priv(dev);
+ bytes = 0;
released = 0;
while (priv->tx_desc_count < priv->tx_ring_size) {
@@ -457,10 +459,13 @@ static int bcm_enet_tx_reclaim(struct ne
if (desc->len_stat & DMADESC_UNDER_MASK)
dev->stats.tx_errors++;
+ bytes += skb->len;
dev_kfree_skb(skb);
released++;
}
+ netdev_completed_queue(dev, released, bytes);
+
if (netif_queue_stopped(dev) && released)
netif_wake_queue(dev);
@@ -627,6 +632,8 @@ bcm_enet_start_xmit(struct sk_buff *skb,
desc->len_stat = len_stat;
wmb();
+ netdev_sent_queue(dev, skb->len);
+
/* kick tx dma */
enet_dmac_writel(priv, priv->dma_chan_en_mask,
ENETDMAC_CHANCFG, priv->tx_chan);
@@ -1170,6 +1177,7 @@ static int bcm_enet_stop(struct net_devi
kdev = &priv->pdev->dev;
netif_stop_queue(dev);
+ netdev_reset_queue(dev);
napi_disable(&priv->napi);
if (priv->has_phy)
phy_stop(dev->phydev);
@@ -2343,6 +2351,7 @@ static int bcm_enetsw_stop(struct net_de
del_timer_sync(&priv->swphy_poll);
netif_stop_queue(dev);
+ netdev_reset_queue(dev);
napi_disable(&priv->napi);
del_timer_sync(&priv->rx_timeout);

View File

@ -0,0 +1,26 @@
From 375281d3a6dcabaa98f489ee412aedca6d99dffb Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Wed, 6 Jan 2021 22:42:04 +0800
Subject: [PATCH 3/7] bcm63xx_enet: add xmit_more support
Support bulking hardware TX queue by using netdev_xmit_more().
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -635,7 +635,8 @@ bcm_enet_start_xmit(struct sk_buff *skb,
netdev_sent_queue(dev, skb->len);
/* kick tx dma */
- enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ if (!netdev_xmit_more() || !priv->tx_desc_count)
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
ENETDMAC_CHANCFG, priv->tx_chan);
/* stop queue if no more desc available */

View File

@ -0,0 +1,45 @@
From c4a207865e7ea310dc146ff4aa1b0aa0c78d3fe1 Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Wed, 6 Jan 2021 22:42:05 +0800
Subject: [PATCH 4/7] bcm63xx_enet: alloc rx skb with NET_IP_ALIGN
Use netdev_alloc_skb_ip_align on newer SoCs with integrated switch
(enetsw) when refilling RX. Increases packet processing performance
by 30% (with netif_receive_skb_list).
Non-enetsw SoCs cannot function with the extra pad so continue to use
the regular netdev_alloc_skb.
Tested on BCM6328 320 MHz and iperf3 -M 512 to measure packet/sec
performance.
Before:
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-30.00 sec 120 MBytes 33.7 Mbits/sec 277 sender
[ 4] 0.00-30.00 sec 120 MBytes 33.5 Mbits/sec receiver
After (+netif_receive_skb_list):
[ 4] 0.00-30.00 sec 155 MBytes 43.3 Mbits/sec 354 sender
[ 4] 0.00-30.00 sec 154 MBytes 43.1 Mbits/sec receiver
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -238,7 +238,10 @@ static int bcm_enet_refill_rx(struct net
desc = &priv->rx_desc_cpu[desc_idx];
if (!priv->rx_skb[desc_idx]) {
- skb = netdev_alloc_skb(dev, priv->rx_skb_size);
+ if (priv->enet_is_sw)
+ skb = netdev_alloc_skb_ip_align(dev, priv->rx_skb_size);
+ else
+ skb = netdev_alloc_skb(dev, priv->rx_skb_size);
if (!skb)
break;
priv->rx_skb[desc_idx] = skb;

View File

@ -0,0 +1,142 @@
From 3d0b72654b0c8304424503e7560ee8635dd56340 Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Wed, 6 Jan 2021 22:42:06 +0800
Subject: [PATCH 5/7] bcm63xx_enet: consolidate rx SKB ring cleanup code
The rx SKB ring use the same code for cleanup at various points.
Combine them into a function to reduce lines of code.
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 72 ++++++--------------
1 file changed, 22 insertions(+), 50 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -861,6 +861,24 @@ static void bcm_enet_adjust_link(struct
priv->pause_tx ? "tx" : "off");
}
+static void bcm_enet_free_rx_skb_ring(struct device *kdev, struct bcm_enet_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct bcm_enet_desc *desc;
+
+ if (!priv->rx_skb[i])
+ continue;
+
+ desc = &priv->rx_desc_cpu[i];
+ dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_skb[i]);
+ }
+ kfree(priv->rx_skb);
+}
+
/*
* open callback, allocate dma rings & buffers and start rx operation
*/
@@ -1085,18 +1103,7 @@ static int bcm_enet_open(struct net_devi
return 0;
out:
- for (i = 0; i < priv->rx_ring_size; i++) {
- struct bcm_enet_desc *desc;
-
- if (!priv->rx_skb[i])
- continue;
-
- desc = &priv->rx_desc_cpu[i];
- dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
- DMA_FROM_DEVICE);
- kfree_skb(priv->rx_skb[i]);
- }
- kfree(priv->rx_skb);
+ bcm_enet_free_rx_skb_ring(kdev, priv);
out_free_tx_skb:
kfree(priv->tx_skb);
@@ -1175,7 +1182,6 @@ static int bcm_enet_stop(struct net_devi
{
struct bcm_enet_priv *priv;
struct device *kdev;
- int i;
priv = netdev_priv(dev);
kdev = &priv->pdev->dev;
@@ -1204,20 +1210,9 @@ static int bcm_enet_stop(struct net_devi
bcm_enet_tx_reclaim(dev, 1);
/* free the rx skb ring */
- for (i = 0; i < priv->rx_ring_size; i++) {
- struct bcm_enet_desc *desc;
-
- if (!priv->rx_skb[i])
- continue;
-
- desc = &priv->rx_desc_cpu[i];
- dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
- DMA_FROM_DEVICE);
- kfree_skb(priv->rx_skb[i]);
- }
+ bcm_enet_free_rx_skb_ring(kdev, priv);
/* free remaining allocated memory */
- kfree(priv->rx_skb);
kfree(priv->tx_skb);
dma_free_coherent(kdev, priv->rx_desc_alloc_size,
priv->rx_desc_cpu, priv->rx_desc_dma);
@@ -2308,18 +2303,7 @@ static int bcm_enetsw_open(struct net_de
return 0;
out:
- for (i = 0; i < priv->rx_ring_size; i++) {
- struct bcm_enet_desc *desc;
-
- if (!priv->rx_skb[i])
- continue;
-
- desc = &priv->rx_desc_cpu[i];
- dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
- DMA_FROM_DEVICE);
- kfree_skb(priv->rx_skb[i]);
- }
- kfree(priv->rx_skb);
+ bcm_enet_free_rx_skb_ring(kdev, priv);
out_free_tx_skb:
kfree(priv->tx_skb);
@@ -2348,7 +2332,6 @@ static int bcm_enetsw_stop(struct net_de
{
struct bcm_enet_priv *priv;
struct device *kdev;
- int i;
priv = netdev_priv(dev);
kdev = &priv->pdev->dev;
@@ -2371,20 +2354,9 @@ static int bcm_enetsw_stop(struct net_de
bcm_enet_tx_reclaim(dev, 1);
/* free the rx skb ring */
- for (i = 0; i < priv->rx_ring_size; i++) {
- struct bcm_enet_desc *desc;
-
- if (!priv->rx_skb[i])
- continue;
-
- desc = &priv->rx_desc_cpu[i];
- dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
- DMA_FROM_DEVICE);
- kfree_skb(priv->rx_skb[i]);
- }
+ bcm_enet_free_rx_skb_ring(kdev, priv);
/* free remaining allocated memory */
- kfree(priv->rx_skb);
kfree(priv->tx_skb);
dma_free_coherent(kdev, priv->rx_desc_alloc_size,
priv->rx_desc_cpu, priv->rx_desc_dma);

View File

@ -0,0 +1,347 @@
From d27de0ef5ef995df2cc5f5c006c0efcf0a62b6af Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Wed, 6 Jan 2021 22:42:07 +0800
Subject: [PATCH 6/7] bcm63xx_enet: convert to build_skb
We can increase the efficiency of rx path by using buffers to receive
packets then build SKBs around them just before passing into the network
stack. In contrast, preallocating SKBs too early reduces CPU cache
efficiency.
Check if we're in NAPI context when refilling RX. Normally we're almost
always running in NAPI context. Dispatch to napi_alloc_frag directly
instead of relying on netdev_alloc_frag which does the same but
with the overhead of local_bh_disable/enable.
Tested on BCM6328 320 MHz and iperf3 -M 512 to measure packet/sec
performance. Included netif_receive_skb_list and NET_IP_ALIGN
optimizations.
Before:
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 49.9 MBytes 41.9 Mbits/sec 197 sender
[ 4] 0.00-10.00 sec 49.3 MBytes 41.3 Mbits/sec receiver
After:
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-30.00 sec 171 MBytes 47.8 Mbits/sec 272 sender
[ 4] 0.00-30.00 sec 170 MBytes 47.6 Mbits/sec receiver
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 111 ++++++++++---------
drivers/net/ethernet/broadcom/bcm63xx_enet.h | 14 ++-
2 files changed, 71 insertions(+), 54 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -221,7 +221,7 @@ static void bcm_enet_mdio_write_mii(stru
/*
* refill rx queue
*/
-static int bcm_enet_refill_rx(struct net_device *dev)
+static int bcm_enet_refill_rx(struct net_device *dev, bool napi_mode)
{
struct bcm_enet_priv *priv;
@@ -229,29 +229,29 @@ static int bcm_enet_refill_rx(struct net
while (priv->rx_desc_count < priv->rx_ring_size) {
struct bcm_enet_desc *desc;
- struct sk_buff *skb;
- dma_addr_t p;
int desc_idx;
u32 len_stat;
desc_idx = priv->rx_dirty_desc;
desc = &priv->rx_desc_cpu[desc_idx];
- if (!priv->rx_skb[desc_idx]) {
- if (priv->enet_is_sw)
- skb = netdev_alloc_skb_ip_align(dev, priv->rx_skb_size);
+ if (!priv->rx_buf[desc_idx]) {
+ void *buf;
+
+ if (likely(napi_mode))
+ buf = napi_alloc_frag(priv->rx_frag_size);
else
- skb = netdev_alloc_skb(dev, priv->rx_skb_size);
- if (!skb)
+ buf = netdev_alloc_frag(priv->rx_frag_size);
+ if (unlikely(!buf))
break;
- priv->rx_skb[desc_idx] = skb;
- p = dma_map_single(&priv->pdev->dev, skb->data,
- priv->rx_skb_size,
- DMA_FROM_DEVICE);
- desc->address = p;
+ priv->rx_buf[desc_idx] = buf;
+ desc->address = dma_map_single(&priv->pdev->dev,
+ buf + priv->rx_buf_offset,
+ priv->rx_buf_size,
+ DMA_FROM_DEVICE);
}
- len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
+ len_stat = priv->rx_buf_size << DMADESC_LENGTH_SHIFT;
len_stat |= DMADESC_OWNER_MASK;
if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
@@ -291,7 +291,7 @@ static void bcm_enet_refill_rx_timer(str
struct net_device *dev = priv->net_dev;
spin_lock(&priv->rx_lock);
- bcm_enet_refill_rx(dev);
+ bcm_enet_refill_rx(dev, false);
spin_unlock(&priv->rx_lock);
}
@@ -321,6 +321,7 @@ static int bcm_enet_receive_queue(struct
int desc_idx;
u32 len_stat;
unsigned int len;
+ void *buf;
desc_idx = priv->rx_curr_desc;
desc = &priv->rx_desc_cpu[desc_idx];
@@ -366,16 +367,14 @@ static int bcm_enet_receive_queue(struct
}
/* valid packet */
- skb = priv->rx_skb[desc_idx];
+ buf = priv->rx_buf[desc_idx];
len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT;
/* don't include FCS */
len -= 4;
if (len < copybreak) {
- struct sk_buff *nskb;
-
- nskb = napi_alloc_skb(&priv->napi, len);
- if (!nskb) {
+ skb = napi_alloc_skb(&priv->napi, len);
+ if (unlikely(!skb)) {
/* forget packet, just rearm desc */
dev->stats.rx_dropped++;
continue;
@@ -383,14 +382,21 @@ static int bcm_enet_receive_queue(struct
dma_sync_single_for_cpu(kdev, desc->address,
len, DMA_FROM_DEVICE);
- memcpy(nskb->data, skb->data, len);
+ memcpy(skb->data, buf + priv->rx_buf_offset, len);
dma_sync_single_for_device(kdev, desc->address,
len, DMA_FROM_DEVICE);
- skb = nskb;
} else {
- dma_unmap_single(&priv->pdev->dev, desc->address,
- priv->rx_skb_size, DMA_FROM_DEVICE);
- priv->rx_skb[desc_idx] = NULL;
+ dma_unmap_single(kdev, desc->address,
+ priv->rx_buf_size, DMA_FROM_DEVICE);
+ priv->rx_buf[desc_idx] = NULL;
+
+ skb = build_skb(buf, priv->rx_frag_size);
+ if (unlikely(!skb)) {
+ skb_free_frag(buf);
+ dev->stats.rx_dropped++;
+ continue;
+ }
+ skb_reserve(skb, priv->rx_buf_offset);
}
skb_put(skb, len);
@@ -404,7 +410,7 @@ static int bcm_enet_receive_queue(struct
netif_receive_skb_list(&rx_list);
if (processed || !priv->rx_desc_count) {
- bcm_enet_refill_rx(dev);
+ bcm_enet_refill_rx(dev, true);
/* kick rx dma */
enet_dmac_writel(priv, priv->dma_chan_en_mask,
@@ -861,22 +867,22 @@ static void bcm_enet_adjust_link(struct
priv->pause_tx ? "tx" : "off");
}
-static void bcm_enet_free_rx_skb_ring(struct device *kdev, struct bcm_enet_priv *priv)
+static void bcm_enet_free_rx_buf_ring(struct device *kdev, struct bcm_enet_priv *priv)
{
int i;
for (i = 0; i < priv->rx_ring_size; i++) {
struct bcm_enet_desc *desc;
- if (!priv->rx_skb[i])
+ if (!priv->rx_buf[i])
continue;
desc = &priv->rx_desc_cpu[i];
- dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ dma_unmap_single(kdev, desc->address, priv->rx_buf_size,
DMA_FROM_DEVICE);
- kfree_skb(priv->rx_skb[i]);
+ skb_free_frag(priv->rx_buf[i]);
}
- kfree(priv->rx_skb);
+ kfree(priv->rx_buf);
}
/*
@@ -988,10 +994,10 @@ static int bcm_enet_open(struct net_devi
priv->tx_curr_desc = 0;
spin_lock_init(&priv->tx_lock);
- /* init & fill rx ring with skbs */
- priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *),
+ /* init & fill rx ring with buffers */
+ priv->rx_buf = kcalloc(priv->rx_ring_size, sizeof(void *),
GFP_KERNEL);
- if (!priv->rx_skb) {
+ if (!priv->rx_buf) {
ret = -ENOMEM;
goto out_free_tx_skb;
}
@@ -1008,8 +1014,8 @@ static int bcm_enet_open(struct net_devi
enet_dmac_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
ENETDMAC_BUFALLOC, priv->rx_chan);
- if (bcm_enet_refill_rx(dev)) {
- dev_err(kdev, "cannot allocate rx skb queue\n");
+ if (bcm_enet_refill_rx(dev, false)) {
+ dev_err(kdev, "cannot allocate rx buffer queue\n");
ret = -ENOMEM;
goto out;
}
@@ -1103,7 +1109,7 @@ static int bcm_enet_open(struct net_devi
return 0;
out:
- bcm_enet_free_rx_skb_ring(kdev, priv);
+ bcm_enet_free_rx_buf_ring(kdev, priv);
out_free_tx_skb:
kfree(priv->tx_skb);
@@ -1209,8 +1215,8 @@ static int bcm_enet_stop(struct net_devi
/* force reclaim of all tx buffers */
bcm_enet_tx_reclaim(dev, 1);
- /* free the rx skb ring */
- bcm_enet_free_rx_skb_ring(kdev, priv);
+ /* free the rx buffer ring */
+ bcm_enet_free_rx_buf_ring(kdev, priv);
/* free remaining allocated memory */
kfree(priv->tx_skb);
@@ -1637,9 +1643,12 @@ static int bcm_enet_change_mtu(struct ne
* align rx buffer size to dma burst len, account FCS since
* it's appended
*/
- priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN,
+ priv->rx_buf_size = ALIGN(actual_mtu + ETH_FCS_LEN,
priv->dma_maxburst * 4);
+ priv->rx_frag_size = SKB_DATA_ALIGN(priv->rx_buf_offset + priv->rx_buf_size) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
dev->mtu = new_mtu;
return 0;
}
@@ -1725,6 +1734,7 @@ static int bcm_enet_probe(struct platfor
priv->enet_is_sw = false;
priv->dma_maxburst = BCMENET_DMA_MAXBURST;
+ priv->rx_buf_offset = NET_SKB_PAD;
ret = bcm_enet_change_mtu(dev, dev->mtu);
if (ret)
@@ -2142,7 +2152,7 @@ static int bcm_enetsw_open(struct net_de
priv->tx_skb = kcalloc(priv->tx_ring_size, sizeof(struct sk_buff *),
GFP_KERNEL);
if (!priv->tx_skb) {
- dev_err(kdev, "cannot allocate rx skb queue\n");
+ dev_err(kdev, "cannot allocate tx skb queue\n");
ret = -ENOMEM;
goto out_free_tx_ring;
}
@@ -2152,11 +2162,11 @@ static int bcm_enetsw_open(struct net_de
priv->tx_curr_desc = 0;
spin_lock_init(&priv->tx_lock);
- /* init & fill rx ring with skbs */
- priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *),
+ /* init & fill rx ring with buffers */
+ priv->rx_buf = kcalloc(priv->rx_ring_size, sizeof(void *),
GFP_KERNEL);
- if (!priv->rx_skb) {
- dev_err(kdev, "cannot allocate rx skb queue\n");
+ if (!priv->rx_buf) {
+ dev_err(kdev, "cannot allocate rx buffer queue\n");
ret = -ENOMEM;
goto out_free_tx_skb;
}
@@ -2203,8 +2213,8 @@ static int bcm_enetsw_open(struct net_de
enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
ENETDMA_BUFALLOC_REG(priv->rx_chan));
- if (bcm_enet_refill_rx(dev)) {
- dev_err(kdev, "cannot allocate rx skb queue\n");
+ if (bcm_enet_refill_rx(dev, false)) {
+ dev_err(kdev, "cannot allocate rx buffer queue\n");
ret = -ENOMEM;
goto out;
}
@@ -2303,7 +2313,7 @@ static int bcm_enetsw_open(struct net_de
return 0;
out:
- bcm_enet_free_rx_skb_ring(kdev, priv);
+ bcm_enet_free_rx_buf_ring(kdev, priv);
out_free_tx_skb:
kfree(priv->tx_skb);
@@ -2353,8 +2363,8 @@ static int bcm_enetsw_stop(struct net_de
/* force reclaim of all tx buffers */
bcm_enet_tx_reclaim(dev, 1);
- /* free the rx skb ring */
- bcm_enet_free_rx_skb_ring(kdev, priv);
+ /* free the rx buffer ring */
+ bcm_enet_free_rx_buf_ring(kdev, priv);
/* free remaining allocated memory */
kfree(priv->tx_skb);
@@ -2655,6 +2665,7 @@ static int bcm_enetsw_probe(struct platf
priv->rx_ring_size = BCMENET_DEF_RX_DESC;
priv->tx_ring_size = BCMENET_DEF_TX_DESC;
priv->dma_maxburst = BCMENETSW_DMA_MAXBURST;
+ priv->rx_buf_offset = NET_SKB_PAD + NET_IP_ALIGN;
pd = dev_get_platdata(&pdev->dev);
if (pd) {
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -230,11 +230,17 @@ struct bcm_enet_priv {
/* next dirty rx descriptor to refill */
int rx_dirty_desc;
- /* size of allocated rx skbs */
- unsigned int rx_skb_size;
+ /* size of allocated rx buffers */
+ unsigned int rx_buf_size;
- /* list of skb given to hw for rx */
- struct sk_buff **rx_skb;
+ /* allocated rx buffer offset */
+ unsigned int rx_buf_offset;
+
+ /* size of allocated rx frag */
+ unsigned int rx_frag_size;
+
+ /* list of buffer given to hw for rx */
+ void **rx_buf;
/* used when rx skb allocation failed, so we defer rx queue
* refill */

View File

@ -0,0 +1,40 @@
From ae2259eebeacb7753e3043278957b45840123972 Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Wed, 6 Jan 2021 22:42:08 +0800
Subject: [PATCH 7/7] bcm63xx_enet: improve rx loop
Use existing rx processed count to track against budget, thereby making
budget decrement operation redundant.
rx_desc_count can be calculated outside the rx loop, making the loop a
bit smaller.
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -340,7 +340,6 @@ static int bcm_enet_receive_queue(struct
priv->rx_curr_desc++;
if (priv->rx_curr_desc == priv->rx_ring_size)
priv->rx_curr_desc = 0;
- priv->rx_desc_count--;
/* if the packet does not have start of packet _and_
* end of packet flag set, then just recycle it */
@@ -405,9 +404,10 @@ static int bcm_enet_receive_queue(struct
dev->stats.rx_bytes += len;
list_add_tail(&skb->list, &rx_list);
- } while (--budget > 0);
+ } while (processed < budget);
netif_receive_skb_list(&rx_list);
+ priv->rx_desc_count -= processed;
if (processed || !priv->rx_desc_count) {
bcm_enet_refill_rx(dev, true);

View File

@ -1,6 +1,6 @@
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1612,7 +1612,7 @@ static int bcm_enet_change_mtu(struct ne
@@ -1629,7 +1629,7 @@ static int bcm_enet_change_mtu(struct ne
return -EBUSY;
/* add ethernet header + vlan tag size */

View File

@ -15,7 +15,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -854,10 +854,8 @@ static int bcm_enet_open(struct net_devi
@@ -893,10 +893,8 @@ static int bcm_enet_open(struct net_devi
struct bcm_enet_priv *priv;
struct sockaddr addr;
struct device *kdev;
@ -26,7 +26,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
void *p;
u32 val;
@@ -865,31 +863,10 @@ static int bcm_enet_open(struct net_devi
@@ -904,31 +902,10 @@ static int bcm_enet_open(struct net_devi
kdev = &priv->pdev->dev;
if (priv->has_phy) {
@ -59,7 +59,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
}
/* mask all interrupts and request them */
@@ -899,7 +876,7 @@ static int bcm_enet_open(struct net_devi
@@ -938,7 +915,7 @@ static int bcm_enet_open(struct net_devi
ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
if (ret)
@ -68,7 +68,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, 0,
dev->name, dev);
@@ -1061,8 +1038,8 @@ static int bcm_enet_open(struct net_devi
@@ -1100,8 +1077,8 @@ static int bcm_enet_open(struct net_devi
enet_dmac_writel(priv, priv->dma_chan_int_mask,
ENETDMAC_IRMASK, priv->tx_chan);
@ -79,7 +79,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
else
bcm_enet_adjust_link(dev);
@@ -1103,10 +1080,6 @@ out_freeirq_rx:
@@ -1131,10 +1108,6 @@ out_freeirq_rx:
out_freeirq:
free_irq(dev->irq, dev);
@ -90,7 +90,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
return ret;
}
@@ -1211,10 +1184,6 @@ static int bcm_enet_stop(struct net_devi
@@ -1228,10 +1201,6 @@ static int bcm_enet_stop(struct net_devi
free_irq(priv->irq_rx, dev);
free_irq(dev->irq, dev);
@ -101,7 +101,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
return 0;
}
@@ -1779,14 +1748,47 @@ static int bcm_enet_probe(struct platfor
@@ -1800,14 +1769,47 @@ static int bcm_enet_probe(struct platfor
/* do minimal hardware init to be able to probe mii bus */
bcm_enet_hw_preinit(priv);
@ -150,7 +150,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
}
bus = priv->mii_bus;
@@ -1810,6 +1812,26 @@ static int bcm_enet_probe(struct platfor
@@ -1831,6 +1833,26 @@ static int bcm_enet_probe(struct platfor
dev_err(&pdev->dev, "unable to register mdio bus\n");
goto out_free_mdio;
}
@ -177,7 +177,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
} else {
/* run platform code to initialize PHY device */
@@ -1817,45 +1839,16 @@ static int bcm_enet_probe(struct platfor
@@ -1838,45 +1860,16 @@ static int bcm_enet_probe(struct platfor
pd->mii_config(dev, 1, bcm_enet_mdio_read_mii,
bcm_enet_mdio_write_mii)) {
dev_err(&pdev->dev, "unable to configure mdio bus\n");
@ -227,7 +227,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
if (priv->mii_bus)
mdiobus_unregister(priv->mii_bus);
@@ -1863,6 +1856,9 @@ out_free_mdio:
@@ -1884,6 +1877,9 @@ out_free_mdio:
if (priv->mii_bus)
mdiobus_free(priv->mii_bus);
@ -237,7 +237,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
out_uninit_hw:
/* turn off mdc clock */
enet_writel(priv, 0, ENET_MIISC_REG);
@@ -1893,6 +1889,7 @@ static int bcm_enet_remove(struct platfo
@@ -1914,6 +1910,7 @@ static int bcm_enet_remove(struct platfo
enet_writel(priv, 0, ENET_MIISC_REG);
if (priv->has_phy) {

View File

@ -32,7 +32,7 @@ Subject: [PATCH 54/81] bcm63xx_enet: enable rgmii clock on external ports
#define ENETSW_MDIOC_EXT_MASK (1 << 16)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -2162,6 +2162,18 @@ static int bcm_enetsw_open(struct net_de
@@ -2183,6 +2183,18 @@ static int bcm_enetsw_open(struct net_de
priv->sw_port_link[i] = 0;
}

View File

@ -1,6 +1,6 @@
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -332,6 +332,9 @@ struct bcm_enet_priv {
@@ -338,6 +338,9 @@ struct bcm_enet_priv {
struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
int sw_port_link[ENETSW_MAX_PORT];
@ -20,7 +20,7 @@
#include <bcm63xx_dev_enet.h>
#include "bcm63xx_enet.h"
@@ -1909,7 +1910,8 @@ static int bcm_enet_remove(struct platfo
@@ -1930,7 +1931,8 @@ static int bcm_enet_remove(struct platfo
return 0;
}
@ -30,7 +30,7 @@
.probe = bcm_enet_probe,
.remove = bcm_enet_remove,
.driver = {
@@ -1918,6 +1920,42 @@ struct platform_driver bcm63xx_enet_driv
@@ -1939,6 +1941,42 @@ struct platform_driver bcm63xx_enet_driv
},
};
@ -73,7 +73,7 @@
/*
* switch mii access callbacks
*/
@@ -2174,29 +2212,6 @@ static int bcm_enetsw_open(struct net_de
@@ -2195,29 +2233,6 @@ static int bcm_enetsw_open(struct net_de
enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i));
}
@ -103,7 +103,7 @@
/* initialize flow control buffer allocation */
enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
ENETDMA_BUFALLOC_REG(priv->rx_chan));
@@ -2652,6 +2667,9 @@ static int bcm_enetsw_probe(struct platf
@@ -2651,6 +2666,9 @@ static int bcm_enetsw_probe(struct platf
struct bcm63xx_enetsw_platform_data *pd;
struct resource *res_mem;
int ret, irq_rx, irq_tx;

View File

@ -12,7 +12,7 @@
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -2209,6 +2209,10 @@ static int bcm_enetsw_open(struct net_de
@@ -2230,6 +2230,10 @@ static int bcm_enetsw_open(struct net_de
rgmii_ctrl = enetsw_readb(priv, ENETSW_RGMII_CTRL_REG(i));
rgmii_ctrl |= ENETSW_RGMII_CTRL_GMII_CLK_EN;

View File

@ -0,0 +1,34 @@
From cf0d2fbaae9e962d91a321de75e0d4f9f9ccbdfe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
Date: Thu, 21 Jan 2021 18:17:37 +0100
Subject: [PATCH] nand: brcmnand: fix OOB R/W with Hamming ECC
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Hamming ECC doesn't cover the OOB data, so reading or writing OOB shall
always be done without ECC enabled.
This is a problem when adding JFFS2 cleanmarkers to erased blocks. When JFFS2
clenmarkers are added to the OOB with ECC enabled, OOB bytes will be changed
from ff ff ff to 00 00 00, reporting incorrect ECC errors.
Signed-off-by: Álvaro Fernández Rojas <noltari@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
@@ -2426,6 +2426,12 @@ static int brcmnand_attach_chip(struct n
ret = brcmstb_choose_ecc_layout(host);
+ /* If OOB is written with ECC enabled it will cause ECC errors */
+ if (is_hamming_ecc(host->ctrl, &host->hwcfg)) {
+ chip->ecc.write_oob = brcmnand_write_oob_raw;
+ chip->ecc.read_oob = brcmnand_read_oob_raw;
+ }
+
return ret;
}

View File

@ -1,11 +0,0 @@
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -488,7 +488,7 @@ static int nand_do_write_oob(struct nand
nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
- if (ops->mode == MTD_OPS_RAW)
+ if (ops->mode == MTD_OPS_AUTO_OOB || ops->mode == MTD_OPS_RAW)
status = chip->ecc.write_oob_raw(chip, page & chip->pagemask);
else
status = chip->ecc.write_oob(chip, page & chip->pagemask);

View File

@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Mon, 30 Nov 2020 11:07:47 +0800
Subject: [PATCH] bcm63xx: enetsw: switch to netdev_alloc_skb_ip_align
Increases packet processing performance by 30%.
Tested on BCM6328 320 MHz and iperf3 -M 512 for packet/sec performance.
Before:
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-30.00 sec 120 MBytes 33.7 Mbits/sec 277 sender
[ 4] 0.00-30.00 sec 120 MBytes 33.5 Mbits/sec receiver
After:
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-30.00 sec 155 MBytes 43.3 Mbits/sec 354 sender
[ 4] 0.00-30.00 sec 154 MBytes 43.1 Mbits/sec receiver
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
---
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 6 +++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -239,7 +239,10 @@ static int bcm_enet_refill_rx(struct net
desc = &priv->rx_desc_cpu[desc_idx];
if (!priv->rx_skb[desc_idx]) {
- skb = netdev_alloc_skb(dev, priv->rx_skb_size);
+ if (priv->enet_is_sw)
+ skb = netdev_alloc_skb_ip_align(dev, priv->rx_skb_size);
+ else
+ skb = netdev_alloc_skb(dev, priv->rx_skb_size);
if (!skb)
break;
priv->rx_skb[desc_idx] = skb;

View File

@ -1,67 +0,0 @@
From 3c0e8e1259d223a1493c47f7e277d05b93909b6b Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Mon, 2 Nov 2020 11:34:06 +0800
Subject: [PATCH 1/2] bcm63xx: add BQL support
Add Byte Queue Limits support to reduce/remove bufferbloat in bcm63xx target.
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
---
bcm63xx_enet.c | 11 +++++++++++
1 file changed, 11 insertions(+)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -423,9 +423,11 @@ static int bcm_enet_tx_reclaim(struct ne
{
struct bcm_enet_priv *priv;
int released;
+ unsigned int bytes;
priv = netdev_priv(dev);
released = 0;
+ bytes = 0;
while (priv->tx_desc_count < priv->tx_ring_size) {
struct bcm_enet_desc *desc;
@@ -461,10 +463,13 @@ static int bcm_enet_tx_reclaim(struct ne
if (desc->len_stat & DMADESC_UNDER_MASK)
dev->stats.tx_errors++;
+ bytes += skb->len;
dev_kfree_skb(skb);
released++;
}
+ netdev_completed_queue(dev, released, bytes);
+
if (netif_queue_stopped(dev) && released)
netif_wake_queue(dev);
@@ -631,6 +636,8 @@ bcm_enet_start_xmit(struct sk_buff *skb,
desc->len_stat = len_stat;
wmb();
+ netdev_sent_queue(dev, skb->len);
+
/* kick tx dma */
enet_dmac_writel(priv, priv->dma_chan_en_mask,
ENETDMAC_CHANCFG, priv->tx_chan);
@@ -1051,6 +1058,8 @@ static int bcm_enet_open(struct net_devi
else
bcm_enet_adjust_link(dev);
+ netdev_reset_queue(dev);
+
netif_start_queue(dev);
return 0;
@@ -2281,6 +2290,8 @@ static int bcm_enetsw_open(struct net_de
enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
ENETDMAC_IRMASK, priv->tx_chan);
+ netdev_reset_queue(dev);
+
netif_carrier_on(dev);
netif_start_queue(dev);

View File

@ -1,54 +0,0 @@
From 79bfb73319098bc4cb701139a6677dcdec99182f Mon Sep 17 00:00:00 2001
From: Sieng Piaw Liew <liew.s.piaw@gmail.com>
Date: Tue, 3 Nov 2020 08:14:35 +0800
Subject: [PATCH 2/2] bcm63xx: support xmit_more in BQL
Support bulking hardware TX queue by using xmit_more.
Signed-off-by: Sieng Piaw Liew <liew.s.piaw@gmail.com>
---
bcm63xx_enet.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -638,14 +638,16 @@ bcm_enet_start_xmit(struct sk_buff *skb,
netdev_sent_queue(dev, skb->len);
- /* kick tx dma */
- enet_dmac_writel(priv, priv->dma_chan_en_mask,
- ENETDMAC_CHANCFG, priv->tx_chan);
-
/* stop queue if no more desc available */
if (!priv->tx_desc_count)
netif_stop_queue(dev);
+ /* kick tx dma */
+ if(!netdev_xmit_more() || !priv->tx_desc_count)
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ ENETDMAC_CHANCFG, priv->tx_chan);
+
+
dev->stats.tx_bytes += skb->len;
dev->stats.tx_packets++;
ret = NETDEV_TX_OK;
@@ -2713,7 +2715,7 @@ static int bcm_enetsw_probe(struct platf
priv->irq_rx = irq_rx;
priv->irq_tx = irq_tx;
priv->rx_ring_size = BCMENET_DEF_RX_DESC;
- priv->tx_ring_size = BCMENET_DEF_TX_DESC;
+ priv->tx_ring_size = BCMENETSW_DEF_TX_DESC;
priv->dma_maxburst = BCMENETSW_DMA_MAXBURST;
pd = dev_get_platdata(&pdev->dev);
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -15,6 +15,7 @@
/* default number of descriptor */
#define BCMENET_DEF_RX_DESC 64
#define BCMENET_DEF_TX_DESC 32
+#define BCMENETSW_DEF_TX_DESC 48
/* maximum burst len for dma (4 bytes unit) */
#define BCMENET_DMA_MAXBURST 16

View File

@ -0,0 +1,28 @@
From 422928a040fe17d17ded69c57903c7908423c7ef Mon Sep 17 00:00:00 2001
From: Boris Brezillon <bbrezillon@kernel.org>
Date: Sun, 3 May 2020 17:53:38 +0200
Subject: [PATCH] dt-bindings: mtd: partition: Document the slc-mode property
Add a boolean property to force a specific partition attached to an MLC
NAND to be accessed in an emulated SLC mode this making this partition
immune to paired-pages corruptions.
Signed-off-by: Boris Brezillon <bbrezillon@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200503155341.16712-6-miquel.raynal@bootlin.com
---
Documentation/devicetree/bindings/mtd/partition.txt | 3 +++
1 file changed, 3 insertions(+)
--- a/Documentation/devicetree/bindings/mtd/partition.txt
+++ b/Documentation/devicetree/bindings/mtd/partition.txt
@@ -61,6 +61,9 @@ Optional properties:
clobbered.
- lock : Do not unlock the partition at initialization time (not supported on
all devices)
+- slc-mode: This parameter, if present, allows one to emulate SLC mode on a
+ partition attached to an MLC NAND thus making this partition immune to
+ paired-pages corruptions
Examples:

View File

@ -0,0 +1,324 @@
From 04e9ab75267489224364fa510a88ada83e11c325 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 10 Dec 2020 18:23:52 +0100
Subject: [PATCH] dt-bindings: mtd: convert "fixed-partitions" to the
json-schema
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This standardizes its documentation, allows validating with Makefile
checks and helps writing DTS files.
Noticeable changes:
1. Dropped "Partitions can be represented by sub-nodes of a flash
device." as we also support subpartitions (don't have to be part of
flash device node)
2. Dropped "to Linux" as bindings are meant to be os agnostic.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Link: https://lore.kernel.org/r/20201210172352.31632-1-zajec5@gmail.com
Signed-off-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/mtd/partition.txt | 131 +--------------
.../mtd/partitions/fixed-partitions.yaml | 152 ++++++++++++++++++
2 files changed, 154 insertions(+), 129 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
--- a/Documentation/devicetree/bindings/mtd/partition.txt
+++ b/Documentation/devicetree/bindings/mtd/partition.txt
@@ -24,137 +24,10 @@ another partitioning method.
Available bindings are listed in the "partitions" subdirectory.
-Fixed Partitions
-================
-
-Partitions can be represented by sub-nodes of a flash device. This can be used
-on platforms which have strong conventions about which portions of a flash are
-used for what purposes, but which don't use an on-flash partition table such
-as RedBoot.
-
-The partition table should be a subnode of the flash node and should be named
-'partitions'. This node should have the following property:
-- compatible : (required) must be "fixed-partitions"
-Partitions are then defined in subnodes of the partitions node.
+Deprecated: partitions defined in flash node
+============================================
For backwards compatibility partitions as direct subnodes of the flash device are
supported. This use is discouraged.
NOTE: also for backwards compatibility, direct subnodes that have a compatible
string are not considered partitions, as they may be used for other bindings.
-
-#address-cells & #size-cells must both be present in the partitions subnode of the
-flash device. There are two valid values for both:
-<1>: for partitions that require a single 32-bit cell to represent their
- size/address (aka the value is below 4 GiB)
-<2>: for partitions that require two 32-bit cells to represent their
- size/address (aka the value is 4 GiB or greater).
-
-Required properties:
-- reg : The partition's offset and size within the flash
-
-Optional properties:
-- label : The label / name for this partition. If omitted, the label is taken
- from the node name (excluding the unit address).
-- read-only : This parameter, if present, is a hint to Linux that this
- partition should only be mounted read-only. This is usually used for flash
- partitions containing early-boot firmware images or data which should not be
- clobbered.
-- lock : Do not unlock the partition at initialization time (not supported on
- all devices)
-- slc-mode: This parameter, if present, allows one to emulate SLC mode on a
- partition attached to an MLC NAND thus making this partition immune to
- paired-pages corruptions
-
-Examples:
-
-
-flash@0 {
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0000000 0x100000>;
- read-only;
- };
-
- uimage@100000 {
- reg = <0x0100000 0x200000>;
- };
- };
-};
-
-flash@1 {
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <2>;
-
- /* a 4 GiB partition */
- partition@0 {
- label = "filesystem";
- reg = <0x00000000 0x1 0x00000000>;
- };
- };
-};
-
-flash@2 {
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <2>;
- #size-cells = <2>;
-
- /* an 8 GiB partition */
- partition@0 {
- label = "filesystem #1";
- reg = <0x0 0x00000000 0x2 0x00000000>;
- };
-
- /* a 4 GiB partition */
- partition@200000000 {
- label = "filesystem #2";
- reg = <0x2 0x00000000 0x1 0x00000000>;
- };
- };
-};
-
-flash@3 {
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "bootloader";
- reg = <0x000000 0x100000>;
- read-only;
- };
-
- firmware@100000 {
- label = "firmware";
- reg = <0x100000 0xe00000>;
- compatible = "brcm,trx";
- };
-
- calibration@f00000 {
- label = "calibration";
- reg = <0xf00000 0x100000>;
- compatible = "fixed-partitions";
- ranges = <0 0xf00000 0x100000>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "wifi0";
- reg = <0x000000 0x080000>;
- };
-
- partition@80000 {
- label = "wifi1";
- reg = <0x080000 0x080000>;
- };
- };
- };
-};
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
@@ -0,0 +1,152 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/partitions/fixed-partitions.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Fixed partitions
+
+description: |
+ This binding can be used on platforms which have strong conventions about
+ which portions of a flash are used for what purposes, but which don't use an
+ on-flash partition table such as RedBoot.
+
+ The partition table should be a node named "partitions". Partitions are then
+ defined as subnodes.
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+properties:
+ compatible:
+ const: fixed-partitions
+
+ "#address-cells": true
+
+ "#size-cells": true
+
+patternProperties:
+ "@[0-9a-f]+$":
+ description: node describing a single flash partition
+ type: object
+
+ properties:
+ reg:
+ description: partition's offset and size within the flash
+ maxItems: 1
+
+ label:
+ description: The label / name for this partition. If omitted, the label
+ is taken from the node name (excluding the unit address).
+
+ read-only:
+ description: This parameter, if present, is a hint that this partition
+ should only be mounted read-only. This is usually used for flash
+ partitions containing early-boot firmware images or data which should
+ not be clobbered.
+ type: boolean
+
+ lock:
+ description: Do not unlock the partition at initialization time (not
+ supported on all devices)
+ type: boolean
+
+ slc-mode:
+ description: This parameter, if present, allows one to emulate SLC mode
+ on a partition attached to an MLC NAND thus making this partition
+ immune to paired-pages corruptions
+ type: boolean
+
+ required:
+ - reg
+
+required:
+ - "#address-cells"
+ - "#size-cells"
+
+additionalProperties: true
+
+examples:
+ - |
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ uimage@100000 {
+ reg = <0x0100000 0x200000>;
+ };
+ };
+ - |
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <2>;
+
+ /* a 4 GiB partition */
+ partition@0 {
+ label = "filesystem";
+ reg = <0x00000000 0x1 0x00000000>;
+ };
+ };
+ - |
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ /* an 8 GiB partition */
+ partition@0 {
+ label = "filesystem #1";
+ reg = <0x0 0x00000000 0x2 0x00000000>;
+ };
+
+ /* a 4 GiB partition */
+ partition@200000000 {
+ label = "filesystem #2";
+ reg = <0x2 0x00000000 0x1 0x00000000>;
+ };
+ };
+ - |
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0x000000 0x100000>;
+ read-only;
+ };
+
+ firmware@100000 {
+ compatible = "brcm,trx";
+ label = "firmware";
+ reg = <0x100000 0xe00000>;
+ };
+
+ calibration@f00000 {
+ compatible = "fixed-partitions";
+ label = "calibration";
+ reg = <0xf00000 0x100000>;
+ ranges = <0 0xf00000 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "wifi0";
+ reg = <0x000000 0x080000>;
+ };
+
+ partition@80000 {
+ label = "wifi1";
+ reg = <0x080000 0x080000>;
+ };
+ };
+ };

View File

@ -0,0 +1,91 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/mtd/partitions/openwrt,uimage.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: OpenWrt variations of U-Boot Image partitions
maintainers:
- Bjørn Mork <bjorn@mork.no>
description: |
The image format defined by the boot loader "Das U-Boot" is often
modified or extended by device vendors. This defines a few optional
properties which can be used to describe such modifications.
# partition.txt defines common properties, but has not yet been
# converted to YAML
#allOf:
# - $ref: ../partition.yaml#
properties:
compatible:
items:
- enum:
- openwrt,uimage
- const: denx,uimage
openwrt,padding:
description: Number of padding bytes between header and data
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
openwrt,ih-magic:
description: U-Boot Image Header magic number.
$ref: /schemas/types.yaml#/definitions/uint32
default: 0x27051956 # IH_MAGIC
openwrt,ih-type:
description: U-Boot Image type
$ref: /schemas/types.yaml#/definitions/uint32
default: 2 # IH_TYPE_KERNEL
openwrt,offset:
description:
Offset between partition start and U-Boot Image in bytes
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
openwrt,partition-magic:
description:
Magic number found at the start of the partition. Will only be
validated if both this property and openwrt,offset is non-zero
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
required:
- compatible
- reg
#unevaluatedProperties: false
additionalProperties: false
examples:
- |
// device with non-default magic
partition@300000 {
compatible = "openwrt,uimage", "denx,uimage";
reg = <0x00300000 0xe80000>;
label = "firmware";
openwrt,ih-magic = <0x4e474520>;
};
- |
// device with U-Boot Image at an offset, with a partition magic value
partition@70000 {
compatible = "openwrt,uimage", "denx,uimage";
reg = <0x00070000 0x00790000>;
label = "firmware";
openwrt,offset = <20>;
openwrt,partition-magic = <0x43535953>;
};
- |
// device using a non-default image type
#include "dt-bindings/mtd/partitions/uimage.h"
partition@6c0000 {
compatible = "openwrt,uimage", "denx,uimage";
reg = <0x6c0000 0x1900000>;
label = "firmware";
openwrt,ih-magic = <0x33373033>;
openwrt,ih-type = <IH_TYPE_FILESYSTEM>;
};

View File

@ -25,6 +25,18 @@ config MTD_SPLIT_BCM_WFI_FW
depends on MTD_SPLIT_SUPPORT
select MTD_SPLIT
config MTD_SPLIT_CFE_BOOTFS
bool "Parser finding rootfs appended to the CFE bootfs"
depends on MTD_SPLIT_SUPPORT && ARCH_BCM4908
select MTD_SPLIT
help
cferom on BCM4908 (and bcm63xx) uses JFFS2 bootfs partition
for storing kernel, cferam and some device specific files.
There isn't any straight way of storing rootfs so it gets
appended to the JFFS2 bootfs partition. Kernel needs to find
it and run init from it. This parser is responsible for
finding appended rootfs.
config MTD_SPLIT_SEAMA_FW
bool "Seama firmware parser"
depends on MTD_SPLIT_SUPPORT

View File

@ -1,5 +1,6 @@
obj-$(CONFIG_MTD_SPLIT) += mtdsplit.o
obj-$(CONFIG_MTD_SPLIT_BCM_WFI_FW) += mtdsplit_bcm_wfi.o
obj-$(CONFIG_MTD_SPLIT_CFE_BOOTFS) += mtdsplit_cfe_bootfs.o
obj-$(CONFIG_MTD_SPLIT_SEAMA_FW) += mtdsplit_seama.o
obj-$(CONFIG_MTD_SPLIT_SQUASHFS_ROOT) += mtdsplit_squashfs.o
obj-$(CONFIG_MTD_SPLIT_UIMAGE_FW) += mtdsplit_uimage.o

View File

@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
*/
#include <linux/init.h>
#include <linux/jffs2.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/of.h>
#include <linux/slab.h>
#include "mtdsplit.h"
#define je16_to_cpu(x) ((x).v16)
#define je32_to_cpu(x) ((x).v32)
#define NR_PARTS 1
static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
struct jffs2_raw_dirent node;
enum mtdsplit_part_type type;
struct mtd_partition *parts;
size_t rootfs_offset;
size_t retlen;
size_t offset;
int err;
/* Don't parse backup partitions */
if (strcmp(mtd->name, "firmware"))
return -EINVAL;
/* Find the end of JFFS2 bootfs partition */
offset = 0;
do {
err = mtd_read(mtd, offset, sizeof(node), &retlen, (void *)&node);
if (err || retlen != sizeof(node))
break;
if (je16_to_cpu(node.magic) != JFFS2_MAGIC_BITMASK)
break;
offset += je32_to_cpu(node.totlen);
offset = (offset + 0x3) & ~0x3;
} while (offset < mtd->size);
/* Find rootfs partition that follows the bootfs */
err = mtd_find_rootfs_from(mtd, mtd->erasesize, mtd->size, &rootfs_offset, &type);
if (err)
return err;
parts = kzalloc(NR_PARTS * sizeof(*parts), GFP_KERNEL);
if (!parts)
return -ENOMEM;
if (type == MTDSPLIT_PART_TYPE_UBI)
parts[0].name = UBI_PART_NAME;
else
parts[0].name = ROOTFS_PART_NAME;
parts[0].offset = rootfs_offset;
parts[0].size = mtd->size - rootfs_offset;
*pparts = parts;
return NR_PARTS;
}
static const struct of_device_id mtdsplit_cfe_bootfs_of_match_table[] = {
{ .compatible = "brcm,bcm4908-firmware" },
{},
};
MODULE_DEVICE_TABLE(of, mtdsplit_cfe_bootfs_of_match_table);
static struct mtd_part_parser mtdsplit_cfe_bootfs_parser = {
.owner = THIS_MODULE,
.name = "cfe-bootfs",
.of_match_table = mtdsplit_cfe_bootfs_of_match_table,
.parse_fn = mtdsplit_cfe_bootfs_parse,
};
module_mtd_part_parser(mtdsplit_cfe_bootfs_parser);

View File

@ -19,23 +19,10 @@
#include <linux/version.h>
#include <linux/byteorder/generic.h>
#include <linux/of.h>
#include <dt-bindings/mtd/partitions/uimage.h>
#include "mtdsplit.h"
/*
* uimage_header itself is only 64B, but it may be prepended with another data.
* Currently the biggest size is for Fon(Foxconn) devices: 64B + 32B
*/
#define MAX_HEADER_LEN 96
#define IH_MAGIC 0x27051956 /* Image Magic Number */
#define IH_NMLEN 32 /* Image Name Length */
#define IH_OS_LINUX 5 /* Linux */
#define IH_TYPE_KERNEL 2 /* OS Kernel Image */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image */
/*
* Legacy format image header,
* all data in network byte order (aka natural aka bigendian).
@ -76,6 +63,53 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf,
return 0;
}
static void uimage_parse_dt(struct mtd_info *master, int *extralen,
u32 *ih_magic, u32 *ih_type,
u32 *header_offset, u32 *part_magic)
{
struct device_node *np = mtd_get_of_node(master);
if (!np || !of_device_is_compatible(np, "openwrt,uimage"))
return;
if (!of_property_read_u32(np, "openwrt,padding", extralen))
pr_debug("got openwrt,padding=%d from device-tree\n", *extralen);
if (!of_property_read_u32(np, "openwrt,ih-magic", ih_magic))
pr_debug("got openwrt,ih-magic=%08x from device-tree\n", *ih_magic);
if (!of_property_read_u32(np, "openwrt,ih-type", ih_type))
pr_debug("got openwrt,ih-type=%08x from device-tree\n", *ih_type);
if (!of_property_read_u32(np, "openwrt,offset", header_offset))
pr_debug("got ih-start=%u from device-tree\n", *header_offset);
if (!of_property_read_u32(np, "openwrt,partition-magic", part_magic))
pr_debug("got openwrt,partition-magic=%08x from device-tree\n", *part_magic);
}
static ssize_t uimage_verify_default(u_char *buf, u32 ih_magic, u32 ih_type)
{
struct uimage_header *header = (struct uimage_header *)buf;
/* default sanity checks */
if (be32_to_cpu(header->ih_magic) != ih_magic) {
pr_debug("invalid uImage magic: %08x != %08x\n",
be32_to_cpu(header->ih_magic), ih_magic);
return -EINVAL;
}
if (header->ih_os != IH_OS_LINUX) {
pr_debug("invalid uImage OS: %08x != %08x\n",
be32_to_cpu(header->ih_os), IH_OS_LINUX);
return -EINVAL;
}
if (header->ih_type != ih_type) {
pr_debug("invalid uImage type: %08x != %08x\n",
be32_to_cpu(header->ih_type), ih_type);
return -EINVAL;
}
return 0;
}
/**
* __mtdsplit_parse_uimage - scan partition and create kernel + rootfs parts
*
@ -84,8 +118,7 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf,
*/
static int __mtdsplit_parse_uimage(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data,
ssize_t (*find_header)(u_char *buf, size_t len, int *extralen))
struct mtd_part_parser_data *data)
{
struct mtd_partition *parts;
u_char *buf;
@ -95,9 +128,14 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master,
size_t uimage_size = 0;
size_t rootfs_offset;
size_t rootfs_size = 0;
size_t buflen;
int uimage_part, rf_part;
int ret;
int extralen;
int extralen = 0;
u32 ih_magic = IH_MAGIC;
u32 ih_type = IH_TYPE_KERNEL;
u32 header_offset = 0;
u32 part_magic = 0;
enum mtdsplit_part_type type;
nr_parts = 2;
@ -105,7 +143,9 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master,
if (!parts)
return -ENOMEM;
buf = vmalloc(MAX_HEADER_LEN);
uimage_parse_dt(master, &extralen, &ih_magic, &ih_type, &header_offset, &part_magic);
buflen = sizeof(struct uimage_header) + header_offset;
buf = vmalloc(buflen);
if (!buf) {
ret = -ENOMEM;
goto err_free_parts;
@ -117,21 +157,25 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master,
uimage_size = 0;
ret = read_uimage_header(master, offset, buf, MAX_HEADER_LEN);
ret = read_uimage_header(master, offset, buf, buflen);
if (ret)
continue;
extralen = 0;
ret = find_header(buf, MAX_HEADER_LEN, &extralen);
/* verify optional partition magic before uimage header */
if (header_offset && part_magic && (be32_to_cpu(*(u32 *)buf) != part_magic))
continue;
ret = uimage_verify_default(buf + header_offset, ih_magic, ih_type);
if (ret < 0) {
pr_debug("no valid uImage found in \"%s\" at offset %llx\n",
master->name, (unsigned long long) offset);
continue;
}
header = (struct uimage_header *)(buf + ret);
header = (struct uimage_header *)(buf + header_offset);
uimage_size = sizeof(*header) +
be32_to_cpu(header->ih_size) + ret + extralen;
be32_to_cpu(header->ih_size) + header_offset + extralen;
if ((offset + uimage_size) > master->size) {
pr_debug("uImage exceeds MTD device \"%s\"\n",
@ -210,43 +254,9 @@ err_free_parts:
return ret;
}
static ssize_t uimage_verify_default(u_char *buf, size_t len, int *extralen)
{
struct uimage_header *header = (struct uimage_header *)buf;
/* default sanity checks */
if (be32_to_cpu(header->ih_magic) != IH_MAGIC) {
pr_debug("invalid uImage magic: %08x\n",
be32_to_cpu(header->ih_magic));
return -EINVAL;
}
if (header->ih_os != IH_OS_LINUX) {
pr_debug("invalid uImage OS: %08x\n",
be32_to_cpu(header->ih_os));
return -EINVAL;
}
if (header->ih_type != IH_TYPE_KERNEL) {
pr_debug("invalid uImage type: %08x\n",
be32_to_cpu(header->ih_type));
return -EINVAL;
}
return 0;
}
static int
mtdsplit_uimage_parse_generic(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
return __mtdsplit_parse_uimage(master, pparts, data,
uimage_verify_default);
}
static const struct of_device_id mtdsplit_uimage_of_match_table[] = {
{ .compatible = "denx,uimage" },
{ .compatible = "openwrt,uimage" },
{},
};
@ -254,300 +264,10 @@ static struct mtd_part_parser uimage_generic_parser = {
.owner = THIS_MODULE,
.name = "uimage-fw",
.of_match_table = mtdsplit_uimage_of_match_table,
.parse_fn = mtdsplit_uimage_parse_generic,
.parse_fn = __mtdsplit_parse_uimage,
.type = MTD_PARSER_TYPE_FIRMWARE,
};
#define FW_MAGIC_GS110TPPV1 0x4e474520
#define FW_MAGIC_WNR2000V1 0x32303031
#define FW_MAGIC_WNR2000V3 0x32303033
#define FW_MAGIC_WNR2000V4 0x32303034
#define FW_MAGIC_WNR2200 0x32323030
#define FW_MAGIC_WNR612V2 0x32303631
#define FW_MAGIC_WNR1000V2 0x31303031
#define FW_MAGIC_WNR1000V2_VC 0x31303030
#define FW_MAGIC_WNDR3700 0x33373030
#define FW_MAGIC_WNDR3700V2 0x33373031
#define FW_MAGIC_WPN824N 0x31313030
static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len, int *extralen)
{
struct uimage_header *header = (struct uimage_header *)buf;
uint8_t expected_type = IH_TYPE_FILESYSTEM;
switch (be32_to_cpu(header->ih_magic)) {
case FW_MAGIC_GS110TPPV1:
case FW_MAGIC_WNR2000V4:
expected_type = IH_TYPE_KERNEL;
break;
case FW_MAGIC_WNR612V2:
case FW_MAGIC_WNR1000V2:
case FW_MAGIC_WNR1000V2_VC:
case FW_MAGIC_WNR2000V1:
case FW_MAGIC_WNR2000V3:
case FW_MAGIC_WNR2200:
case FW_MAGIC_WNDR3700:
case FW_MAGIC_WNDR3700V2:
case FW_MAGIC_WPN824N:
break;
default:
return -EINVAL;
}
if (header->ih_os != IH_OS_LINUX ||
header->ih_type != expected_type)
return -EINVAL;
return 0;
}
static int
mtdsplit_uimage_parse_netgear(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
return __mtdsplit_parse_uimage(master, pparts, data,
uimage_verify_wndr3700);
}
static const struct of_device_id mtdsplit_uimage_netgear_of_match_table[] = {
{ .compatible = "netgear,uimage" },
{},
};
static struct mtd_part_parser uimage_netgear_parser = {
.owner = THIS_MODULE,
.name = "netgear-fw",
.of_match_table = mtdsplit_uimage_netgear_of_match_table,
.parse_fn = mtdsplit_uimage_parse_netgear,
.type = MTD_PARSER_TYPE_FIRMWARE,
};
/**************************************************
* ALLNET
**************************************************/
#define FW_MAGIC_SG8208M 0x00000006
#define FW_MAGIC_SG8310PM 0x83000006
static ssize_t uimage_verify_allnet(u_char *buf, size_t len, int *extralen)
{
struct uimage_header *header = (struct uimage_header *)buf;
switch (be32_to_cpu(header->ih_magic)) {
case FW_MAGIC_SG8208M:
case FW_MAGIC_SG8310PM:
break;
default:
return -EINVAL;
}
if (header->ih_os != IH_OS_LINUX)
return -EINVAL;
return 0;
}
static int
mtdsplit_uimage_parse_allnet(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
return __mtdsplit_parse_uimage(master, pparts, data,
uimage_verify_allnet);
}
static const struct of_device_id mtdsplit_uimage_allnet_of_match_table[] = {
{ .compatible = "allnet,uimage" },
{},
};
static struct mtd_part_parser uimage_allnet_parser = {
.owner = THIS_MODULE,
.name = "allnet-fw",
.of_match_table = mtdsplit_uimage_allnet_of_match_table,
.parse_fn = mtdsplit_uimage_parse_allnet,
};
/**************************************************
* Edimax
**************************************************/
#define FW_EDIMAX_OFFSET 20
#define FW_MAGIC_EDIMAX 0x43535953
static ssize_t uimage_find_edimax(u_char *buf, size_t len, int *extralen)
{
u32 *magic;
if (len < FW_EDIMAX_OFFSET + sizeof(struct uimage_header)) {
pr_err("Buffer too small for checking Edimax header\n");
return -ENOSPC;
}
magic = (u32 *)buf;
if (be32_to_cpu(*magic) != FW_MAGIC_EDIMAX)
return -EINVAL;
if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len, extralen))
return FW_EDIMAX_OFFSET;
return -EINVAL;
}
static int
mtdsplit_uimage_parse_edimax(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
return __mtdsplit_parse_uimage(master, pparts, data,
uimage_find_edimax);
}
static const struct of_device_id mtdsplit_uimage_edimax_of_match_table[] = {
{ .compatible = "edimax,uimage" },
{},
};
static struct mtd_part_parser uimage_edimax_parser = {
.owner = THIS_MODULE,
.name = "edimax-fw",
.of_match_table = mtdsplit_uimage_edimax_of_match_table,
.parse_fn = mtdsplit_uimage_parse_edimax,
.type = MTD_PARSER_TYPE_FIRMWARE,
};
/**************************************************
* Fon(Foxconn)
**************************************************/
#define FONFXC_PAD_LEN 32
static ssize_t uimage_find_fonfxc(u_char *buf, size_t len, int *extralen)
{
if (uimage_verify_default(buf, len, extralen) < 0)
return -EINVAL;
*extralen = FONFXC_PAD_LEN;
return 0;
}
static int
mtdsplit_uimage_parse_fonfxc(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
return __mtdsplit_parse_uimage(master, pparts, data,
uimage_find_fonfxc);
}
static const struct of_device_id mtdsplit_uimage_fonfxc_of_match_table[] = {
{ .compatible = "fonfxc,uimage" },
{},
};
static struct mtd_part_parser uimage_fonfxc_parser = {
.owner = THIS_MODULE,
.name = "fonfxc-fw",
.of_match_table = mtdsplit_uimage_fonfxc_of_match_table,
.parse_fn = mtdsplit_uimage_parse_fonfxc,
};
/**************************************************
* SGE (T&W) Shenzhen Gongjin Electronics
**************************************************/
#define SGE_PAD_LEN 96
static ssize_t uimage_find_sge(u_char *buf, size_t len, int *extralen)
{
if (uimage_verify_default(buf, len, extralen) < 0)
return -EINVAL;
*extralen = SGE_PAD_LEN;
return 0;
}
static int
mtdsplit_uimage_parse_sge(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
return __mtdsplit_parse_uimage(master, pparts, data,
uimage_find_sge);
}
static const struct of_device_id mtdsplit_uimage_sge_of_match_table[] = {
{ .compatible = "sge,uimage" },
{},
};
static struct mtd_part_parser uimage_sge_parser = {
.owner = THIS_MODULE,
.name = "sge-fw",
.of_match_table = mtdsplit_uimage_sge_of_match_table,
.parse_fn = mtdsplit_uimage_parse_sge,
};
/**************************************************
* OKLI (OpenWrt Kernel Loader Image)
**************************************************/
#define IH_MAGIC_OKLI 0x4f4b4c49
static ssize_t uimage_verify_okli(u_char *buf, size_t len, int *extralen)
{
struct uimage_header *header = (struct uimage_header *)buf;
/* default sanity checks */
if (be32_to_cpu(header->ih_magic) != IH_MAGIC_OKLI) {
pr_debug("invalid uImage magic: %08x\n",
be32_to_cpu(header->ih_magic));
return -EINVAL;
}
if (header->ih_os != IH_OS_LINUX) {
pr_debug("invalid uImage OS: %08x\n",
be32_to_cpu(header->ih_os));
return -EINVAL;
}
if (header->ih_type != IH_TYPE_KERNEL) {
pr_debug("invalid uImage type: %08x\n",
be32_to_cpu(header->ih_type));
return -EINVAL;
}
return 0;
}
static int
mtdsplit_uimage_parse_okli(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
return __mtdsplit_parse_uimage(master, pparts, data,
uimage_verify_okli);
}
static const struct of_device_id mtdsplit_uimage_okli_of_match_table[] = {
{ .compatible = "openwrt,okli" },
{},
};
static struct mtd_part_parser uimage_okli_parser = {
.owner = THIS_MODULE,
.name = "okli-fw",
.of_match_table = mtdsplit_uimage_okli_of_match_table,
.parse_fn = mtdsplit_uimage_parse_okli,
};
/**************************************************
* Init
**************************************************/
@ -555,12 +275,6 @@ static struct mtd_part_parser uimage_okli_parser = {
static int __init mtdsplit_uimage_init(void)
{
register_mtd_parser(&uimage_generic_parser);
register_mtd_parser(&uimage_netgear_parser);
register_mtd_parser(&uimage_allnet_parser);
register_mtd_parser(&uimage_edimax_parser);
register_mtd_parser(&uimage_fonfxc_parser);
register_mtd_parser(&uimage_sge_parser);
register_mtd_parser(&uimage_okli_parser);
return 0;
}

View File

@ -0,0 +1,198 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* *** IMPORTANT ***
* This file is not only included from C-code but also from devicetree source
* files. As such this file MUST only contain comments and defines.
*
* Based on image.h from U-Boot which is
* (C) Copyright 2008 Semihalf
* (C) Copyright 2000-2005 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#ifndef __UIMAGE_H__
#define __UIMAGE_H__
/*
* Operating System Codes
*
* The following are exposed to uImage header.
* New IDs *MUST* be appended at the end of the list and *NEVER*
* inserted for backward compatibility.
*/
#define IH_OS_INVALID 0 /* Invalid OS */
#define IH_OS_OPENBSD 1 /* OpenBSD */
#define IH_OS_NETBSD 2 /* NetBSD */
#define IH_OS_FREEBSD 3 /* FreeBSD */
#define IH_OS_4_4BSD 4 /* 4.4BSD */
#define IH_OS_LINUX 5 /* Linux */
#define IH_OS_SVR4 6 /* SVR4 */
#define IH_OS_ESIX 7 /* Esix */
#define IH_OS_SOLARIS 8 /* Solaris */
#define IH_OS_IRIX 9 /* Irix */
#define IH_OS_SCO 10 /* SCO */
#define IH_OS_DELL 11 /* Dell */
#define IH_OS_NCR 12 /* NCR */
#define IH_OS_LYNXOS 13 /* LynxOS */
#define IH_OS_VXWORKS 14 /* VxWorks */
#define IH_OS_PSOS 15 /* pSOS */
#define IH_OS_QNX 16 /* QNX */
#define IH_OS_U_BOOT 17 /* Firmware */
#define IH_OS_RTEMS 18 /* RTEMS */
#define IH_OS_ARTOS 19 /* ARTOS */
#define IH_OS_UNITY 20 /* Unity OS */
#define IH_OS_INTEGRITY 21 /* INTEGRITY */
#define IH_OS_OSE 22 /* OSE */
#define IH_OS_PLAN9 23 /* Plan 9 */
#define IH_OS_OPENRTOS 24 /* OpenRTOS */
#define IH_OS_ARM_TRUSTED_FIRMWARE 25 /* ARM Trusted Firmware */
#define IH_OS_TEE 26 /* Trusted Execution Environment */
#define IH_OS_OPENSBI 27 /* RISC-V OpenSBI */
#define IH_OS_EFI 28 /* EFI Firmware (e.g. GRUB2) */
/*
* CPU Architecture Codes (supported by Linux)
*
* The following are exposed to uImage header.
* New IDs *MUST* be appended at the end of the list and *NEVER*
* inserted for backward compatibility.
*/
#define IH_ARCH_INVALID 0 /* Invalid CPU */
#define IH_ARCH_ALPHA 1 /* Alpha */
#define IH_ARCH_ARM 2 /* ARM */
#define IH_ARCH_I386 3 /* Intel x86 */
#define IH_ARCH_IA64 4 /* IA64 */
#define IH_ARCH_MIPS 5 /* MIPS */
#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */
#define IH_ARCH_PPC 7 /* PowerPC */
#define IH_ARCH_S390 8 /* IBM S390 */
#define IH_ARCH_SH 9 /* SuperH */
#define IH_ARCH_SPARC 10 /* Sparc */
#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */
#define IH_ARCH_M68K 12 /* M68K */
#define IH_ARCH_NIOS 13 /* Nios-32 */
#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */
#define IH_ARCH_NIOS2 15 /* Nios-II */
#define IH_ARCH_BLACKFIN 16 /* Blackfin */
#define IH_ARCH_AVR32 17 /* AVR32 */
#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */
#define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */
#define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */
#define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */
#define IH_ARCH_ARM64 22 /* ARM64 */
#define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */
#define IH_ARCH_X86_64 24 /* AMD x86_64, Intel and Via */
#define IH_ARCH_XTENSA 25 /* Xtensa */
#define IH_ARCH_RISCV 26 /* RISC-V */
/*
* Image Types
*
* "Standalone Programs" are directly runnable in the environment
* provided by U-Boot; it is expected that (if they behave
* well) you can continue to work in U-Boot after return from
* the Standalone Program.
* "OS Kernel Images" are usually images of some Embedded OS which
* will take over control completely. Usually these programs
* will install their own set of exception handlers, device
* drivers, set up the MMU, etc. - this means, that you cannot
* expect to re-enter U-Boot except by resetting the CPU.
* "RAMDisk Images" are more or less just data blocks, and their
* parameters (address, size) are passed to an OS kernel that is
* being started.
* "Multi-File Images" contain several images, typically an OS
* (Linux) kernel image and one or more data images like
* RAMDisks. This construct is useful for instance when you want
* to boot over the network using BOOTP etc., where the boot
* server provides just a single image file, but you want to get
* for instance an OS kernel and a RAMDisk image.
*
* "Multi-File Images" start with a list of image sizes, each
* image size (in bytes) specified by an "uint32_t" in network
* byte order. This list is terminated by an "(uint32_t)0".
* Immediately after the terminating 0 follow the images, one by
* one, all aligned on "uint32_t" boundaries (size rounded up to
* a multiple of 4 bytes - except for the last file).
*
* "Firmware Images" are binary images containing firmware (like
* U-Boot or FPGA images) which usually will be programmed to
* flash memory.
*
* "Script files" are command sequences that will be executed by
* U-Boot's command interpreter; this feature is especially
* useful when you configure U-Boot to use a real shell (hush)
* as command interpreter (=> Shell Scripts).
*
* The following are exposed to uImage header.
* New IDs *MUST* be appended at the end of the list and *NEVER*
* inserted for backward compatibility.
*/
#define IH_TYPE_INVALID 0 /* Invalid Image */
#define IH_TYPE_STANDALONE 1 /* Standalone Program */
#define IH_TYPE_KERNEL 2 /* OS Kernel Image */
#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */
#define IH_TYPE_MULTI 4 /* Multi-File Image */
#define IH_TYPE_FIRMWARE 5 /* Firmware Image */
#define IH_TYPE_SCRIPT 6 /* Script file */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */
#define IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */
#define IH_TYPE_UBLIMAGE 11 /* Davinci UBL Image */
#define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */
#define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */
/* OS Kernel Image, can run from any load address */
#define IH_TYPE_KERNEL_NOLOAD 14
#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */
#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */
#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */
#define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */
#define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA CV/AV Preloader */
#define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */
#define IH_TYPE_LPC32XXIMAGE 21 /* x86 setup.bin Image */
#define IH_TYPE_LOADABLE 22 /* A list of typeless images */
#define IH_TYPE_RKIMAGE 23 /* Rockchip Boot Image */
#define IH_TYPE_RKSD 24 /* Rockchip SD card */
#define IH_TYPE_RKSPI 25 /* Rockchip SPI image */
#define IH_TYPE_ZYNQIMAGE 26 /* Xilinx Zynq Boot Image */
#define IH_TYPE_ZYNQMPIMAGE 27 /* Xilinx ZynqMP Boot Image */
#define IH_TYPE_ZYNQMPBIF 28 /* Xilinx ZynqMP Boot Image (bif) */
#define IH_TYPE_FPGA 29 /* FPGA Image */
#define IH_TYPE_VYBRIDIMAGE 30 /* VYBRID .vyb Image */
#define IH_TYPE_TEE 31 /* Trusted Execution Environment OS Image */
#define IH_TYPE_FIRMWARE_IVT 32 /* Firmware Image with HABv4 IVT */
#define IH_TYPE_PMMC 33 /* TI Power Management Micro-Controller Firmware */
#define IH_TYPE_STM32IMAGE 34 /* STMicroelectronics STM32 Image */
#define IH_TYPE_SOCFPGAIMAGE_V1 35 /* Altera SOCFPGA A10 Preloader */
#define IH_TYPE_MTKIMAGE 36 /* MediaTek BootROM loadable Image */
#define IH_TYPE_IMX8MIMAGE 37 /* Freescale IMX8MBoot Image */
#define IH_TYPE_IMX8IMAGE 38 /* Freescale IMX8Boot Image */
#define IH_TYPE_COPRO 39 /* Coprocessor Image for remoteproc*/
/*
* Compression Types
*
* The following are exposed to uImage header.
* New IDs *MUST* be appended at the end of the list and *NEVER*
* inserted for backward compatibility.
*/
#define IH_COMP_NONE 0 /* No Compression Used */
#define IH_COMP_GZIP 1 /* gzip Compression Used */
#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
#define IH_COMP_LZMA 3 /* lzma Compression Used */
#define IH_COMP_LZO 4 /* lzo Compression Used */
#define IH_COMP_LZ4 5 /* lz4 Compression Used */
#define LZ4F_MAGIC 0x184D2204 /* LZ4 Magic Number */
#define IH_MAGIC 0x27051956 /* Image Magic Number */
#define IH_NMLEN 32 /* Image Name Length */
/*
* Magic values specific to "openwrt,uimage" partitions
*/
#define IH_MAGIC_OKLI 0x4f4b4c49 /* 'OKLI' */
#define FW_EDIMAX_OFFSET 20 /* Edimax Firmware Offset */
#define FW_MAGIC_EDIMAX 0x43535953 /* Edimax Firmware Magic Number */
#endif /* __UIMAGE_H__ */

View File

@ -834,5 +834,3 @@ define Device/zyxel_wre6606
DEVICE_PACKAGES := -kmod-ath10k-ct kmod-ath10k-ct-smallbuffers
endef
TARGET_DEVICES += zyxel_wre6606
$(eval $(call BuildImage))

View File

@ -15,6 +15,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "edimax,br-6478ac-v2", "ralink,mt7620a-soc";
@ -116,7 +117,9 @@
};
partition@70000 {
compatible = "edimax,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,offset = <FW_EDIMAX_OFFSET>;
openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
label = "firmware";
reg = <0x00070000 0x00790000>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "edimax,ew-7478apc", "ralink,mt7620a-soc";
@ -102,7 +103,9 @@
};
partition@70000 {
compatible = "edimax,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,offset = <FW_EDIMAX_OFFSET>;
openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
label = "firmware";
reg = <0x00070000 0x00790000>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "ralink,mt7620a-soc";
@ -122,7 +123,9 @@
};
partition@70000 {
compatible = "edimax,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,offset = <FW_EDIMAX_OFFSET>;
openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
label = "firmware";
reg = <0x00070000 0x00790000>;
};

View File

@ -83,7 +83,8 @@
};
partition@50000 {
compatible = "fonfxc,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,padding = <32>;
label = "firmware";
reg = <0x50000 0xf90000>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
aliases {
@ -31,7 +32,8 @@
#size-cells = <1>;
partition@0 {
compatible = "openwrt,okli";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <IH_MAGIC_OKLI>;
label = "firmware";
reg = <0x0 0x0>;
};

View File

@ -34,7 +34,8 @@
};
partition@60000 {
compatible = "sge,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,padding = <96>;
label = "firmware";
reg = <0x60000 0xfa0000>;
};

View File

@ -89,7 +89,8 @@
partition@180000 {
label = "firmware";
compatible = "sge,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,padding = <96>;
reg = <0x180000 0x2800000>;
};
@ -101,7 +102,8 @@
partition@4980000 {
label = "firmware2";
compatible = "sge,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,padding = <96>;
reg = <0x4980000 0x2800000>;
};

View File

@ -4,6 +4,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "edimax,re23s", "mediatek,mt7621-soc";
@ -97,7 +98,9 @@
};
partition@70000 {
compatible = "edimax,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,offset = <FW_EDIMAX_OFFSET>;
openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
label = "firmware";
reg = <0x70000 0xf50000>;
};

View File

@ -1,7 +1,4 @@
#include "mt7621.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "mt7621_xiaomi_nand_128m.dtsi"
/ {
compatible = "xiaomi,mi-router-3g", "mediatek,mt7621-soc";
@ -15,10 +12,6 @@
label-mac-device = &gmac0;
};
chosen {
bootargs = "console=ttyS0,115200n8";
};
leds {
compatible = "gpio-leds";
@ -56,16 +49,6 @@
};
};
keys {
compatible = "gpio-keys";
reset {
label = "reset";
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
reg_usb_vbus: regulator {
compatible = "regulator-fixed";
regulator-name = "usb_vbus";
@ -80,92 +63,6 @@
vbus-supply = <&reg_usb_vbus>;
};
&nand {
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "Bootloader";
reg = <0x0 0x80000>;
read-only;
};
partition@80000 {
label = "Config";
reg = <0x80000 0x40000>;
};
partition@c0000 {
label = "Bdata";
reg = <0xc0000 0x40000>;
read-only;
};
factory: partition@100000 {
label = "factory";
reg = <0x100000 0x40000>;
read-only;
};
partition@140000 {
label = "crash";
reg = <0x140000 0x40000>;
};
partition@180000 {
label = "crash_syslog";
reg = <0x180000 0x40000>;
};
partition@1c0000 {
label = "reserved0";
reg = <0x1c0000 0x40000>;
read-only;
};
/* uboot expects to find kernels at 0x200000 & 0x600000
* referred to as system 1 & system 2 respectively.
* a kernel is considered suitable for handing control over
* if its linux magic number exists & uImage CRC are correct.
* If either of those conditions fail, a matching sys'n'_fail flag
* is set in uboot env & a restart performed in the hope that the
* alternate kernel is okay.
* if neither kernel checksums ok and both are marked failed, system 2
* is booted anyway.
*
* Note uboot's tftp flash install writes the transferred
* image to both kernel partitions.
*/
partition@200000 {
label = "kernel_stock";
reg = <0x200000 0x400000>;
};
partition@600000 {
label = "kernel";
reg = <0x600000 0x400000>;
};
/* ubi partition is the result of squashing
* next consecutive stock partitions:
* - rootfs0 (rootfs partition for stock kernel0),
* - rootfs1 (rootfs partition for stock failsafe kernel1),
* - overlay (used as ubi overlay in stock fw)
* resulting 117,5MiB space for packages.
*/
partition@a00000 {
label = "ubi";
reg = <0xa00000 0x7580000>;
};
};
};
&pcie {
status = "okay";
};

View File

@ -0,0 +1,96 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "mt7621_xiaomi_nand_128m.dtsi"
/ {
compatible = "xiaomi,mi-router-4", "mediatek,mt7621-soc";
model = "Xiaomi Mi Router 4";
aliases {
led-boot = &led_status_yellow;
led-failsafe = &led_status_red;
led-running = &led_status_blue;
led-upgrade = &led_status_yellow;
label-mac-device = &gmac0;
};
leds {
compatible = "gpio-leds";
led_status_red: status_red {
label = "red:status";
gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
};
led_status_blue: status_blue {
label = "blue:status";
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
};
led_status_yellow: status_yellow {
label = "yellow:status";
gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
};
};
};
&keys {
minet {
label = "minet";
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WPS_BUTTON>;
};
};
&pcie {
status = "okay";
};
&pcie0 {
wifi@0,0 {
compatible = "pci14c3,7603";
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x0000>;
ieee80211-freq-limit = <2400000 2500000>;
};
};
&pcie1 {
wifi@0,0 {
compatible = "pci14c3,7662";
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x8000>;
ieee80211-freq-limit = <5000000 6000000>;
};
};
&gmac0 {
mtd-mac-address = <&factory 0xe000>;
};
&switch0 {
ports {
port@1 {
status = "okay";
label = "lan2";
};
port@2 {
status = "okay";
label = "lan1";
};
port@4 {
status = "okay";
label = "wan";
mtd-mac-address = <&factory 0xe006>;
};
};
};
&state_default {
gpio {
groups = "jtag", "uart2", "uart3", "wdt";
function = "gpio";
};
};

View File

@ -0,0 +1,109 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "mt7621.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
chosen {
bootargs = "console=ttyS0,115200n8";
};
keys: keys {
compatible = "gpio-keys";
reset {
label = "reset";
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
};
&nand {
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "Bootloader";
reg = <0x0 0x80000>;
read-only;
};
partition@80000 {
label = "Config";
reg = <0x80000 0x40000>;
};
partition@c0000 {
label = "Bdata";
reg = <0xc0000 0x40000>;
read-only;
};
factory: partition@100000 {
label = "factory";
reg = <0x100000 0x40000>;
read-only;
};
partition@140000 {
label = "crash";
reg = <0x140000 0x40000>;
};
partition@180000 {
label = "crash_syslog";
reg = <0x180000 0x40000>;
};
partition@1c0000 {
label = "reserved0";
reg = <0x1c0000 0x40000>;
read-only;
};
/* uboot expects to find kernels at 0x200000 & 0x600000
* referred to as system 1 & system 2 respectively.
* a kernel is considered suitable for handing control over
* if its linux magic number exists & uImage CRC are correct.
* If either of those conditions fail, a matching sys'n'_fail flag
* is set in uboot env & a restart performed in the hope that the
* alternate kernel is okay.
* if neither kernel checksums ok and both are marked failed, system 2
* is booted anyway.
*
* Note uboot's tftp flash install writes the transferred
* image to both kernel partitions.
*/
/* We keep stock xiaomi firmware (kernel0) here */
partition@200000 {
label = "kernel_stock";
reg = <0x200000 0x400000>;
};
partition@600000 {
label = "kernel";
reg = <0x600000 0x400000>;
};
/* ubi partition is the result of squashing
* next consecutive stock partitions:
* - rootfs0 (rootfs partition for stock kernel0),
* - rootfs1 (rootfs partition for stock failsafe kernel1),
* - overlay (used as ubi overlay in stock fw)
* resulting 117,5MiB space for packages.
*/
partition@a00000 {
label = "ubi";
reg = <0xa00000 0x7580000>;
};
};
};

View File

@ -1,90 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "mt7621.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
chosen {
bootargs = "console=ttyS0,115200n8";
};
keys {
compatible = "gpio-keys";
reset {
label = "reset";
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
};
&nand {
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "Bootloader";
reg = <0x0 0x80000>;
read-only;
};
partition@80000 {
label = "Config";
reg = <0x80000 0x40000>;
};
partition@c0000 {
label = "Bdata";
reg = <0xc0000 0x40000>;
read-only;
};
factory: partition@100000 {
label = "factory";
reg = <0x100000 0x40000>;
read-only;
};
partition@140000 {
label = "crash";
reg = <0x140000 0x40000>;
};
partition@180000 {
label = "crash_syslog";
reg = <0x180000 0x40000>;
};
partition@1c0000 {
label = "reserved0";
reg = <0x1c0000 0x40000>;
read-only;
};
/* We keep stock xiaomi firmware (kernel0) here */
partition@200000 {
label = "kernel_stock";
reg = <0x200000 0x400000>;
};
partition@600000 {
label = "kernel";
reg = <0x600000 0x400000>;
};
partition@a00000 {
label = "ubi";
reg = <0xa00000 0x7580000>;
};
};
};
#include "mt7621_xiaomi_nand_128m.dtsi"
&pcie {
status = "okay";

View File

@ -2,6 +2,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "edimax,3g-6200n", "ralink,rt3050-soc";
@ -50,7 +51,9 @@
};
partition@50000 {
compatible = "edimax,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,offset = <FW_EDIMAX_OFFSET>;
openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
label = "firmware";
reg = <0x50000 0x390000>;
};

View File

@ -2,6 +2,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "edimax,3g-6200nl", "ralink,rt3050-soc";
@ -50,7 +51,9 @@
};
partition@50000 {
compatible = "edimax,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,offset = <FW_EDIMAX_OFFSET>;
openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
label = "firmware";
reg = <0x50000 0x390000>;
};

View File

@ -2,6 +2,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mtd/partitions/uimage.h>
/ {
compatible = "edimax,br-6475nd", "ralink,rt3662-soc", "ralink,rt3883-soc";
@ -86,7 +87,9 @@
};
partition@70000 {
compatible = "edimax,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,offset = <FW_EDIMAX_OFFSET>;
openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
reg = <0x00070000 0x00790000>;
label = "firmware";
};

View File

@ -1218,39 +1218,27 @@ define Device/winstars_ws-wn583a6
endef
TARGET_DEVICES += winstars_ws-wn583a6
define Device/xiaomi-ac2100
define Device/xiaomi_nand_separate
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
DEVICE_VENDOR := Xiaomi
DEVICE_PACKAGES := uboot-envtools
BLOCKSIZE := 128k
PAGESIZE := 2048
KERNEL_SIZE := 4096k
IMAGE_SIZE := 120320k
UBINIZE_OPTS := -E 5
IMAGES += kernel1.bin rootfs0.bin
IMAGE/kernel1.bin := append-kernel
IMAGE/rootfs0.bin := append-ubi | check-size
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
DEVICE_VENDOR := Xiaomi
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware \
uboot-envtools
endef
define Device/xiaomi_mi-router-3g
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
BLOCKSIZE := 128k
PAGESIZE := 2048
KERNEL_SIZE := 4096k
IMAGE_SIZE := 124416k
UBINIZE_OPTS := -E 5
IMAGES += kernel1.bin rootfs0.bin
IMAGE/kernel1.bin := append-kernel
IMAGE/rootfs0.bin := append-ubi | check-size
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
DEVICE_VENDOR := Xiaomi
$(Device/xiaomi_nand_separate)
DEVICE_MODEL := Mi Router 3G
DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport uboot-envtools
IMAGE_SIZE := 124416k
DEVICE_PACKAGES += kmod-mt7603 kmod-mt76x2 kmod-usb3 \
kmod-usb-ledtrig-usbport
SUPPORTED_DEVICES += R3G mir3g xiaomi,mir3g
endef
TARGET_DEVICES += xiaomi_mi-router-3g
@ -1287,6 +1275,14 @@ define Device/xiaomi_mi-router-3-pro
endef
TARGET_DEVICES += xiaomi_mi-router-3-pro
define Device/xiaomi_mi-router-4
$(Device/xiaomi_nand_separate)
DEVICE_MODEL := Mi Router 4
IMAGE_SIZE := 124416k
DEVICE_PACKAGES += kmod-mt7603 kmod-mt76x2
endef
TARGET_DEVICES += xiaomi_mi-router-4
define Device/xiaomi_mi-router-4a-gigabit
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
@ -1299,14 +1295,18 @@ endef
TARGET_DEVICES += xiaomi_mi-router-4a-gigabit
define Device/xiaomi_mi-router-ac2100
$(Device/xiaomi-ac2100)
$(Device/xiaomi_nand_separate)
DEVICE_MODEL := Mi Router AC2100
IMAGE_SIZE := 120320k
DEVICE_PACKAGES += kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
endef
TARGET_DEVICES += xiaomi_mi-router-ac2100
define Device/xiaomi_redmi-router-ac2100
$(Device/xiaomi-ac2100)
$(Device/xiaomi_nand_separate)
DEVICE_MODEL := Redmi Router AC2100
IMAGE_SIZE := 120320k
DEVICE_PACKAGES += kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
endef
TARGET_DEVICES += xiaomi_redmi-router-ac2100

View File

@ -19,6 +19,7 @@ ramips_setup_interfaces()
mikrotik,routerboard-m33g|\
xiaomi,mi-router-3g|\
xiaomi,mi-router-3g-v2|\
xiaomi,mi-router-4|\
xiaomi,mi-router-4a-gigabit)
ucidef_set_interfaces_lan_wan "lan1 lan2" "wan"
;;

View File

@ -63,6 +63,7 @@ platform_do_upgrade() {
netis,wf2881|\
xiaomi,mi-router-3g|\
xiaomi,mi-router-3-pro|\
xiaomi,mi-router-4|\
xiaomi,mi-router-ac2100|\
xiaomi,redmi-router-ac2100)
nand_do_upgrade "$1"

View File

@ -70,7 +70,8 @@
};
partition@300000{
label = "firmware";
compatible = "netgear,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x4e474520>;
reg = <0x0300000 0x1d00000>;
};
};

View File

@ -95,7 +95,8 @@
partition@2a0000 {
label = "firmware";
reg = <0x2a0000 0xd60000>;
compatible = "allnet,uimage";
compatible = "openwrt,uimage", "denx,uimage";
openwrt,ih-magic = <0x00000006>;
};
};
};

View File

@ -27,6 +27,7 @@ define Host/Compile
$(call cc,add_header)
$(call cc,addpattern)
$(call cc,asustrx)
$(call cc,bcm4908asus,-Wall)
$(call cc,bcm4908img,-Wall)
$(call cc,bcm4908kernel,-Wall)
$(call cc,buffalo-enc buffalo-lib,-Wall)

View File

@ -0,0 +1,444 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
*/
#include <byteswap.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#if __BYTE_ORDER == __BIG_ENDIAN
#define cpu_to_le32(x) bswap_32(x)
#define le32_to_cpu(x) bswap_32(x)
#define cpu_to_le16(x) bswap_16(x)
#define le16_to_cpu(x) bswap_16(x)
#elif __BYTE_ORDER == __LITTLE_ENDIAN
#define cpu_to_le32(x) (x)
#define le32_to_cpu(x) (x)
#define cpu_to_le16(x) (x)
#define le16_to_cpu(x) (x)
#else
#error "Unsupported endianness"
#endif
/* BCM4908 specific tail - appended to the firmware image */
struct bcm4908img_tail {
uint32_t crc32;
uint32_t unk1;
uint32_t family;
uint32_t unk2;
uint32_t unk3;
};
/* Asus BCM4908 tail - placed at the end of BCM4908 firmware, right before BCM4908 tail */
struct bcm4908asus_tail {
uint8_t fw_ver[4];
uint16_t build_no;
uint16_t extend_no_u16;
char productid[12]; /* The longest seen was 9 (e.g. GT-AC5300) */
uint8_t unused1[8];
uint32_t extend_no_u32;
uint8_t unused2[31];
uint8_t ver_flags; /* Version or flags (only seen values: 0x00 and 0x01) */
};
/*
* Example:
*
* 0053ffb0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
* 0053ffc0 03 00 00 04 80 01 94 52 47 54 2d 41 43 35 33 30 |.......RGT-AC530|
* 0053ffd0 30 00 00 00 00 00 00 00 00 00 00 00 94 52 00 00 |0............R..|
* 0053ffe0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
* 0053fff0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 |................|
* 00540000 c4 20 e6 72 32 57 00 00 08 49 00 00 03 00 00 00 |. .r2W...I......|
* 00540010 02 00 00 00 |....|
*/
char *in_path = NULL;
char *out_path = NULL;
static inline size_t bcm4908asus_min(size_t x, size_t y) {
return x < y ? x : y;
}
static const uint32_t crc32_tbl[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
uint32_t bcm4908img_crc32(uint32_t crc, uint8_t *buf, size_t len) {
while (len) {
crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8);
buf++;
len--;
}
return crc;
}
/**************************************************
* Info
**************************************************/
static int bcm4908asus_info(int argc, char **argv)
{
struct bcm4908asus_tail asus_tail;
struct bcm4908img_tail img_tail;
struct stat st;
const char *pathname;
size_t bytes, length;
uint8_t buf[1024];
uint32_t crc32;
bool empty;
FILE *fp;
int i;
int err = 0;
if (argc < 3) {
fprintf(stderr, "No BCM4908 Asus image pathname passed\n");
err = -EINVAL;
goto out;
}
pathname = argv[2];
if (stat(pathname, &st)) {
fprintf(stderr, "Failed to stat %s\n", pathname);
err = -EIO;
goto out;
}
fp = fopen(pathname, "r");
if (!fp) {
fprintf(stderr, "Failed to open %s\n", pathname);
err = -EACCES;
goto out;
}
crc32 = 0xffffffff;
length = st.st_size - sizeof(asus_tail) - sizeof(img_tail);
while (length && (bytes = fread(buf, 1, bcm4908asus_min(sizeof(buf), length), fp)) > 0) {
crc32 = bcm4908img_crc32(crc32, buf, bytes);
length -= bytes;
}
if (length) {
fprintf(stderr, "Failed to read from %s\n", pathname);
err = -EIO;
goto err_close;
}
if (fread(&asus_tail, 1, sizeof(asus_tail), fp) != sizeof(asus_tail)) {
fprintf(stderr, "Failed to read BCM4908 Asus image tail\n");
err = -EIO;
goto err_close;
}
crc32 = bcm4908img_crc32(crc32, (uint8_t *)&asus_tail, sizeof(asus_tail));
if (fread(&img_tail, 1, sizeof(img_tail), fp) != sizeof(img_tail)) {
fprintf(stderr, "Failed to read BCM4908 Asus image tail\n");
err = -EIO;
goto err_close;
}
if (crc32 != le32_to_cpu(img_tail.crc32)) {
fprintf(stderr, "Invalid crc32 (calculated 0x%08x expected 0x%08x)\n", crc32, le32_to_cpu(img_tail.crc32));
err = -EINVAL;
goto err_close;
}
empty = true;
for (i = 0; i < sizeof(asus_tail); i++) {
if (((uint8_t *)&asus_tail)[i] != 0xff) {
empty = false;
break;
}
}
if (empty) {
fprintf(stderr, "BCM4908 image doesn't contain Asus tail\n");
err = -EINVAL;
goto err_close;
}
printf("Firmware version:\t%u.%u.%u.%u\n", asus_tail.fw_ver[0], asus_tail.fw_ver[1], asus_tail.fw_ver[2], asus_tail.fw_ver[3]);
printf("Build number:\t\t%u\n", le16_to_cpu(asus_tail.build_no));
printf("Extended number:\t%u\n", asus_tail.ver_flags & 0x1 ? le32_to_cpu(asus_tail.extend_no_u32) : le16_to_cpu(asus_tail.extend_no_u16));
printf("Product ID:\t\t%s\n", asus_tail.productid);
err_close:
fclose(fp);
out:
return err;
}
/**************************************************
* Create
**************************************************/
static void bcm4908asus_create_parse_options(int argc, char **argv, struct bcm4908asus_tail *tail)
{
uint32_t tmp32;
uint16_t tmp16;
int c;
while ((c = getopt(argc, argv, "i:o:p:f:b:e:")) != -1) {
switch (c) {
case 'i':
in_path = optarg;
break;
case 'o':
out_path = optarg;
break;
case 'p':
strncpy(tail->productid, optarg, sizeof(tail->productid));
break;
case 'f':
if (sscanf(optarg, "%hhu.%hhu.%hhu.%hhu", &(tail->fw_ver[0]), &tail->fw_ver[1], &tail->fw_ver[2], &tail->fw_ver[3]) != 4)
fprintf(stderr, "Version %s doesn't match suppored 4-digits format\n", optarg);
break;
case 'b':
tmp16 = strtol(optarg, NULL, 0);
tail->build_no = cpu_to_le16(tmp16);
break;
case 'e':
tmp32 = strtol(optarg, NULL, 0);
tail->ver_flags = 0x01;
tail->extend_no_u32 = cpu_to_le32(tmp32);
tail->extend_no_u16 = cpu_to_le16((uint16_t)tmp32);
break;
}
}
}
static int bcm4908asus_create(int argc, char **argv)
{
struct bcm4908asus_tail asus_tail = {};
struct bcm4908img_tail img_tail = {};
struct stat st;
uint32_t crc32_old;
uint32_t crc32_new;
uint8_t buf[1024];
FILE *out = NULL;
FILE *in = NULL;
size_t length;
size_t bytes;
FILE *fp;
int i;
int err = 0;
/* Parse & validate arguments */
bcm4908asus_create_parse_options(argc, argv, &asus_tail);
if (!in_path) {
fprintf(stderr, "No BCM4908 Asus image pathname passed\n");
err = -EINVAL;
goto err;
}
/* Check input file: size, access, empty space for Asus tail */
if (stat(in_path, &st)) {
fprintf(stderr, "Failed to stat %s\n", in_path);
err = -EIO;
goto err;
}
in = fopen(in_path, "r+");
if (!in) {
fprintf(stderr, "Failed to open %s\n", in_path);
err = -EIO;
goto err;
}
length = st.st_size - sizeof(asus_tail) - sizeof(img_tail);
fseek(in, length, SEEK_SET);
if (fread(buf, 1, sizeof(asus_tail), in) != sizeof(asus_tail)) {
fprintf(stderr, "Failed to read BCM4908 image from %s\n", in_path);
err = -EIO;
goto err;
}
for (i = 0; i < sizeof(asus_tail); i++) {
if (buf[i] != 0xff) {
fprintf(stderr, "Input BCM4908 image doesn't have empty 64 B tail\n");
err = -ENOSPC;
goto err;
}
}
rewind(in);
/* Create new BCM4908 Asus image file if requested (otherwise input file will get modified) */
if (out_path && !(out = fopen(out_path, "w+"))) {
fprintf(stderr, "Failed to open %s\n", out_path);
err = -EIO;
goto err;
}
/* Calculate CRC for data that doesn't get modified. Optionally copy input file if requested */
crc32_old = 0xffffffff;
length = st.st_size - sizeof(asus_tail) - sizeof(img_tail);
while (length && (bytes = fread(buf, 1, bcm4908asus_min(sizeof(buf), length), in)) > 0) {
if (out && fwrite(buf, 1, bytes, out) != bytes) {
fprintf(stderr, "Failed to write %zu B to %s\n", bytes, out_path);
err = -EIO;
goto err;
}
crc32_old = bcm4908img_crc32(crc32_old, buf, bytes);
length -= bytes;
}
if (length) {
fprintf(stderr, "Failed to read from %s\n", in_path);
err = -EIO;
goto err;
}
crc32_new = crc32_old;
/* Finish calculating old checksum & verify it */
for (i = 0; i < sizeof(asus_tail); i++) {
uint8_t val = 0xff;
crc32_old = bcm4908img_crc32(crc32_old, &val, 1);
}
fseek(in, sizeof(asus_tail), SEEK_CUR);
if (fread(&img_tail, 1, sizeof(img_tail), in) != sizeof(img_tail)) {
fprintf(stderr, "Failed to read BCM4908 image tail from %s\n", in_path);
err = -EIO;
goto err;
}
if (crc32_old != le32_to_cpu(img_tail.crc32)) {
fprintf(stderr, "Invalid data crc32: calculated 0x%08x instead of 0x%08x\n", crc32_old, le32_to_cpu(img_tail.crc32));
err = -EPROTO;
goto err;
}
/* Write Asus tail & updated BCM4908 tail */
if (out) {
fp = out;
} else {
fp = in;
fseek(in, -sizeof(asus_tail) - sizeof(img_tail), SEEK_CUR);
}
if (fwrite(&asus_tail, 1, sizeof(asus_tail), fp) != sizeof(asus_tail)) {
fprintf(stderr, "Failed to write BCM4908 image Asus tail to %s\n", out_path);
err = -EIO;
goto err;
}
crc32_new = bcm4908img_crc32(crc32_new, (uint8_t *)&asus_tail, sizeof(asus_tail));
img_tail.crc32 = cpu_to_le32(crc32_new);
if (fwrite(&img_tail, 1, sizeof(img_tail), fp) != sizeof(img_tail)) {
fprintf(stderr, "Failed to write BCM4908 image tail to %s\n", out_path);
err = -EIO;
goto err;
}
err:
if (out)
fclose(out);
if (in)
fclose(in);
return err;
}
static void usage() {
printf("Usage:\n");
printf("\n");
printf("Info about BCM4908 Asus image:\n");
printf("\tbcm4908asus info <file>\tget info about BCM4908 Asus image\n");
printf("\n");
printf("Create a BCM4908 Asus image:\n");
printf("\tbcm4908asus create\tinsert Asus info into BCM4908 image\n");
printf("\t-i file\t\t\t\tinput BCM4908 image file (required)\n");
printf("\t-o file\t\t\t\toutput BCM4908 Asus image file\n");
printf("\t-p productid\t\t\tproduct (device) ID\n");
printf("\t-f firmware version\t\tfirmware version formatted with 4 digits like: 1.2.3.4\n");
printf("\t-b build number\t\tbuild number (e.g. 380, 382, 384)\n");
printf("\t-e extend number\t\textended number (e.g. 21140, 81622, 81695, 82037)\n");
}
int main(int argc, char **argv) {
if (argc > 1) {
if (!strcmp(argv[1], "info"))
return bcm4908asus_info(argc, argv);
else if (!strcmp(argv[1], "create"))
return bcm4908asus_create(argc, argv);
}
usage();
return 0;
}