diff --git a/include/image-commands.mk b/include/image-commands.mk index 684646e233..2c56ed8d1d 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -27,6 +27,10 @@ define Build/append-kernel dd if=$(IMAGE_KERNEL) >> $@ endef +define Build/append-image + dd if=$(BIN_DIR)/$(DEVICE_IMG_PREFIX)-$(1) >> $@ +endef + compat_version=$(if $(DEVICE_COMPAT_VERSION),$(DEVICE_COMPAT_VERSION),1.0) json_quote=$(subst ','\'',$(subst ",\",$(1))) #")') diff --git a/include/image.mk b/include/image.mk index 48038f4c7c..0ab616dbcf 100644 --- a/include/image.mk +++ b/include/image.mk @@ -419,7 +419,7 @@ DEFAULT_DEVICE_VARS := \ CMDLINE UBOOTENV_IN_UBI KERNEL_IN_UBI BLOCKSIZE PAGESIZE SUBPAGESIZE \ VID_HDR_OFFSET UBINIZE_OPTS UBINIZE_PARTS MKUBIFS_OPTS DEVICE_DTS \ DEVICE_DTS_CONFIG DEVICE_DTS_DIR DEVICE_DTS_OVERLAY DEVICE_FDT_NUM \ - SOC BOARD_NAME UIMAGE_MAGIC UIMAGE_NAME \ + DEVICE_IMG_PREFIX SOC BOARD_NAME UIMAGE_MAGIC UIMAGE_NAME \ SUPPORTED_DEVICES IMAGE_METADATA KERNEL_ENTRY KERNEL_LOADADDR \ UBOOT_PATH IMAGE_SIZE \ DEVICE_COMPAT_VERSION DEVICE_COMPAT_MESSAGE \ @@ -478,6 +478,7 @@ define Device/Build/initramfs $$(if $$(CONFIG_JSON_OVERVIEW_IMAGE_INFO), $(BUILD_DIR)/json_info_files/$$(KERNEL_INITRAMFS_IMAGE).json,)) $(KDIR)/$$(KERNEL_INITRAMFS_NAME):: image_prepare + $(1)-images: $(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE) $(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE): $(KDIR)/tmp/$$(KERNEL_INITRAMFS_IMAGE) cp $$^ $$@ @@ -570,6 +571,7 @@ define Device/Build/image $(BUILD_DIR)/json_info_files/$(call DEVICE_IMG_NAME,$(1),$(2)).json, \ $(BIN_DIR)/$(call DEVICE_IMG_NAME,$(1),$(2))$$(GZ_SUFFIX)) $(eval $(call Device/Export,$(KDIR)/tmp/$(call DEVICE_IMG_NAME,$(1),$(2)),$(1))) + $(3)-images: $(BIN_DIR)/$(call DEVICE_IMG_NAME,$(1),$(2))$$(GZ_SUFFIX) ROOTFS/$(1)/$(3) := \ $(KDIR)/root.$(1)$$(strip \ @@ -628,7 +630,7 @@ endef define Device/Build/artifact $$(_TARGET): $(BIN_DIR)/$(DEVICE_IMG_PREFIX)-$(1) $(eval $(call Device/Export,$(KDIR)/tmp/$(DEVICE_IMG_PREFIX)-$(1))) - $(KDIR)/tmp/$(DEVICE_IMG_PREFIX)-$(1): $$(KDIR_KERNEL_IMAGE) + $(KDIR)/tmp/$(DEVICE_IMG_PREFIX)-$(1): $$(KDIR_KERNEL_IMAGE) $(2)-images @rm -f $$@ $$(call concat_cmd,$(ARTIFACT/$(1))) @@ -651,7 +653,7 @@ define Device/Build $$(call Device/Build/image,$$(fs),$$(image),$(1))))) $$(eval $$(foreach artifact,$$(ARTIFACTS), \ - $$(call Device/Build/artifact,$$(artifact)))) + $$(call Device/Build/artifact,$$(artifact),$(1)))) endef diff --git a/include/kernel-version.mk b/include/kernel-version.mk index b5762dd831..e7bc91c06e 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -7,10 +7,10 @@ ifdef CONFIG_TESTING_KERNEL endif LINUX_VERSION-5.4 = .106 -LINUX_VERSION-5.10 = .23 +LINUX_VERSION-5.10 = .26 LINUX_KERNEL_HASH-5.4.106 = cc873b2c39c1823d4bc4f6cde527943c8cfd28ae94cb517804b0f9679359c8db -LINUX_KERNEL_HASH-5.10.23 = f6e21c03ec6ff85b26d77c59fdab81e64707792a57593643307df192749edb6a +LINUX_KERNEL_HASH-5.10.26 = fc532833f1ac167f363f1b9de85db39d2d635ab516f66dc381bdd70804601482 remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) diff --git a/include/prereq-build.mk b/include/prereq-build.mk index b2526a1ec1..0375ef6861 100644 --- a/include/prereq-build.mk +++ b/include/prereq-build.mk @@ -136,6 +136,10 @@ $(eval $(call SetupHostCommand,bzip2,Please install 'bzip2', \ $(eval $(call SetupHostCommand,wget,Please install GNU 'wget', \ wget --version | grep GNU)) +$(eval $(call SetupHostCommand,install,Please install GNU 'install', \ + install --version | grep GNU, \ + ginstall --version | grep GNU)) + $(eval $(call SetupHostCommand,perl,Please install Perl 5.x, \ perl --version | grep "perl.*v5")) diff --git a/package/kernel/mwlwifi/Makefile b/package/kernel/mwlwifi/Makefile index 648c826ccb..eb986dca03 100644 --- a/package/kernel/mwlwifi/Makefile +++ b/package/kernel/mwlwifi/Makefile @@ -21,6 +21,7 @@ PKG_MIRROR_HASH:=0eda0e774a87e58e611d6436350e1cf2be3de50fddde334909a07a15b0c9862 PKG_MAINTAINER:=Imre Kaloz PKG_BUILD_PARALLEL:=1 +PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/package.mk diff --git a/package/libs/elfutils/Makefile b/package/libs/elfutils/Makefile index dd0b8ecdde..3e36dc27b8 100644 --- a/package/libs/elfutils/Makefile +++ b/package/libs/elfutils/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=elfutils PKG_VERSION:=0.180 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION) @@ -21,7 +21,7 @@ PKG_CPE_ID:=cpe:/a:elfutils_project:elfutils PKG_FIXUP:=autoreconf PKG_INSTALL:=1 -PKG_USE_MIPS16:=0 +PKG_USE_MIPS16:=1 PKG_BUILD_DEPENDS:=!USE_GLIBC:argp-standalone include $(INCLUDE_DIR)/package.mk diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile index 64b6c7bcda..6fb9f73c3d 100644 --- a/package/utils/ucode/Makefile +++ b/package/utils/ucode/Makefile @@ -14,7 +14,7 @@ PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/jow-/ucode.git PKG_SOURCE_DATE:=2021-03-19 PKG_SOURCE_VERSION:=4a5b9010ccc56fdf288fe758023af445feb93fad -PKG_MIRROR_HASH:=145a2ce69e14cae9b448de85b94c7a817ba3aea04b1611399186ad36fb88958e +PKG_MIRROR_HASH:=2d15fe2f51ebdeae532a2e8130689400cf2364876e737cfbb1bf9c045719acf1 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/rules.mk b/rules.mk index 8f41ff5861..f31d9bb113 100644 --- a/rules.mk +++ b/rules.mk @@ -75,12 +75,12 @@ IS_PACKAGE_BUILD := $(if $(filter package/%,$(BUILD_SUBDIR)),1) OPTIMIZE_FOR_CPU=$(subst i386,i486,$(ARCH)) ifneq (,$(findstring $(ARCH) , aarch64 aarch64_be powerpc )) - FPIC:=-fPIC + FPIC:=-DPIC -fPIC else - FPIC:=-fpic + FPIC:=-DPIC -fpic endif -HOST_FPIC:=-fPIC +HOST_FPIC:=-DPIC -fPIC ARCH_SUFFIX:=$(call qstrip,$(CONFIG_CPU_TYPE)) GCC_ARCH:= diff --git a/scripts/json_overview_image_info.py b/scripts/json_overview_image_info.py index 23d8dcb857..8dbd24af2d 100755 --- a/scripts/json_overview_image_info.py +++ b/scripts/json_overview_image_info.py @@ -38,10 +38,9 @@ if output: "make", "--no-print-directory", "-C", - "target/linux/{}".format(output["target"].split("/")[0]), + "target/linux/", "val.DEFAULT_PACKAGES", "val.ARCH_PACKAGES", - "DUMP=1", ], stdout=PIPE, stderr=PIPE, @@ -50,7 +49,8 @@ if output: universal_newlines=True, ).stdout.splitlines() - output["default_packages"] = default_packages.split() + output["default_packages"] = sorted(default_packages.split()) + output_path.write_text(json.dumps(output, sort_keys=True, separators=(",", ":"))) else: print("JSON info file script could not find any JSON files for target") diff --git a/target/linux/apm821xx/patches-5.10/802-usb-xhci-force-msi-renesas-xhci.patch b/target/linux/apm821xx/patches-5.10/802-usb-xhci-force-msi-renesas-xhci.patch index 5de02ae679..ed557fd0dc 100644 --- a/target/linux/apm821xx/patches-5.10/802-usb-xhci-force-msi-renesas-xhci.patch +++ b/target/linux/apm821xx/patches-5.10/802-usb-xhci-force-msi-renesas-xhci.patch @@ -13,7 +13,7 @@ produce a noisy warning. --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c -@@ -260,6 +260,7 @@ static void xhci_pci_quirks(struct devic +@@ -261,6 +261,7 @@ static void xhci_pci_quirks(struct devic pdev->device == 0x0015) { xhci->quirks |= XHCI_RESET_ON_RESUME; xhci->quirks |= XHCI_ZERO_64B_REGS; @@ -43,7 +43,7 @@ produce a noisy warning. hcd->msi_enabled = 1; --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1886,6 +1886,7 @@ struct xhci_hcd { +@@ -1887,6 +1887,7 @@ struct xhci_hcd { struct xhci_hub usb2_rhub; struct xhci_hub usb3_rhub; /* support xHCI 1.0 spec USB2 hardware LPM */ diff --git a/target/linux/ath79/patches-5.10/0036-GPIO-add-named-gpio-exports.patch b/target/linux/ath79/patches-5.10/0036-GPIO-add-named-gpio-exports.patch index fe34f0b21b..09bad30109 100644 --- a/target/linux/ath79/patches-5.10/0036-GPIO-add-named-gpio-exports.patch +++ b/target/linux/ath79/patches-5.10/0036-GPIO-add-named-gpio-exports.patch @@ -141,7 +141,7 @@ Signed-off-by: John Crispin { --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h -@@ -713,6 +713,7 @@ static inline void devm_acpi_dev_remove_ +@@ -715,6 +715,7 @@ static inline void devm_acpi_dev_remove_ #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) @@ -149,7 +149,7 @@ Signed-off-by: John Crispin int gpiod_export(struct gpio_desc *desc, bool direction_may_change); int gpiod_export_link(struct device *dev, const char *name, struct gpio_desc *desc); -@@ -720,6 +721,13 @@ void gpiod_unexport(struct gpio_desc *de +@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ diff --git a/target/linux/ath79/patches-5.10/471-mtd-cfi_cmdset_0002-AMD-chip-0x2201-write-words.patch b/target/linux/ath79/patches-5.10/471-mtd-cfi_cmdset_0002-AMD-chip-0x2201-write-words.patch new file mode 100644 index 0000000000..35ea92a7bc --- /dev/null +++ b/target/linux/ath79/patches-5.10/471-mtd-cfi_cmdset_0002-AMD-chip-0x2201-write-words.patch @@ -0,0 +1,51 @@ +From f1f811410af297c848e9ec17eaa280d190fdce10 Mon Sep 17 00:00:00 2001 +From: Mauri Sandberg +Date: Tue, 23 Feb 2021 18:09:31 +0200 +Subject: [PATCH] mtd: cfi_cmdset_0002: AMD chip 0x2201 - write words + +Buffer writes do not work with AMD chip 0x2201. The chip in question +is a AMD/Spansion/Cypress Semiconductor S29GL256N and datasheet [1] +talks about writing buffers being possible. While waiting for a neater +solution resort to writing word-sized chunks only. + +Without the patch kernel logs will be flooded with entries like below: + +jffs2_scan_eraseblock(): End of filesystem marker found at 0x0 +jffs2_build_filesystem(): unlocking the mtd device... +done. +jffs2_build_filesystem(): erasing all blocks after the end marker... +MTD do_write_buffer_wait(): software timeout, address:0x01ec000a. +jffs2: Write clean marker to block at 0x01920000 failed: -5 +MTD do_write_buffer_wait(): software timeout, address:0x01e2000a. +jffs2: Write clean marker to block at 0x01880000 failed: -5 +MTD do_write_buffer_wait(): software timeout, address:0x01e0000a. +jffs2: Write clean marker to block at 0x01860000 failed: -5 +MTD do_write_buffer_wait(): software timeout, address:0x01dc000a. +jffs2: Write clean marker to block at 0x01820000 failed: -5 +MTD do_write_buffer_wait(): software timeout, address:0x01da000a. +jffs2: Write clean marker to block at 0x01800000 failed: -5 +... + +Tested on a Buffalo wzr-hp-g300nh running kernel 5.10.16. + +[1] https://www.cypress.com/file/219941/download +or https://datasheetspdf.com/pdf-file/565708/SPANSION/S29GL256N/1 + +Signed-off-by: Mauri Sandberg +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -272,6 +272,10 @@ static void fixup_use_write_buffers(stru + { + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; ++ ++ if ((cfi->mfr == CFI_MFR_AMD) && (cfi->id == 0x2201)) ++ return; ++ + if (cfi->cfiq->BufWriteTimeoutTyp) { + pr_debug("Using buffer write method\n"); + mtd->_write = cfi_amdstd_write_buffers; diff --git a/target/linux/bcm63xx/patches-5.10/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch b/target/linux/bcm63xx/patches-5.10/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch index 6d91129932..5822166485 100644 --- a/target/linux/bcm63xx/patches-5.10/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch +++ b/target/linux/bcm63xx/patches-5.10/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch @@ -4,7 +4,7 @@ Date: Mon, 28 Jan 2013 20:06:30 +0100 Subject: [PATCH 12/12] MIPS: BCM63XX: EHCI controller does not support overcurrent -This patch sets the ignore_oc flag for the BCM63XX EHCI controller as it +This patch sets the spurious_oc flag for the BCM63XX EHCI controller as it does not support proper overcurrent reporting. Signed-off-by: Florian Fainelli @@ -18,7 +18,7 @@ Signed-off-by: Florian Fainelli static struct usb_ehci_pdata bcm63xx_ehci_pdata = { .big_endian_desc = 1, .big_endian_mmio = 1, -+ .ignore_oc = 1, ++ .spurious_oc = 1, .power_on = bcm63xx_ehci_power_on, .power_off = bcm63xx_ehci_power_off, .power_suspend = bcm63xx_ehci_power_off, diff --git a/target/linux/bcm63xx/patches-5.10/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch b/target/linux/bcm63xx/patches-5.10/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch index 0011c7a0e6..b35242efae 100644 --- a/target/linux/bcm63xx/patches-5.10/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch +++ b/target/linux/bcm63xx/patches-5.10/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch @@ -116,7 +116,7 @@ Signed-off-by: Jonas Gorski } --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c -@@ -1886,7 +1886,8 @@ int gpiochip_add_pingroup_range(struct g +@@ -1897,7 +1897,8 @@ int gpiochip_add_pingroup_range(struct g list_add_tail(&pin_range->node, &gdev->pin_ranges); @@ -126,7 +126,7 @@ Signed-off-by: Jonas Gorski } EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range); -@@ -1943,7 +1944,7 @@ int gpiochip_add_pin_range(struct gpio_c +@@ -1954,7 +1955,7 @@ int gpiochip_add_pin_range(struct gpio_c list_add_tail(&pin_range->node, &gdev->pin_ranges); diff --git a/target/linux/bcm63xx/patches-5.4/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch b/target/linux/bcm63xx/patches-5.4/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch index 6d91129932..5822166485 100644 --- a/target/linux/bcm63xx/patches-5.4/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch +++ b/target/linux/bcm63xx/patches-5.4/110-MIPS-BCM63XX-EHCI-controller-does-not-support-overcu.patch @@ -4,7 +4,7 @@ Date: Mon, 28 Jan 2013 20:06:30 +0100 Subject: [PATCH 12/12] MIPS: BCM63XX: EHCI controller does not support overcurrent -This patch sets the ignore_oc flag for the BCM63XX EHCI controller as it +This patch sets the spurious_oc flag for the BCM63XX EHCI controller as it does not support proper overcurrent reporting. Signed-off-by: Florian Fainelli @@ -18,7 +18,7 @@ Signed-off-by: Florian Fainelli static struct usb_ehci_pdata bcm63xx_ehci_pdata = { .big_endian_desc = 1, .big_endian_mmio = 1, -+ .ignore_oc = 1, ++ .spurious_oc = 1, .power_on = bcm63xx_ehci_power_on, .power_off = bcm63xx_ehci_power_off, .power_suspend = bcm63xx_ehci_power_off, diff --git a/target/linux/bmips/config-5.10 b/target/linux/bmips/config-5.10 index e2fc405c57..253b528ffd 100644 --- a/target/linux/bmips/config-5.10 +++ b/target/linux/bmips/config-5.10 @@ -16,6 +16,17 @@ CONFIG_BCM63XX_POWER=y CONFIG_BCM7038_L1_IRQ=y CONFIG_BCM7038_WDT=y CONFIG_BCM7120_L2_IRQ=y +CONFIG_BCMA=y +CONFIG_BCMA_BLOCKIO=y +# CONFIG_BCMA_DEBUG is not set +# CONFIG_BCMA_DRIVER_GMAC_CMN is not set +# CONFIG_BCMA_DRIVER_MIPS is not set +CONFIG_BCMA_DRIVER_PCI=y +# CONFIG_BCMA_DRIVER_PCI_HOSTMODE is not set +CONFIG_BCMA_HOST_PCI=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BLK_MQ_PCI=y CONFIG_BLK_PM=y CONFIG_BMIPS_GENERIC=y CONFIG_BOARD_SCACHE=y @@ -139,6 +150,7 @@ CONFIG_MDIO_BUS=y CONFIG_MDIO_BUS_MUX=y CONFIG_MDIO_BUS_MUX_BCM6368=y CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y CONFIG_MEMFD_CREATE=y CONFIG_MFD_SYSCON=y CONFIG_MIGRATION=y @@ -194,6 +206,13 @@ CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y CONFIG_OF_NET=y CONFIG_PADATA=y +CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_BCM6318=y +CONFIG_PCIE_BCM6328=y +CONFIG_PCIE_PME=y +CONFIG_PCI_BCM6348=y +CONFIG_PCI_DOMAINS=y CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 @@ -244,6 +263,15 @@ CONFIG_SPI_BCM63XX_HSSPI=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y CONFIG_SRCU=y +CONFIG_SSB=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_BLOCKIO=y +# CONFIG_SSB_DRIVER_MIPS is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_SPROM=y CONFIG_SWAP_IO_SPACE=y CONFIG_SWPHY=y CONFIG_SYNC_R4K=y diff --git a/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts b/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts index a5ae435a3a..725c7e38cd 100644 --- a/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts +++ b/target/linux/bmips/dts/bcm6318-comtrend-ar-5315u.dts @@ -31,6 +31,28 @@ debounce-interval = <60>; }; }; + + bcm43217-sprom { + compatible = "brcm,bcm43217-sprom"; + + pci-bus = <1>; + pci-dev = <0>; + + mtd-mac-address = <&cfe 0x6a0>; + mtd-mac-address-increment = <1>; + + brcm,sprom-fixups = <6 0x1c00>, + <65 0x1255>, + <97 0xfe55>, + <98 0x171d>, + <99 0xfa42>, + <113 0xfeb7>, + <114 0x18cd>, + <115 0xfa4f>, + <162 0x6444>, + <170 0x6444>, + <172 0x6444>; + }; }; &ehci { @@ -164,6 +186,10 @@ status = "okay"; }; +&pcie { + status = "okay"; +}; + &pinctrl { pinctrl_leds: leds { function = "led"; diff --git a/target/linux/bmips/dts/bcm6318.dtsi b/target/linux/bmips/dts/bcm6318.dtsi index e7dc38e937..6064c9ac4c 100644 --- a/target/linux/bmips/dts/bcm6318.dtsi +++ b/target/linux/bmips/dts/bcm6318.dtsi @@ -304,7 +304,7 @@ compatible = "brcm,bcm6318-ehci", "generic-ehci"; reg = <0x10005000 0x100>; big-endian; - ignore-oc; + spurious-oc; interrupt-parent = <&periph_intc>; interrupts = ; @@ -347,6 +347,41 @@ status = "disabled"; }; + pcie: pcie@10010000 { + compatible = "brcm,bcm6318-pcie"; + reg = <0x10010000 0x10000>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + bus-range = <0x00 0x01>; + ranges = <0x2000000 0 0x10200000 0x10200000 0 0x100000>; + linux,pci-probe-only = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = ; + + clocks = <&periph_clk BCM6318_CLK_PCIE>, + <&periph_clk BCM6318_CLK_PCIE25>, + <&ubus_clk BCM6318_UCLK_PCIE>; + clock-names = "pcie", + "pcie25", + "pcie-ubus"; + + resets = <&periph_rst BCM6318_RST_PCIE>, + <&periph_rst BCM6318_RST_PCIE_EXT>, + <&periph_rst BCM6318_RST_PCIE_CORE>, + <&periph_rst BCM6318_RST_PCIE_HARD>; + reset-names = "pcie", + "pcie-ext", + "pcie-core", + "pcie-hard"; + + power-domains = <&periph_pwr BCM6318_POWER_DOMAIN_PCIE>; + + status = "disabled"; + }; + switch0: switch@10080000 { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/bmips/dts/bcm63268.dtsi b/target/linux/bmips/dts/bcm63268.dtsi index 284d2c8ef0..d71cef4ccd 100644 --- a/target/linux/bmips/dts/bcm63268.dtsi +++ b/target/linux/bmips/dts/bcm63268.dtsi @@ -371,6 +371,12 @@ status = "disabled"; }; + serdes_cntl: syscon@10001804 { + compatible = "syscon"; + reg = <0x10001804 0x4>; + native-endian; + }; + periph_pwr: power-controller@1000184c { compatible = "brcm,bcm63268-power-controller"; reg = <0x1000184c 0x4>; @@ -390,7 +396,7 @@ compatible = "brcm,bcm63268-ehci", "generic-ehci"; reg = <0x10002500 0x100>; big-endian; - ignore-oc; + spurious-oc; interrupt-parent = <&periph_intc>; interrupts = ; @@ -468,6 +474,39 @@ status = "disabled"; }; + pcie: pcie@106e0000 { + compatible = "brcm,bcm6328-pcie"; + reg = <0x106e0000 0x10000>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + bus-range = <0x00 0x01>; + ranges = <0x2000000 0 0x11000000 0x11000000 0 0xf00000>; + linux,pci-probe-only = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = ; + + clocks = <&periph_clk BCM63268_CLK_PCIE>; + clock-names = "pcie"; + + resets = <&periph_rst BCM63268_RST_PCIE>, + <&periph_rst BCM63268_RST_PCIE_EXT>, + <&periph_rst BCM63268_RST_PCIE_CORE>, + <&periph_rst BCM63268_RST_PCIE_HARD>; + reset-names = "pcie", + "pcie-ext", + "pcie-core", + "pcie-hard"; + + power-domains = <&periph_pwr BCM63268_POWER_DOMAIN_PCIE>; + + brcm,serdes = <&serdes_cntl>; + + status = "disabled"; + }; + switch0: switch@10700000 { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts b/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts index 9ebd6c5c4d..14608fedb1 100644 --- a/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts +++ b/target/linux/bmips/dts/bcm6328-comtrend-ar-5387un.dts @@ -24,6 +24,41 @@ debounce-interval = <60>; }; }; + + bcm43225-sprom { + compatible = "brcm,bcm43225-sprom"; + + pci-bus = <1>; + pci-dev = <0>; + + mtd-mac-address = <&cfe 0x6a0>; + mtd-mac-address-increment = <1>; + + brcm,sprom-fixups = <2 0x05bb>, + <65 0x1204>, + <78 0x0303>, + <79 0x0202>, + <80 0xff02>, + <87 0x0315>, + <88 0x0315>, + <96 0x2048>, + <97 0xff11>, + <98 0x1567>, + <99 0xfb24>, + <100 0x3e3c>, + <101 0x4038>, + <102 0xfe7f>, + <103 0x1279>, + <112 0x2048>, + <113 0xff03>, + <114 0x154c>, + <115 0xfb27>, + <116 0x3e3c>, + <117 0x4038>, + <118 0xfe87>, + <119 0x1233>, + <203 0x2226>; + }; }; &ehci { @@ -111,6 +146,10 @@ status = "okay"; }; +&pcie { + status = "okay"; +}; + &pinctrl { pinctrl_leds: leds { function = "led"; diff --git a/target/linux/bmips/dts/bcm6328.dtsi b/target/linux/bmips/dts/bcm6328.dtsi index 64fd04142c..6ca7e4d9a6 100644 --- a/target/linux/bmips/dts/bcm6328.dtsi +++ b/target/linux/bmips/dts/bcm6328.dtsi @@ -317,6 +317,12 @@ status = "disabled"; }; + serdes_cntl: syscon@10001800 { + compatible = "syscon"; + reg = <0x10001800 0x4>; + native-endian; + }; + periph_pwr: power-controller@10001848 { compatible = "brcm,bcm6328-power-controller"; reg = <0x10001848 0x4>; @@ -328,7 +334,7 @@ compatible = "brcm,bcm6328-ehci", "generic-ehci"; reg = <0x10002500 0x100>; big-endian; - ignore-oc; + spurious-oc; interrupt-parent = <&periph_intc>; interrupts = ; @@ -462,5 +468,38 @@ reg = <1>; }; }; + + pcie: pcie@10e40000 { + compatible = "brcm,bcm6328-pcie"; + reg = <0x10e40000 0x10000>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + bus-range = <0x00 0x01>; + ranges = <0x2000000 0 0x10f00000 0x10f00000 0 0x100000>; + linux,pci-probe-only = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = ; + + clocks = <&periph_clk BCM6328_CLK_PCIE>; + clock-names = "pcie"; + + resets = <&periph_rst BCM6328_RST_PCIE>, + <&periph_rst BCM6328_RST_PCIE_EXT>, + <&periph_rst BCM6328_RST_PCIE_CORE>, + <&periph_rst BCM6328_RST_PCIE_HARD>; + reset-names = "pcie", + "pcie-ext", + "pcie-core", + "pcie-hard"; + + power-domains = <&periph_pwr BCM6328_POWER_DOMAIN_PCIE>; + + brcm,serdes = <&serdes_cntl>; + + status = "disabled"; + }; }; }; diff --git a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts index ba776caf78..65b4480ee1 100644 --- a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts +++ b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts @@ -119,6 +119,21 @@ gpios = <&pinctrl 28 GPIO_ACTIVE_LOW>; }; }; + + ath9k-fixup { + compatible = "brcm,ath9k-fixup"; + reg = <0x30000000 0x8000000>; + + pci-dev = <1>; + + mtd-mac-address = <&cfe 0x6a0>; + mtd-mac-address-increment = <1>; + + ath,eeprom = <&cal_data 0x1e000>; + ath,endian-check; + ath,led-pin = <2>; + ath,led-active-high; + }; }; &ehci { @@ -129,6 +144,10 @@ status = "okay"; }; +&pci { + status = "okay"; +}; + &pflash { status = "okay"; diff --git a/target/linux/bmips/dts/bcm6358.dtsi b/target/linux/bmips/dts/bcm6358.dtsi index c06001c62d..3ebbf74613 100644 --- a/target/linux/bmips/dts/bcm6358.dtsi +++ b/target/linux/bmips/dts/bcm6358.dtsi @@ -280,11 +280,36 @@ status = "disabled"; }; + pci: pci@fffe1000 { + compatible = "brcm,bcm6348-pci"; + reg = <0xfffe1000 0x200>, + <0x08000000 0x10000>; + reg-names = "pci", + "pci-io"; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + bus-range = <0x00 0x01>; + ranges = <0x2000000 0 0x30000000 0x30000000 0 0x8000000>; + linux,pci-probe-only = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = ; + + resets = <&periph_rst BCM6358_RST_MPI>; + reset-names = "pci"; + + brcm,remap; + + status = "disabled"; + }; + ehci: usb@fffe1300 { compatible = "brcm,bcm6358-ehci", "generic-ehci"; reg = <0xfffe1300 0x100>; big-endian; - ignore-oc; + spurious-oc; interrupt-parent = <&periph_intc>; interrupts = ; diff --git a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts index 0d88169184..3ad37fed71 100644 --- a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts +++ b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts @@ -209,6 +209,10 @@ status = "okay"; }; +&pcie { + status = "okay"; +}; + &pinctrl { pinctrl_leds: leds { function = "led"; diff --git a/target/linux/bmips/dts/bcm6362.dtsi b/target/linux/bmips/dts/bcm6362.dtsi index 9a3d9c1f66..04df06c0db 100644 --- a/target/linux/bmips/dts/bcm6362.dtsi +++ b/target/linux/bmips/dts/bcm6362.dtsi @@ -406,6 +406,12 @@ status = "disabled"; }; + serdes_cntl: syscon@10001804 { + compatible = "syscon"; + reg = <0x10001804 0x4>; + native-endian; + }; + periph_pwr: power-controller@10001848 { compatible = "brcm,bcm6362-power-controller"; reg = <0x10001848 0x4>; @@ -425,7 +431,7 @@ compatible = "brcm,bcm6362-ehci", "generic-ehci"; reg = <0x10002500 0x100>; big-endian; - ignore-oc; + spurious-oc; interrupt-parent = <&periph_intc>; interrupts = ; @@ -559,5 +565,36 @@ reg = <1>; }; }; + + pcie: pcie@10e40000 { + compatible = "brcm,bcm6328-pcie"; + reg = <0x10e40000 0x10000>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + bus-range = <0x00 0x01>; + ranges = <0x2000000 0 0x10f00000 0x10f00000 0 0x100000>; + linux,pci-probe-only = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = ; + + clocks = <&periph_clk BCM6362_CLK_PCIE>; + clock-names = "pcie"; + + resets = <&periph_rst BCM6362_RST_PCIE>, + <&periph_rst BCM6362_RST_PCIE_EXT>, + <&periph_rst BCM6362_RST_PCIE_CORE>; + reset-names = "pcie", + "pcie-ext", + "pcie-core"; + + power-domains = <&periph_pwr BCM6362_POWER_DOMAIN_PCIE>; + + brcm,serdes = <&serdes_cntl>; + + status = "disabled"; + }; }; }; diff --git a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts index b597a05f3a..6466cb3aca 100644 --- a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts +++ b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts @@ -53,6 +53,23 @@ gpios = <&pinctrl 31 GPIO_ACTIVE_HIGH>; }; }; + + bcm43222-sprom { + compatible = "brcm,bcm43222-sprom"; + + pci-bus = <0>; + pci-dev = <1>; + + mtd-mac-address = <&cfe 0x6a0>; + mtd-mac-address-increment = <1>; + + brcm,sprom-fixups = <97 0xfeb3>, + <98 0x1618>, + <99 0xfab0>, + <113 0xfed1>, + <114 0x1609>, + <115 0xfad9>; + }; }; &ehci { @@ -69,6 +86,10 @@ status = "okay"; }; +&pci { + status = "okay"; +}; + &pflash { status = "okay"; @@ -98,7 +119,7 @@ &pinctrl { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pci &pinctrl_ephy0_led &pinctrl_ephy1_led + pinctrl-0 = <&pinctrl_ephy0_led &pinctrl_ephy1_led &pinctrl_ephy2_led &pinctrl_ephy3_led>; }; diff --git a/target/linux/bmips/dts/bcm6368.dtsi b/target/linux/bmips/dts/bcm6368.dtsi index 5b5064b29e..afdf3c5dc0 100644 --- a/target/linux/bmips/dts/bcm6368.dtsi +++ b/target/linux/bmips/dts/bcm6368.dtsi @@ -414,11 +414,39 @@ status = "disabled"; }; + pci: pci@10001000 { + compatible = "brcm,bcm6348-pci"; + reg = <0x10001000 0x200>, + <0x08000000 0x10000>; + reg-names = "pci", + "pci-io"; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + bus-range = <0x00 0x01>; + ranges = <0x2000000 0 0x30000000 0x30000000 0 0x8000000>; + linux,pci-probe-only = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = ; + + resets = <&periph_rst BCM6368_RST_MPI>; + reset-names = "pci"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pci>; + + brcm,remap; + + status = "disabled"; + }; + ehci: usb@10001500 { compatible = "brcm,bcm6368-ehci", "generic-ehci"; reg = <0x10001500 0x100>; big-endian; - ignore-oc; + spurious-oc; interrupt-parent = <&periph_intc>; interrupts = ; diff --git a/target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c b/target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c new file mode 100644 index 0000000000..dd13ac6256 --- /dev/null +++ b/target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * ATH9K Fixup Driver + * + * Copyright (C) 2020 Álvaro Fernández Rojas + * Copyright (C) 2014 Jonas Gorski + * Copyright (C) 2008 Maxime Bizon + * Copyright (C) 2008 Florian Fainelli + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ATH9K_MAX_FIXUPS 2 + +#define ATH9K_DEF_LED_PIN -1 +#define ATH9K_DEF_PCI_DEV 255 + +struct ath9k_fixup { + struct device *dev; + struct resource *mem_res; + u32 pci_dev; + u8 mac[ETH_ALEN]; + struct ath9k_platform_data pdata; +}; + +static int ath9k_num_fixups; +static struct ath9k_fixup *ath9k_fixups[ATH9K_MAX_FIXUPS]; + +static void ath9k_pci_fixup(struct pci_dev *dev) +{ + void __iomem *mem; + struct ath9k_fixup *priv = NULL; + struct ath9k_platform_data *pdata = NULL; + struct pci_dev *bridge = pci_upstream_bridge(dev); + u16 *cal_data = NULL; + u16 cmd; + u32 bar0; + u32 val; + unsigned i; + + for (i = 0; i < ath9k_num_fixups; i++) { + if (ath9k_fixups[i]->pci_dev != PCI_SLOT(dev->devfn)) + continue; + + priv = ath9k_fixups[i]; + cal_data = priv->pdata.eeprom_data; + pdata = &priv->pdata; + break; + } + + if (cal_data == NULL) + return; + + if (*cal_data != 0xa55a) { + pr_err("pci %s: invalid calibration data\n", pci_name(dev)); + return; + } + + pr_info("pci %s: fixup device configuration\n", pci_name(dev)); + + val = priv->mem_res->start; + mem = ioremap(priv->mem_res->start, resource_size(priv->mem_res)); + if (!mem) { + pr_err("pci %s: ioremap error\n", pci_name(dev)); + return; + } + + if (bridge) + pci_enable_device(bridge); + + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, val); + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config_word(dev, PCI_COMMAND, cmd); + + /* set offset to first reg address */ + cal_data += 3; + while(*cal_data != 0xffff) { + u32 reg; + + reg = *cal_data++; + val = *cal_data++; + val |= (*cal_data++) << 16; + + writel(val, mem + reg); + udelay(100); + } + + pci_read_config_dword(dev, PCI_VENDOR_ID, &val); + dev->vendor = val & 0xffff; + dev->device = (val >> 16) & 0xffff; + + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); + dev->revision = val & 0xff; + dev->class = val >> 8; /* upper 3 bytes */ + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + pci_write_config_word(dev, PCI_COMMAND, cmd); + + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); + + if (bridge) + pci_disable_device(bridge); + + iounmap(mem); + + dev->dev.platform_data = pdata; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); + +static int ath9k_mtd_eeprom(struct ath9k_fixup *priv) +{ + struct device *dev = priv->dev; + struct device_node *node = dev->of_node; + struct device_node *mtd_np = NULL; + struct mtd_info *the_mtd; + phandle phandle; + size_t eeprom_readlen; + const char *part; + const __be32 *list; + int ret, i; + + list = of_get_property(node, "ath,eeprom", &i); + if (!list || (i != (2 * sizeof(*list)))) + return -ENODEV; + + phandle = be32_to_cpup(list++); + if (phandle) + mtd_np = of_find_node_by_phandle(phandle); + if (!mtd_np) + return -ENODEV; + + part = of_get_property(mtd_np, "label", NULL); + if (!part) + part = mtd_np->name; + + the_mtd = get_mtd_device_nm(part); + if (IS_ERR(the_mtd)) + return -ENODEV; + + ret = mtd_read(the_mtd, be32_to_cpup(list), + ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16), + &eeprom_readlen, (void *) priv->pdata.eeprom_data); + put_mtd_device(the_mtd); + if (ret) + return ret; + + return 0; +} + +static int ath9k_fixup_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct ath9k_fixup *priv; + struct resource *res; + const void *mac; + int ret; + + if (ath9k_num_fixups >= ATH9K_MAX_FIXUPS) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->mem_res = res; + + ret = of_property_read_u32(node, "pci-dev", &priv->pci_dev); + if (ret) + priv->pci_dev = ATH9K_DEF_PCI_DEV; + + ret = ath9k_mtd_eeprom(priv); + if (ret) + return ret; + + priv->pdata.endian_check = of_property_read_bool(node, + "ath,endian-check"); + ret = of_property_read_s32(node, "ath,led-pin", &priv->pdata.led_pin); + if (ret) + priv->pdata.led_pin = ATH9K_DEF_LED_PIN; + priv->pdata.led_active_high = of_property_read_bool(node, + "ath,led-active-high"); + + mac = of_get_mac_address(node); + if (!IS_ERR_OR_NULL(mac)) { + memcpy(priv->mac, mac, ETH_ALEN); + dev_info(dev, "mtd mac %pM\n", priv->mac); + } else { + random_ether_addr(priv->mac); + dev_info(dev, "random mac %pM\n", priv->mac); + } + + priv->pdata.macaddr = priv->mac; + + ath9k_fixups[ath9k_num_fixups] = priv; + ath9k_num_fixups++; + + return 0; +} + +static const struct of_device_id ath9k_fixup_of_match[] = { + { .compatible = "brcm,ath9k-fixup" }, + { /* sentinel */ } +}; + +static struct platform_driver ath9k_fixup_driver = { + .probe = ath9k_fixup_probe, + .driver = { + .name = "ath9k-fixup", + .of_match_table = ath9k_fixup_of_match, + }, +}; + +int __init ath9k_fixup_init(void) +{ + int ret = platform_driver_register(&ath9k_fixup_driver); + if (ret) + pr_err("ath9k_fixup: Error registering platform driver!\n"); + return ret; +} +late_initcall(ath9k_fixup_init); diff --git a/target/linux/bmips/files/arch/mips/bmips/b43-sprom.c b/target/linux/bmips/files/arch/mips/bmips/b43-sprom.c new file mode 100644 index 0000000000..2348bd1fe2 --- /dev/null +++ b/target/linux/bmips/files/arch/mips/bmips/b43-sprom.c @@ -0,0 +1,1195 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * B43 Fallback SPROM Driver + * + * Copyright (C) 2020 Álvaro Fernández Rojas + * Copyright (C) 2014 Jonas Gorski + * Copyright (C) 2008 Maxime Bizon + * Copyright (C) 2008 Florian Fainelli + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum b43_sprom_type { + B43_SPROM_SSB, + B43_SPROM_BCMA, + B43_SPROM_NUM +}; + +struct b43_sprom_raw { + u16 *map; + size_t size; + u8 type; +}; + +struct b43_sprom { + struct device *dev; + struct ssb_sprom sprom; + u32 pci_bus; + u32 pci_dev; + u8 mac[ETH_ALEN]; + int devid_override; +}; + +static struct b43_sprom b43_sprom; + +#if defined (CONFIG_SSB_PCIHOST) +static u16 bcm4306_sprom_map[] = { + 0x4001, 0x0000, 0x0453, 0x14e4, 0x4320, 0x8000, 0x0002, 0x0002, + 0x1000, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3034, 0x14d4, + 0xfa91, 0xfe60, 0xffff, 0xffff, 0x004c, 0xffff, 0xffff, 0xffff, + 0x003e, 0x0a49, 0xff02, 0x0000, 0xff10, 0xffff, 0xffff, 0x0002, +}; + +struct b43_sprom_raw bcm4306_sprom = { + .map = bcm4306_sprom_map, + .size = ARRAY_SIZE(bcm4306_sprom_map), + .type = B43_SPROM_SSB, +}; + +static u16 bcm4318_sprom_map[] = { + 0x2001, 0x0000, 0x0449, 0x14e4, 0x4318, 0x8000, 0x0002, 0x0000, + 0x1000, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3046, 0x15a7, + 0xfab0, 0xfe97, 0xffff, 0xffff, 0x0048, 0xffff, 0xffff, 0xffff, + 0x003e, 0xea49, 0xff02, 0x0000, 0xff08, 0xffff, 0xffff, 0x0002, +}; + +struct b43_sprom_raw bcm4318_sprom = { + .map = bcm4318_sprom_map, + .size = ARRAY_SIZE(bcm4318_sprom_map), + .type = B43_SPROM_SSB, +}; + +static u16 bcm4321_sprom_map[] = { + 0x3001, 0x0000, 0x046c, 0x14e4, 0x4328, 0x8000, 0x0002, 0x0000, + 0x1000, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x5372, 0x0032, 0x4a01, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0303, 0x0202, + 0xffff, 0x2728, 0x5b5b, 0x222b, 0x5b5b, 0x1927, 0x5b5b, 0x1e36, + 0x5b5b, 0x303c, 0x3030, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3e4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x7838, 0x3a34, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x3e4c, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7838, 0x3a34, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x0008, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x0004, +}; + +struct b43_sprom_raw bcm4321_sprom = { + .map = bcm4321_sprom_map, + .size = ARRAY_SIZE(bcm4321_sprom_map), + .type = B43_SPROM_SSB, +}; + +static u16 bcm4322_sprom_map[] = { + 0x3001, 0x0000, 0x04bc, 0x14e4, 0x432c, 0x8000, 0x0002, 0x0000, + 0x1730, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x5372, 0x1209, 0x0200, 0x0000, 0x0400, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0303, 0x0202, + 0xffff, 0x0033, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0301, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x2048, 0xfe9a, 0x1571, 0xfabd, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x2048, 0xfeb9, 0x159f, 0xfadd, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3333, 0x5555, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x0008, +}; + +struct b43_sprom_raw bcm4322_sprom = { + .map = bcm4322_sprom_map, + .size = ARRAY_SIZE(bcm4322_sprom_map), + .type = B43_SPROM_SSB, +}; + +static u16 bcm43222_sprom_map[] = { + 0x2001, 0x0000, 0x04d4, 0x14e4, 0x4351, 0x8000, 0x0002, 0x0000, + 0x1730, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x5372, 0x2305, 0x0200, 0x0000, 0x2400, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0303, 0x0202, + 0xffff, 0x0033, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0325, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x204c, 0xfea6, 0x1717, 0xfa6d, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x204c, 0xfeb8, 0x167c, 0xfa9e, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x3333, 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, + 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x0008, +}; + +struct b43_sprom_raw bcm43222_sprom = { + .map = bcm43222_sprom_map, + .size = ARRAY_SIZE(bcm43222_sprom_map), + .type = B43_SPROM_SSB, +}; +#endif /* CONFIG_SSB_PCIHOST */ + +#if defined(CONFIG_BCMA_HOST_PCI) +static u16 bcm4313_sprom_map[] = { + 0x2801, 0x0000, 0x0510, 0x14e4, 0x0078, 0xedbe, 0x0000, 0x2bc4, + 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820, + 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100, + 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4727, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5372, 0x1215, 0x2a00, 0x0800, 0x0800, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0003, 0x0202, + 0xffff, 0x0011, 0x007a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0201, + 0x0000, 0x7800, 0x7c0a, 0x0398, 0x0008, 0x0000, 0x0000, 0x0000, + 0x0044, 0x1684, 0xfd0d, 0xff35, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0048, 0xfed2, 0x15d9, 0xfac6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0008, +}; + +struct b43_sprom_raw bcm4313_sprom = { + .map = bcm4313_sprom_map, + .size = ARRAY_SIZE(bcm4313_sprom_map), + .type = B43_SPROM_BCMA, +}; + +static u16 bcm4331_sprom_map[] = { + 0x2801, 0x0000, 0x0525, 0x14e4, 0x0078, 0xedbe, 0x0000, 0x2bc4, + 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820, + 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100, + 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x1010, 0x0005, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4331, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x5372, 0x1104, 0x0200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xffff, 0x88ff, 0xffff, 0x0707, 0x0202, + 0xff02, 0x0077, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0325, + 0x0325, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x2048, 0xfe56, 0x16f2, 0xfa44, 0x3e3c, 0x3c3c, 0xfe77, 0x1657, + 0xfa75, 0xffff, 0xffff, 0xffff, 0xfe76, 0x15da, 0xfa85, 0x0000, + 0x2048, 0xfe5c, 0x16b5, 0xfa56, 0x3e3c, 0x3c3c, 0xfe7c, 0x169d, + 0xfa6b, 0xffff, 0xffff, 0xffff, 0xfe7a, 0x1597, 0xfa97, 0x0000, + 0x2048, 0xfe68, 0x1734, 0xfa46, 0x3e3c, 0x3c3c, 0xfe7f, 0x15e4, + 0xfa94, 0xffff, 0xffff, 0xffff, 0xfe7d, 0x1582, 0xfa9f, 0x0000, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x0009, +}; + +struct b43_sprom_raw bcm4331_sprom = { + .map = bcm4331_sprom_map, + .size = ARRAY_SIZE(bcm4331_sprom_map), + .type = B43_SPROM_BCMA, +}; + +static u16 bcm43131_sprom_map[] = { + 0x2801, 0x0000, 0x05f7, 0x14e4, 0x0070, 0xedbe, 0x1c00, 0x2bc4, + 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820, + 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100, + 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000, + 0x43aa, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5372, 0x1280, 0x0200, 0x0000, 0x8800, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0002, 0x0202, + 0xffff, 0x0022, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0415, + 0x0000, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x204c, 0xfe96, 0x192c, 0xfa15, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x204c, 0xfe91, 0x1950, 0xfa0a, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x4444, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x6666, 0x6666, 0x6666, + 0x6666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x0008, +}; + +struct b43_sprom_raw bcm43131_sprom = { + .map = bcm43131_sprom_map, + .size = ARRAY_SIZE(bcm43131_sprom_map), + .type = B43_SPROM_BCMA, +}; + +static u16 bcm43217_sprom_map[] = { + 0x2801, 0x0000, 0x05e9, 0x14e4, 0x0070, 0xedbe, 0x0000, 0x2bc4, + 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820, + 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100, + 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000, + 0x43a9, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5372, 0x1252, 0x0200, 0x0000, 0x9800, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0003, 0x0202, + 0xffff, 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0415, + 0x0000, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x204c, 0xfe96, 0x192c, 0xfa15, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x204c, 0xfe91, 0x1950, 0xfa0a, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x4444, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x6666, 0x6666, 0x6666, + 0x6666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x7a08, +}; + +struct b43_sprom_raw bcm43217_sprom = { + .map = bcm43217_sprom_map, + .size = ARRAY_SIZE(bcm43217_sprom_map), + .type = B43_SPROM_BCMA, +}; + +static u16 bcm43225_sprom_map[] = { + 0x2801, 0x0000, 0x04da, 0x14e4, 0x0078, 0xedbe, 0x0000, 0x2bc4, + 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820, + 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100, + 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x1008, 0x0005, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4357, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x5372, 0x1200, 0x0200, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x88ff, 0xffff, 0xffff, 0x0303, 0x0202, + 0xffff, 0x0033, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0325, + 0xffff, 0x7800, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x204e, 0xfead, 0x1611, 0xfa9a, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x204e, 0xfec1, 0x1674, 0xfab2, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x5555, 0x7555, 0x5555, 0x7555, 0x5555, 0x7555, 0x5555, + 0x7555, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x0008, +}; + +struct b43_sprom_raw bcm43225_sprom = { + .map = bcm43225_sprom_map, + .size = ARRAY_SIZE(bcm43225_sprom_map), + .type = B43_SPROM_BCMA, +}; + +static u16 bcm43227_sprom_map[] = { + 0x2801, 0x0000, 0x0543, 0x14e4, 0x0070, 0xedbe, 0x0000, 0x2bc4, + 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820, + 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100, + 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4358, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5372, 0x1402, 0x0200, 0x0000, 0x0800, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0003, 0x0202, + 0xffff, 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0415, + 0x0000, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x204c, 0xff36, 0x16d2, 0xfaae, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x204c, 0xfeca, 0x159b, 0xfa80, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x4444, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x6666, 0x6666, 0x6666, + 0x6666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x0008, +}; + +struct b43_sprom_raw bcm43227_sprom = { + .map = bcm43227_sprom_map, + .size = ARRAY_SIZE(bcm43227_sprom_map), + .type = B43_SPROM_BCMA, +}; + +static u16 bcm43228_sprom_map[] = { + 0x2801, 0x0000, 0x0011, 0x1028, 0x0070, 0xedbe, 0x0000, 0x2bc4, + 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820, + 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100, + 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000, + 0x4359, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x5372, 0x1203, 0x0200, 0x0000, 0x0800, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0303, 0x0202, + 0xffff, 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0215, + 0x0215, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x204c, 0xff73, 0x1762, 0xfaa4, 0x3e34, 0x3434, 0xfea1, 0x154c, + 0xfad0, 0xfea1, 0x144c, 0xfafb, 0xfe7b, 0x13fe, 0xfafc, 0x0000, + 0x204c, 0xff41, 0x16a3, 0xfa8f, 0x3e34, 0x3434, 0xfe97, 0x1446, + 0xfb05, 0xfe97, 0x1346, 0xfb32, 0xfeb9, 0x1516, 0xfaee, 0x0000, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0000, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x8888, 0x8888, 0x8888, + 0x8888, 0x0000, 0x0000, 0x0000, 0x0000, 0x3333, 0x3333, 0x3333, + 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x3333, 0x3333, 0x3333, + 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x3333, 0x3333, 0x3333, + 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xf008, +}; + +struct b43_sprom_raw bcm43228_sprom = { + .map = bcm43228_sprom_map, + .size = ARRAY_SIZE(bcm43228_sprom_map), + .type = B43_SPROM_BCMA, +}; +#endif /* CONFIG_BCMA_HOST_PCI */ + +/* Get the word-offset for a SSB_SPROM_XXX define. */ +#define SPOFF(offset) ((offset) / sizeof(u16)) +/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ +#define SPEX16(_outvar, _offset, _mask, _shift) \ + out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) +#define SPEX32(_outvar, _offset, _mask, _shift) \ + out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \ + in[SPOFF(_offset)]) & (_mask)) >> (_shift)) +#define SPEX(_outvar, _offset, _mask, _shift) \ + SPEX16(_outvar, _offset, _mask, _shift) + +#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \ + do { \ + SPEX(_field[0], _offset + 0, _mask, _shift); \ + SPEX(_field[1], _offset + 2, _mask, _shift); \ + SPEX(_field[2], _offset + 4, _mask, _shift); \ + SPEX(_field[3], _offset + 6, _mask, _shift); \ + SPEX(_field[4], _offset + 8, _mask, _shift); \ + SPEX(_field[5], _offset + 10, _mask, _shift); \ + SPEX(_field[6], _offset + 12, _mask, _shift); \ + SPEX(_field[7], _offset + 14, _mask, _shift); \ + } while (0) + + +static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset, + u16 mask, u16 shift) +{ + u16 v; + u8 gain; + + v = in[SPOFF(offset)]; + gain = (v & mask) >> shift; + if (gain == 0xFF) + gain = 2; /* If unset use 2dBm */ + if (sprom_revision == 1) { + /* Convert to Q5.2 */ + gain <<= 2; + } else { + /* Q5.2 Fractional part is stored in 0xC0 */ + gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2); + } + + return (s8)gain; +} + +static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in) +{ + SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); + SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0); + SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0); + SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0); + SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0); + SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0); + SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0); + SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0); + SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0); + SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO, + SSB_SPROM2_MAXP_A_LO_SHIFT); +} + +static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) +{ + u16 loc[3]; + + if (out->revision == 3) /* rev 3 moved MAC */ + loc[0] = SSB_SPROM3_IL0MAC; + else { + loc[0] = SSB_SPROM1_IL0MAC; + loc[1] = SSB_SPROM1_ET0MAC; + loc[2] = SSB_SPROM1_ET1MAC; + } + + SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); + SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, + SSB_SPROM1_ETHPHY_ET1A_SHIFT); + SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); + SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); + SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); + SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); + if (out->revision == 1) + SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, + SSB_SPROM1_BINF_CCODE_SHIFT); + SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, + SSB_SPROM1_BINF_ANTA_SHIFT); + SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, + SSB_SPROM1_BINF_ANTBG_SHIFT); + SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0); + SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0); + SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0); + SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0); + SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0); + SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0); + SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1, + SSB_SPROM1_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3, + SSB_SPROM1_GPIOB_P3_SHIFT); + SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, + SSB_SPROM1_MAXPWR_A_SHIFT); + SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0); + SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, + SSB_SPROM1_ITSSI_A_SHIFT); + SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); + SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); + + SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8); + SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); + + /* Extract the antenna gain values. */ + out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, + SSB_SPROM1_AGAIN, + SSB_SPROM1_AGAIN_BG, + SSB_SPROM1_AGAIN_BG_SHIFT); + out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, + SSB_SPROM1_AGAIN, + SSB_SPROM1_AGAIN_A, + SSB_SPROM1_AGAIN_A_SHIFT); + if (out->revision >= 2) + sprom_extract_r23(out, in); +} + +/* Revs 4 5 and 8 have partially shared layout */ +static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in) +{ + SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, + SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT); + SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, + SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT); + SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, + SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT); + SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, + SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT); + + SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, + SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT); + SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, + SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT); + SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, + SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT); + SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, + SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT); + + SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, + SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT); + SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, + SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT); + SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, + SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT); + SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, + SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT); + + SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, + SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT); + SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, + SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT); + SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, + SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT); + SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, + SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT); +} + +static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) +{ + static const u16 pwr_info_offset[] = { + SSB_SPROM4_PWR_INFO_CORE0, SSB_SPROM4_PWR_INFO_CORE1, + SSB_SPROM4_PWR_INFO_CORE2, SSB_SPROM4_PWR_INFO_CORE3 + }; + int i; + + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != + ARRAY_SIZE(out->core_pwr_info)); + + SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); + SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, + SSB_SPROM4_ETHPHY_ET1A_SHIFT); + SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0); + SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); + if (out->revision == 4) { + SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8); + SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0); + SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); + SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); + SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0); + SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0); + } else { + SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8); + SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0); + SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); + SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); + SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); + SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0); + } + SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, + SSB_SPROM4_ANTAVAIL_A_SHIFT); + SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, + SSB_SPROM4_ANTAVAIL_BG_SHIFT); + SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0); + SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG, + SSB_SPROM4_ITSSI_BG_SHIFT); + SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); + SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, + SSB_SPROM4_ITSSI_A_SHIFT); + if (out->revision == 4) { + SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, + SSB_SPROM4_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, + SSB_SPROM4_GPIOB_P3_SHIFT); + } else { + SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1, + SSB_SPROM5_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3, + SSB_SPROM5_GPIOB_P3_SHIFT); + } + + /* Extract the antenna gain values. */ + out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, + SSB_SPROM4_AGAIN01, + SSB_SPROM4_AGAIN0, + SSB_SPROM4_AGAIN0_SHIFT); + out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, + SSB_SPROM4_AGAIN01, + SSB_SPROM4_AGAIN1, + SSB_SPROM4_AGAIN1_SHIFT); + out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in, + SSB_SPROM4_AGAIN23, + SSB_SPROM4_AGAIN2, + SSB_SPROM4_AGAIN2_SHIFT); + out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in, + SSB_SPROM4_AGAIN23, + SSB_SPROM4_AGAIN3, + SSB_SPROM4_AGAIN3_SHIFT); + + /* Extract cores power info info */ + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { + u16 o = pwr_info_offset[i]; + + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SPROM4_2G_MAXP_ITSSI, + SSB_SPROM4_2G_ITSSI, SSB_SPROM4_2G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SPROM4_2G_MAXP_ITSSI, + SSB_SPROM4_2G_MAXP, 0); + + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SPROM4_2G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SPROM4_2G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SPROM4_2G_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[3], o + SSB_SPROM4_2G_PA_3, ~0, 0); + + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SPROM4_5G_MAXP_ITSSI, + SSB_SPROM4_5G_ITSSI, SSB_SPROM4_5G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SPROM4_5G_MAXP_ITSSI, + SSB_SPROM4_5G_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM4_5GHL_MAXP, + SSB_SPROM4_5GH_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM4_5GHL_MAXP, + SSB_SPROM4_5GL_MAXP, SSB_SPROM4_5GL_MAXP_SHIFT); + + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SPROM4_5GL_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SPROM4_5GL_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SPROM4_5GL_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[3], o + SSB_SPROM4_5GL_PA_3, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SPROM4_5G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SPROM4_5G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SPROM4_5G_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[3], o + SSB_SPROM4_5G_PA_3, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SPROM4_5GH_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SPROM4_5GH_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SPROM4_5GH_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[3], o + SSB_SPROM4_5GH_PA_3, ~0, 0); + } + + sprom_extract_r458(out, in); + + /* TODO - get remaining rev 4 stuff needed */ +} + +static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) +{ + int i; + u16 o; + static const u16 pwr_info_offset[] = { + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 + }; + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != + ARRAY_SIZE(out->core_pwr_info)); + + SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); + SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); + SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); + SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); + SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); + SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0); + SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0); + SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0); + SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A, + SSB_SPROM8_ANTAVAIL_A_SHIFT); + SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG, + SSB_SPROM8_ANTAVAIL_BG_SHIFT); + SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0); + SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG, + SSB_SPROM8_ITSSI_BG_SHIFT); + SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0); + SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A, + SSB_SPROM8_ITSSI_A_SHIFT); + SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0); + SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK, + SSB_SPROM8_MAXP_AL_SHIFT); + SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1, + SSB_SPROM8_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3, + SSB_SPROM8_GPIOB_P3_SHIFT); + SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0); + SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G, + SSB_SPROM8_TRI5G_SHIFT); + SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0); + SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH, + SSB_SPROM8_TRI5GH_SHIFT); + SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0); + SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G, + SSB_SPROM8_RXPO5G_SHIFT); + SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0); + SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G, + SSB_SPROM8_RSSISMC2G_SHIFT); + SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G, + SSB_SPROM8_RSSISAV2G_SHIFT); + SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G, + SSB_SPROM8_BXA2G_SHIFT); + SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0); + SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G, + SSB_SPROM8_RSSISMC5G_SHIFT); + SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G, + SSB_SPROM8_RSSISAV5G_SHIFT); + SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G, + SSB_SPROM8_BXA5G_SHIFT); + SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0); + SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0); + SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0); + SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0); + SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0); + SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0); + SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0); + SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0); + SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0); + SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0); + SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0); + SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0); + SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0); + SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0); + SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0); + SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0); + SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); + + /* Extract the antenna gain values. */ + out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, + SSB_SPROM8_AGAIN01, + SSB_SPROM8_AGAIN0, + SSB_SPROM8_AGAIN0_SHIFT); + out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, + SSB_SPROM8_AGAIN01, + SSB_SPROM8_AGAIN1, + SSB_SPROM8_AGAIN1_SHIFT); + out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in, + SSB_SPROM8_AGAIN23, + SSB_SPROM8_AGAIN2, + SSB_SPROM8_AGAIN2_SHIFT); + out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in, + SSB_SPROM8_AGAIN23, + SSB_SPROM8_AGAIN3, + SSB_SPROM8_AGAIN3_SHIFT); + + /* Extract cores power info info */ + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { + o = pwr_info_offset[i]; + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_MAXP, 0); + + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); + + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GH_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); + + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); + } + + /* Extract FEM info */ + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, + SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); + SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, + SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); + SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, + SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); + SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, + SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); + SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, + SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); + + SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, + SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); + SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, + SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); + SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, + SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); + SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, + SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); + SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, + SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); + + SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON, + SSB_SPROM8_LEDDC_ON_SHIFT); + SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF, + SSB_SPROM8_LEDDC_OFF_SHIFT); + + SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN, + SSB_SPROM8_TXRXC_TXCHAIN_SHIFT); + SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN, + SSB_SPROM8_TXRXC_RXCHAIN_SHIFT); + SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH, + SSB_SPROM8_TXRXC_SWITCH_SHIFT); + + SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0); + + SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0); + SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0); + SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0); + SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0); + + SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP, + SSB_SPROM8_RAWTS_RAWTEMP_SHIFT); + SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER, + SSB_SPROM8_RAWTS_MEASPOWER_SHIFT); + SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX, + SSB_SPROM8_OPT_CORRX_TEMP_SLOPE, + SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT); + SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX, + SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT); + SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX, + SSB_SPROM8_OPT_CORRX_TEMP_OPTION, + SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT); + SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP, + SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR, + SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT); + SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP, + SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP, + SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT); + SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL, + SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT); + + SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0); + SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0); + SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0); + SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0); + + SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH, + SSB_SPROM8_THERMAL_TRESH_SHIFT); + SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET, + SSB_SPROM8_THERMAL_OFFSET_SHIFT); + SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA, + SSB_SPROM8_TEMPDELTA_PHYCAL, + SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT); + SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD, + SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT); + SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA, + SSB_SPROM8_TEMPDELTA_HYSTERESIS, + SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT); + sprom_extract_r458(out, in); + + /* TODO - get remaining rev 8 stuff needed */ +} + +static int sprom_extract(struct ssb_sprom *out, const u16 *in, u16 size) +{ + memset(out, 0, sizeof(*out)); + + out->revision = in[size - 1] & 0x00FF; + memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ + memset(out->et1mac, 0xFF, 6); + + switch (out->revision) { + case 1: + case 2: + case 3: + sprom_extract_r123(out, in); + break; + case 4: + case 5: + sprom_extract_r45(out, in); + break; + case 8: + sprom_extract_r8(out, in); + break; + default: + pr_warn("Unsupported SPROM revision %d detected. Will extract v1\n", + out->revision); + out->revision = 1; + sprom_extract_r123(out, in); + } + + if (out->boardflags_lo == 0xFFFF) + out->boardflags_lo = 0; /* per specs */ + if (out->boardflags_hi == 0xFFFF) + out->boardflags_hi = 0; /* per specs */ + + return 0; +} + +static void b43_sprom_fixup(struct b43_sprom *priv, u16 *sprom) +{ + struct device_node *node = priv->dev->of_node; + u32 fixups, off, val; + int i = 0; + + if (!of_get_property(node, "brcm,sprom-fixups", &fixups)) + return; + + fixups /= sizeof(u32); + + dev_info(priv->dev, "patching SPROM with %u fixups...\n", fixups >> 1); + + while (i < fixups) { + if (of_property_read_u32_index(node, "brcm,sprom-fixups", + i++, &off)) { + dev_err(priv->dev, "error reading fixup[%u] offset\n", + i - 1); + return; + } + + if (of_property_read_u32_index(node, "brcm,sprom-fixups", + i++, &val)) { + dev_err(priv->dev, "error reading fixup[%u] value\n", + i - 1); + return; + } + + dev_dbg(priv->dev, "fixup[%d]=0x%04x\n", off, val); + + sprom[off] = val; + } +} + +int sprom_override_devid(struct b43_sprom *priv, struct ssb_sprom *out, + const u16 *in) +{ + const struct b43_sprom_raw *raw = of_device_get_match_data(priv->dev); + + if (raw->type == B43_SPROM_SSB) { + SPEX(dev_id, SSB_SPROM1_PID, 0xFFFF, 0); + return !!out->dev_id; + } else if (raw->type == B43_SPROM_BCMA) { + SPEX(dev_id, 0x0060, 0xFFFF, 0); + return !!out->dev_id; + } + + return 0; +} + +static void b43_sprom_set(struct b43_sprom *priv) +{ + const struct b43_sprom_raw *raw = of_device_get_match_data(priv->dev); + struct ssb_sprom *sprom = &priv->sprom; + + if (raw) { + u16 template_sprom[220]; + + memcpy(template_sprom, raw->map, raw->size * sizeof(u16)); + b43_sprom_fixup(priv, template_sprom); + sprom_extract(sprom, template_sprom, raw->size); + + priv->devid_override = sprom_override_devid(priv, sprom, + template_sprom); + } else { + sprom->revision = 0x02; + sprom->board_rev = 0x0017; + sprom->country_code = 0x00; + sprom->ant_available_bg = 0x03; + sprom->pa0b0 = 0x15ae; + sprom->pa0b1 = 0xfa85; + sprom->pa0b2 = 0xfe8d; + sprom->pa1b0 = 0xffff; + sprom->pa1b1 = 0xffff; + sprom->pa1b2 = 0xffff; + sprom->gpio0 = 0xff; + sprom->gpio1 = 0xff; + sprom->gpio2 = 0xff; + sprom->gpio3 = 0xff; + sprom->maxpwr_bg = 0x4c; + sprom->itssi_bg = 0x00; + sprom->boardflags_lo = 0x2848; + sprom->boardflags_hi = 0x0000; + priv->devid_override = 0; + } +} + +#if defined(CONFIG_SSB_PCIHOST) +int b43_get_fallback_ssb_sprom(struct ssb_bus *bus, struct ssb_sprom *out) +{ + struct b43_sprom *priv = &b43_sprom; + + if (bus->bustype == SSB_BUSTYPE_PCI) { + if (bus->host_pci->bus->number != priv->pci_bus || + PCI_SLOT(bus->host_pci->devfn) != priv->pci_dev) + pr_warn("ssb_fallback_sprom: pci bus/device num " + "mismatch: expected %i/%i, but got %i/%i\n", + priv->pci_bus, priv->pci_dev, + bus->host_pci->bus->number, + PCI_SLOT(bus->host_pci->devfn)); + if (priv->devid_override) + bus->host_pci->device = priv->sprom.dev_id; + memcpy(out, &priv->sprom, sizeof(struct ssb_sprom)); + return 0; + } else { + pr_err("%s: unable to fill SPROM for given bustype.\n", + __func__); + return -EINVAL; + } +} +#endif /* CONFIG_SSB_PCIHOST */ + +#if defined(CONFIG_BCMA_HOST_PCI) +int b43_get_fallback_bcma_sprom(struct bcma_bus *bus, struct ssb_sprom *out) +{ + struct b43_sprom *priv = &b43_sprom; + + if (bus->hosttype == BCMA_HOSTTYPE_PCI) { + if (bus->host_pci->bus->number != priv->pci_bus || + PCI_SLOT(bus->host_pci->devfn) != priv->pci_dev) + pr_warn("bcma_fallback_sprom: pci bus/device num " + "mismatch: expected %i/%i, but got %i/%i\n", + priv->pci_bus, priv->pci_dev, + bus->host_pci->bus->number, + PCI_SLOT(bus->host_pci->devfn)); + if (priv->devid_override) + bus->host_pci->device = priv->sprom.dev_id; + memcpy(out, &priv->sprom, sizeof(struct ssb_sprom)); + return 0; + } else { + pr_err("%s: unable to fill SPROM for given bustype.\n", + __func__); + return -EINVAL; + } +} +#endif /* CONFIG_BCMA_HOST_PCI */ + +static int b43_sprom_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct b43_sprom *priv = &b43_sprom; + const void *mac; + int ret; + + priv->dev = dev; + + b43_sprom_set(priv); + + of_property_read_u32(node, "pci-bus", &priv->pci_bus); + of_property_read_u32(node, "pci-dev", &priv->pci_dev); + + mac = of_get_mac_address(node); + if (!IS_ERR_OR_NULL(mac)) { + memcpy(priv->mac, mac, ETH_ALEN); + dev_info(dev, "mtd mac %pM\n", priv->mac); + } else { + random_ether_addr(priv->mac); + dev_info(dev, "random mac %pM\n", priv->mac); + } + + memcpy(priv->sprom.il0mac, priv->mac, ETH_ALEN); + memcpy(priv->sprom.et0mac, priv->mac, ETH_ALEN); + memcpy(priv->sprom.et1mac, priv->mac, ETH_ALEN); + +#if defined(CONFIG_SSB_PCIHOST) + ret = ssb_arch_register_fallback_sprom(&b43_get_fallback_ssb_sprom); + if (ret) + return ret; +#endif /* CONFIG_SSB_PCIHOST */ + +#if defined(CONFIG_BCMA_HOST_PCI) + ret = bcma_arch_register_fallback_sprom(b43_get_fallback_bcma_sprom); + if (ret) + return ret; +#endif /* CONFIG_BCMA_HOST_PCI */ + + return 0; +} + +static const struct of_device_id b43_sprom_of_match[] = { + { .compatible = "brcm,bcm43xx-sprom", .data = NULL }, +#if defined (CONFIG_SSB_PCIHOST) + { .compatible = "brcm,bcm4306-sprom", .data = &bcm4306_sprom, }, + { .compatible = "brcm,bcm4321-sprom", .data = &bcm4321_sprom, }, + { .compatible = "brcm,bcm4322-sprom", .data = &bcm4322_sprom, }, + { .compatible = "brcm,bcm43222-sprom", .data = &bcm43222_sprom, }, +#endif /* CONFIG_BCMA_HOST_PCI */ +#if defined(CONFIG_BCMA_HOST_PCI) + { .compatible = "brcm,bcm4313-sprom", .data = &bcm4313_sprom, }, + { .compatible = "brcm,bcm4331-sprom", .data = &bcm4331_sprom, }, + { .compatible = "brcm,bcm43131-sprom", .data = &bcm43131_sprom, }, + { .compatible = "brcm,bcm43217-sprom", .data = &bcm43217_sprom, }, + { .compatible = "brcm,bcm43225-sprom", .data = &bcm43225_sprom, }, + { .compatible = "brcm,bcm43227-sprom", .data = &bcm43227_sprom, }, + { .compatible = "brcm,bcm43228-sprom", .data = &bcm43228_sprom, }, +#endif /* CONFIG_BCMA_HOST_PCI */ + { /* sentinel */ } +}; + +static struct platform_driver b43_sprom_driver = { + .probe = b43_sprom_probe, + .driver = { + .name = "b43-sprom", + .of_match_table = b43_sprom_of_match, + }, +}; + +int __init b43_sprom_init(void) +{ + int ret = platform_driver_register(&b43_sprom_driver); + if (ret) + pr_err("b43-sprom: Error registering platform driver!\n"); + return ret; +} +late_initcall(b43_sprom_init); diff --git a/target/linux/bmips/files/arch/mips/pci/fixup-bmips.c b/target/linux/bmips/files/arch/mips/pci/fixup-bmips.c new file mode 100644 index 0000000000..34050407c4 --- /dev/null +++ b/target/linux/bmips/files/arch/mips/pci/fixup-bmips.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Álvaro Fernández Rojas + */ + +#include + +int bmips_pci_irq = -1; + +int pcibios_plat_dev_init(struct pci_dev *pci_dev) +{ + return PCIBIOS_SUCCESSFUL; +} + +int pcibios_map_irq(const struct pci_dev *pci_dev, u8 slot, u8 pin) +{ + return bmips_pci_irq; +} diff --git a/target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c b/target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c new file mode 100644 index 0000000000..c1d3bde5df --- /dev/null +++ b/target/linux/bmips/files/drivers/pci/controller/pci-bcm6348.c @@ -0,0 +1,825 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * BCM6348 PCI Controller Driver + * + * Copyright (C) 2020 Álvaro Fernández Rojas + * Copyright (C) 2015 Jonas Gorski + * Copyright (C) 2008 Maxime Bizon + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../pci.h" + +#define CARDBUS_DUMMY_ID 0x6348 +#define CARDBUS_PCI_IDSEL 0x8 +#define FAKE_CB_BRIDGE_SLOT 0x1e + +#define BCMPCI_REG_TIMERS 0x40 +#define REG_TIMER_TRDY_SHIFT 0 +#define REG_TIMER_TRDY_MASK (0xff << REG_TIMER_TRDY_SHIFT) +#define REG_TIMER_RETRY_SHIFT 8 +#define REG_TIMER_RETRY_MASK (0xff << REG_TIMER_RETRY_SHIFT) + +#define MPI_SP0_RANGE_REG 0x100 +#define MPI_SP0_REMAP_REG 0x104 +#define MPI_SP0_REMAP_ENABLE_MASK (1 << 0) +#define MPI_SP1_RANGE_REG 0x10C +#define MPI_SP1_REMAP_REG 0x110 +#define MPI_SP1_REMAP_ENABLE_MASK (1 << 0) + +#define MPI_L2PCFG_REG 0x11c +#define MPI_L2PCFG_CFG_TYPE_SHIFT 0 +#define MPI_L2PCFG_CFG_TYPE_MASK (0x3 << MPI_L2PCFG_CFG_TYPE_SHIFT) +#define MPI_L2PCFG_REG_SHIFT 2 +#define MPI_L2PCFG_REG_MASK (0x3f << MPI_L2PCFG_REG_SHIFT) +#define MPI_L2PCFG_FUNC_SHIFT 8 +#define MPI_L2PCFG_FUNC_MASK (0x7 << MPI_L2PCFG_FUNC_SHIFT) +#define MPI_L2PCFG_DEVNUM_SHIFT 11 +#define MPI_L2PCFG_DEVNUM_MASK (0x1f << MPI_L2PCFG_DEVNUM_SHIFT) +#define MPI_L2PCFG_CFG_USEREG_MASK (1 << 30) +#define MPI_L2PCFG_CFG_SEL_MASK (1 << 31) + +#define MPI_L2PMEMRANGE1_REG 0x120 +#define MPI_L2PMEMBASE1_REG 0x124 +#define MPI_L2PMEMREMAP1_REG 0x128 +#define MPI_L2PMEMRANGE2_REG 0x12C +#define MPI_L2PMEMBASE2_REG 0x130 +#define MPI_L2PMEMREMAP2_REG 0x134 +#define MPI_L2PIORANGE_REG 0x138 +#define MPI_L2PIOBASE_REG 0x13C +#define MPI_L2PIOREMAP_REG 0x140 +#define MPI_L2P_BASE_MASK (0xffff8000) +#define MPI_L2PREMAP_ENABLED_MASK (1 << 0) +#define MPI_L2PREMAP_IS_CARDBUS_MASK (1 << 2) + +#define MPI_PCIMODESEL_REG 0x144 +#define MPI_PCIMODESEL_BAR1_NOSWAP_MASK (1 << 0) +#define MPI_PCIMODESEL_BAR2_NOSWAP_MASK (1 << 1) +#define MPI_PCIMODESEL_EXT_ARB_MASK (1 << 2) +#define MPI_PCIMODESEL_PREFETCH_SHIFT 4 +#define MPI_PCIMODESEL_PREFETCH_MASK (0xf << MPI_PCIMODESEL_PREFETCH_SHIFT) + +#define MPI_LOCBUSCTL_REG 0x14c +#define MPI_LOCBUSCTL_EN_PCI_GPIO_MASK (1 << 0) +#define MPI_LOCBUSCTL_U2P_NOSWAP_MASK (1 << 1) + +#define MPI_LOCINT_REG 0x150 +#define MPI_LOCINT_MASK(x) (1 << (x + 16)) +#define MPI_LOCINT_STAT(x) (1 << (x)) +#define MPI_LOCINT_DIR_FAILED 6 +#define MPI_LOCINT_EXT_PCI_INT 7 +#define MPI_LOCINT_SERR 8 +#define MPI_LOCINT_CSERR 9 + +#define MPI_PCICFGCTL_REG 0x178 +#define MPI_PCICFGCTL_CFGADDR_SHIFT 2 +#define MPI_PCICFGCTL_CFGADDR_MASK (0x1f << MPI_PCICFGCTL_CFGADDR_SHIFT) +#define MPI_PCICFGCTL_WRITEEN_MASK (1 << 7) + +#define MPI_PCICFGDATA_REG 0x17c + +#define PCMCIA_OFFSET 0x54 + +#define PCMCIA_C1_REG 0x0 +#define PCMCIA_C1_CD1_MASK (1 << 0) +#define PCMCIA_C1_CD2_MASK (1 << 1) +#define PCMCIA_C1_VS1_MASK (1 << 2) +#define PCMCIA_C1_VS2_MASK (1 << 3) +#define PCMCIA_C1_VS1OE_MASK (1 << 6) +#define PCMCIA_C1_VS2OE_MASK (1 << 7) +#define PCMCIA_C1_CBIDSEL_SHIFT (8) +#define PCMCIA_C1_CBIDSEL_MASK (0x1f << PCMCIA_C1_CBIDSEL_SHIFT) +#define PCMCIA_C1_EN_PCMCIA_GPIO_MASK (1 << 13) +#define PCMCIA_C1_EN_PCMCIA_MASK (1 << 14) +#define PCMCIA_C1_EN_CARDBUS_MASK (1 << 15) +#define PCMCIA_C1_RESET_MASK (1 << 18) + +#ifdef CONFIG_CARDBUS +struct bcm6348_cb { + u16 pci_command; + u8 cb_latency; + u8 subordinate_busn; + u8 cardbus_busn; + u8 pci_busn; + int bus_assigned; + u16 bridge_control; + + u32 mem_base0; + u32 mem_limit0; + u32 mem_base1; + u32 mem_limit1; + + u32 io_base0; + u32 io_limit0; + u32 io_base1; + u32 io_limit1; +}; +#endif /* CONFIG_CARDBUS */ + +struct bcm6348_pci { + void __iomem *pci; + void __iomem *pcmcia; + void __iomem *io; + int irq; + struct reset_control *reset; + bool remap; +#ifdef CONFIG_CARDBUS + struct bcm6348_cb cb; + int cb_bus; +#endif /* CONFIG_CARDBUS */ +}; + +static struct bcm6348_pci bcm6348_pci; + +extern int bmips_pci_irq; + +static u32 bcm6348_int_cfg_readl(u32 reg) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + u32 tmp; + + tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK; + tmp |= MPI_PCICFGCTL_WRITEEN_MASK; + __raw_writel(tmp, priv->pci + MPI_PCICFGCTL_REG); + iob(); + return __raw_readl(priv->pci + MPI_PCICFGDATA_REG); +} + +static void bcm6348_int_cfg_writel(u32 val, u32 reg) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + u32 tmp; + + tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK; + tmp |= MPI_PCICFGCTL_WRITEEN_MASK; + __raw_writel(tmp, priv->pci + MPI_PCICFGCTL_REG); + __raw_writel(val, priv->pci + MPI_PCICFGDATA_REG); +} + +/* + * swizzle 32bits data to return only the needed part + */ +static int postprocess_read(u32 data, int where, unsigned int size) +{ + u32 ret = 0; + + switch (size) { + case 1: + ret = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + ret = (data >> ((where & 3) << 3)) & 0xffff; + break; + case 4: + ret = data; + break; + } + + return ret; +} + +static int preprocess_write(u32 orig_data, u32 val, int where, + unsigned int size) +{ + u32 ret = 0; + + switch (size) { + case 1: + ret = (orig_data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 2: + ret = (orig_data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 4: + ret = val; + break; + } + + return ret; +} + +static int bcm6348_setup_cfg_access(int type, unsigned int busn, + unsigned int devfn, int where) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + unsigned int slot, func, reg; + u32 val; + + slot = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + reg = where >> 2; + + /* sanity check */ + if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT)) + return 1; + + if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT)) + return 1; + + if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT)) + return 1; + + /* ok, setup config access */ + val = (reg << MPI_L2PCFG_REG_SHIFT); + val |= (func << MPI_L2PCFG_FUNC_SHIFT); + val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT); + val |= MPI_L2PCFG_CFG_USEREG_MASK; + val |= MPI_L2PCFG_CFG_SEL_MASK; + /* type 0 cycle for local bus, type 1 cycle for anything else */ + if (type != 0) { + /* FIXME: how to specify bus ??? */ + val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT); + } + __raw_writel(val, priv->pci + MPI_L2PCFG_REG); + + return 0; +} + + +static int bcm6348_do_cfg_read(int type, unsigned int busn, + unsigned int devfn, int where, int size, + u32 *val) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + u32 data; + + /* two phase cycle, first we write address, then read data at + * another location, caller already has a spinlock so no need + * to add one here */ + if (bcm6348_setup_cfg_access(type, busn, devfn, where)) + return PCIBIOS_DEVICE_NOT_FOUND; + iob(); + data = le32_to_cpu(__raw_readl(priv->io)); + /* restore IO space normal behaviour */ + __raw_writel(0, priv->pci + MPI_L2PCFG_REG); + + *val = postprocess_read(data, where, size); + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm6348_do_cfg_write(int type, unsigned int busn, + unsigned int devfn, int where, int size, + u32 val) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + u32 data; + + /* two phase cycle, first we write address, then write data to + * another location, caller already has a spinlock so no need + * to add one here */ + if (bcm6348_setup_cfg_access(type, busn, devfn, where)) + return PCIBIOS_DEVICE_NOT_FOUND; + iob(); + + data = le32_to_cpu(__raw_readl(priv->io)); + data = preprocess_write(data, val, where, size); + + __raw_writel(cpu_to_le32(data), priv->io); + wmb(); + /* no way to know the access is done, we have to wait */ + udelay(500); + /* restore IO space normal behaviour */ + __raw_writel(0, priv->pci + MPI_L2PCFG_REG); + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm6348_pci_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + int type; + + type = bus->parent ? 1 : 0; + + if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL) + return PCIBIOS_DEVICE_NOT_FOUND; + + return bcm6348_do_cfg_read(type, bus->number, devfn, + where, size, val); +} + +static int bcm6348_pci_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + int type; + + type = bus->parent ? 1 : 0; + + if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL) + return PCIBIOS_DEVICE_NOT_FOUND; + + return bcm6348_do_cfg_write(type, bus->number, devfn, + where, size, val); +} + +static struct pci_ops bcm6348_pci_ops = { + .read = bcm6348_pci_read, + .write = bcm6348_pci_write, +}; + +static struct resource bcm6348_pci_io_resource = { + .name = "BCM6348 PCI IO space", + .flags = IORESOURCE_IO, +}; +static struct resource bcm6348_pci_mem_resource; +static struct resource bcm6348_pci_busn_resource; + +static struct pci_controller bcm6348_pci_controller = { + .pci_ops = &bcm6348_pci_ops, + .io_resource = &bcm6348_pci_io_resource, + .mem_resource = &bcm6348_pci_mem_resource, + .busn_resource = &bcm6348_pci_busn_resource, +}; + +#ifdef CONFIG_CARDBUS +static int bcm6348_cb_bridge_read(int where, int size, u32 *val) +{ + struct bcm6348_cb *cb = &bcm6348_pci.cb; + unsigned int reg; + u32 data; + + data = 0; + reg = where >> 2; + switch (reg) { + case (PCI_VENDOR_ID >> 2): + case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2): + /* create dummy vendor/device id from our cpu id */ + data = (CARDBUS_DUMMY_ID << 16) | PCI_VENDOR_ID_BROADCOM; + break; + + case (PCI_COMMAND >> 2): + data = (PCI_STATUS_DEVSEL_SLOW << 16); + data |= cb->pci_command; + break; + + case (PCI_CLASS_REVISION >> 2): + data = (PCI_CLASS_BRIDGE_CARDBUS << 16); + break; + + case (PCI_CACHE_LINE_SIZE >> 2): + data = (PCI_HEADER_TYPE_CARDBUS << 16); + break; + + case (PCI_INTERRUPT_LINE >> 2): + /* bridge control */ + data = (cb->bridge_control << 16); + /* pin:intA line:0xff */ + data |= (0x1 << 8) | 0xff; + break; + + case (PCI_CB_PRIMARY_BUS >> 2): + data = (cb->cb_latency << 24); + data |= (cb->subordinate_busn << 16); + data |= (cb->cardbus_busn << 8); + data |= cb->pci_busn; + break; + + case (PCI_CB_MEMORY_BASE_0 >> 2): + data = cb->mem_base0; + break; + + case (PCI_CB_MEMORY_LIMIT_0 >> 2): + data = cb->mem_limit0; + break; + + case (PCI_CB_MEMORY_BASE_1 >> 2): + data = cb->mem_base1; + break; + + case (PCI_CB_MEMORY_LIMIT_1 >> 2): + data = cb->mem_limit1; + break; + + case (PCI_CB_IO_BASE_0 >> 2): + /* | 1 for 32bits io support */ + data = cb->io_base0 | 0x1; + break; + + case (PCI_CB_IO_LIMIT_0 >> 2): + data = cb->io_limit0; + break; + + case (PCI_CB_IO_BASE_1 >> 2): + /* | 1 for 32bits io support */ + data = cb->io_base1 | 0x1; + break; + + case (PCI_CB_IO_LIMIT_1 >> 2): + data = cb->io_limit1; + break; + } + + *val = postprocess_read(data, where, size); + return PCIBIOS_SUCCESSFUL; +} + +/* + * emulate configuration write access on a cardbus bridge + */ +static int bcm6348_cb_bridge_write(int where, int size, u32 val) +{ + struct bcm6348_cb *cb = &bcm6348_pci.cb; + unsigned int reg; + u32 data, tmp; + int ret; + + ret = bcm6348_cb_bridge_read((where & ~0x3), 4, &data); + if (ret != PCIBIOS_SUCCESSFUL) + return ret; + + data = preprocess_write(data, val, where, size); + + reg = where >> 2; + switch (reg) { + case (PCI_COMMAND >> 2): + cb->pci_command = (data & 0xffff); + break; + + case (PCI_CB_PRIMARY_BUS >> 2): + cb->cb_latency = (data >> 24) & 0xff; + cb->subordinate_busn = (data >> 16) & 0xff; + cb->cardbus_busn = (data >> 8) & 0xff; + cb->pci_busn = data & 0xff; + if (cb->cardbus_busn) + cb->bus_assigned = 1; + break; + + case (PCI_INTERRUPT_LINE >> 2): + tmp = (data >> 16) & 0xffff; + /* Disable memory prefetch support */ + tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; + tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; + cb->bridge_control = tmp; + break; + + case (PCI_CB_MEMORY_BASE_0 >> 2): + cb->mem_base0 = data; + break; + + case (PCI_CB_MEMORY_LIMIT_0 >> 2): + cb->mem_limit0 = data; + break; + + case (PCI_CB_MEMORY_BASE_1 >> 2): + cb->mem_base1 = data; + break; + + case (PCI_CB_MEMORY_LIMIT_1 >> 2): + cb->mem_limit1 = data; + break; + + case (PCI_CB_IO_BASE_0 >> 2): + cb->io_base0 = data; + break; + + case (PCI_CB_IO_LIMIT_0 >> 2): + cb->io_limit0 = data; + break; + + case (PCI_CB_IO_BASE_1 >> 2): + cb->io_base1 = data; + break; + + case (PCI_CB_IO_LIMIT_1 >> 2): + cb->io_limit1 = data; + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm6348_cb_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + struct bcm6348_cb *cb = &priv->cb; + + /* Snoop access to slot 0x1e on root bus, we fake a cardbus + * bridge at this location */ + if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) { + priv->cb_bus = bus->number; + return bcm6348_cb_bridge_read(where, size, val); + } + + /* A configuration cycle for the device behind the cardbus + * bridge is actually done as a type 0 cycle on the primary + * bus. This means that only one device can be on the cardbus + * bus */ + if (cb->bus_assigned && + bus->number == cb->cardbus_busn && + PCI_SLOT(devfn) == 0) + return bcm6348_do_cfg_read(0, 0, + PCI_DEVFN(CARDBUS_PCI_IDSEL, 0), + where, size, val); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static int bcm6348_cb_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + struct bcm6348_cb *cb = &priv->cb; + + if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) { + priv->cb_bus = bus->number; + return bcm6348_cb_bridge_write(where, size, val); + } + + if (cb->bus_assigned && + bus->number == cb->cardbus_busn && + PCI_SLOT(devfn) == 0) + return bcm6348_do_cfg_write(0, 0, + PCI_DEVFN(CARDBUS_PCI_IDSEL, 0), + where, size, val); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static struct pci_ops bcm6348_cb_ops = { + .read = bcm6348_cb_read, + .write = bcm6348_cb_write, +}; + +/* + * only one IO window, so it cannot be shared by PCI and cardbus, use + * fixup to choose and detect unhandled configuration + */ +static void bcm6348_pci_fixup(struct pci_dev *dev) +{ + struct bcm6348_pci *priv = &bcm6348_pci; + struct bcm6348_cb *cb = &priv->cb; + static int io_window = -1; + int i, found, new_io_window; + u32 val; + + /* look for any io resource */ + found = 0; + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (pci_resource_flags(dev, i) & IORESOURCE_IO) { + found = 1; + break; + } + } + + if (!found) + return; + + /* skip our fake bus with only cardbus bridge on it */ + if (dev->bus->number == priv->cb_bus) + return; + + /* find on which bus the device is */ + if (cb->bus_assigned && + dev->bus->number == cb->cardbus_busn && + PCI_SLOT(dev->devfn) == 0) + new_io_window = 1; + else + new_io_window = 0; + + if (new_io_window == io_window) + return; + + if (io_window != -1) { + pr_err("bcm63xx: both PCI and cardbus devices " + "need IO, which hardware cannot do\n"); + return; + } + + pr_info("bcm63xx: PCI IO window assigned to %s\n", + (new_io_window == 0) ? "PCI" : "cardbus"); + + val = __raw_readl(priv->pci + MPI_L2PIOREMAP_REG); + if (io_window) + val |= MPI_L2PREMAP_IS_CARDBUS_MASK; + else + val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK; + __raw_writel(val, priv->pci + MPI_L2PIOREMAP_REG); + + io_window = new_io_window; +} +DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm6348_pci_fixup); + +static struct resource bcm6348_cb_io_resource = { + .name = "bcm6348 CB IO space", + .flags = IORESOURCE_IO, +}; +static struct resource bcm6348_cb_mem_resource; + +static struct pci_controller bcm6348_cb_controller = { + .pci_ops = &bcm6348_cb_ops, + .io_resource = &bcm6348_cb_io_resource, + .mem_resource = &bcm6348_cb_mem_resource, +}; +#endif /* CONFIG_CARDBUS */ + +static void bcm6348_pci_setup(struct bcm6348_pci *priv) +{ + u32 val; + + /* Setup local bus to PCI access (PCI memory) */ + val = bcm6348_pci_mem_resource.start & MPI_L2P_BASE_MASK; + __raw_writel(val, priv->pci + MPI_L2PMEMBASE1_REG); + __raw_writel(~(resource_size(&bcm6348_pci_mem_resource) - 1), + priv->pci + MPI_L2PMEMRANGE1_REG); + __raw_writel(val | MPI_L2PREMAP_ENABLED_MASK, + priv->pci + MPI_L2PMEMREMAP1_REG); + + /* Set Cardbus IDSEL (type 0 cfg access on primary bus for + * this IDSEL will be done on Cardbus instead) */ + val = __raw_readl(priv->pcmcia + PCMCIA_C1_REG); + val &= ~PCMCIA_C1_CBIDSEL_MASK; + val |= (CARDBUS_PCI_IDSEL << PCMCIA_C1_CBIDSEL_SHIFT); + __raw_writel(val, priv->pcmcia + PCMCIA_C1_REG); + +#ifdef CONFIG_CARDBUS + /* setup local bus to PCI access (Cardbus memory) */ + val = bcm6348_cb_mem_resource.start & MPI_L2P_BASE_MASK; + __raw_writel(val, priv->pci + MPI_L2PMEMBASE2_REG); + __raw_writel(~(resource_size(&bcm6348_cb_mem_resource) - 1), + priv->pci + MPI_L2PMEMRANGE2_REG); + val |= MPI_L2PREMAP_ENABLED_MASK | MPI_L2PREMAP_IS_CARDBUS_MASK; + __raw_writel(val, priv->pci + MPI_L2PMEMREMAP2_REG); +#else + /* disable second access windows */ + __raw_writel(0, priv->pci + MPI_L2PMEMREMAP2_REG); +#endif + + /* setup local bus to PCI access (IO memory), we have only 1 + * IO window for both PCI and cardbus, but it cannot handle + * both at the same time, assume standard PCI for now, if + * cardbus card has IO zone, PCI fixup will change window to + * cardbus */ + val = bcm6348_pci_io_resource.start & MPI_L2P_BASE_MASK; + __raw_writel(val, priv->pci + MPI_L2PIOBASE_REG); + __raw_writel(~(resource_size(&bcm6348_pci_io_resource) - 1), + priv->pci + MPI_L2PIORANGE_REG); + __raw_writel(val | MPI_L2PREMAP_ENABLED_MASK, + priv->pci + MPI_L2PIOREMAP_REG); + + /* Enable PCI related GPIO pins */ + __raw_writel(MPI_LOCBUSCTL_EN_PCI_GPIO_MASK, + priv->pci + MPI_LOCBUSCTL_REG); + + /* Setup PCI to local bus access, used by PCI device to target + * local RAM while bus mastering */ + bcm6348_int_cfg_writel(0, PCI_BASE_ADDRESS_3); + if (priv->remap) + val = MPI_SP0_REMAP_ENABLE_MASK; + else + val = 0; + __raw_writel(val, priv->pci + MPI_SP0_REMAP_REG); + + bcm6348_int_cfg_writel(0, PCI_BASE_ADDRESS_4); + __raw_writel(0, priv->pci + MPI_SP1_REMAP_REG); + + /* Setup sp0 range to local RAM size */ + __raw_writel(~(memblock_phys_mem_size() - 1), + priv->pci + MPI_SP0_RANGE_REG); + __raw_writel(0, priv->pci + MPI_SP1_RANGE_REG); + + /* Change host bridge retry counter to infinite number of + * retries, needed for some broadcom wifi cards with Silicon + * Backplane bus where access to srom seems very slow */ + val = bcm6348_int_cfg_readl(BCMPCI_REG_TIMERS); + val &= ~REG_TIMER_RETRY_MASK; + bcm6348_int_cfg_writel(val, BCMPCI_REG_TIMERS); + + /* EEnable memory decoder and bus mastering */ + val = bcm6348_int_cfg_readl(PCI_COMMAND); + val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + bcm6348_int_cfg_writel(val, PCI_COMMAND); + + /* Enable read prefetching & disable byte swapping for bus + * mastering transfers */ + val = __raw_readl(priv->pci + MPI_PCIMODESEL_REG); + val &= ~MPI_PCIMODESEL_BAR1_NOSWAP_MASK; + val &= ~MPI_PCIMODESEL_BAR2_NOSWAP_MASK; + val &= ~MPI_PCIMODESEL_PREFETCH_MASK; + val |= (8 << MPI_PCIMODESEL_PREFETCH_SHIFT); + __raw_writel(val, priv->pci + MPI_PCIMODESEL_REG); + + /* Enable pci interrupt */ + val = __raw_readl(priv->pci + MPI_LOCINT_REG); + val |= MPI_LOCINT_MASK(MPI_LOCINT_EXT_PCI_INT); + __raw_writel(val, priv->pci + MPI_LOCINT_REG); +} + +static int bcm6348_pci_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6348_pci *priv = &bcm6348_pci; + struct resource *res; + + of_pci_check_probe_only(); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pci"); + priv->pci = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->pci)) + return PTR_ERR(priv->pci); + + priv->pcmcia = priv->pci + PCMCIA_OFFSET; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pci-io"); + if (!res) + return -EINVAL; +#ifdef CONFIG_CARDBUS + bcm6348_pci_io_resource.start = res->start; + bcm6348_pci_io_resource.end = res->end - (resource_size(res) >> 1); + bcm6348_cb_io_resource.start = res->start + (resource_size(res) >> 1); + bcm6348_cb_io_resource.end = res->end; +#else + bcm6348_pci_io_resource.start = res->start; + bcm6348_pci_io_resource.end = res->end; +#endif + + priv->irq = platform_get_irq(pdev, 0); + if (!priv->irq) + return -ENODEV; + + bmips_pci_irq = priv->irq; + + priv->reset = devm_reset_control_get(dev, "pci"); + if (IS_ERR(priv->reset)) + return PTR_ERR(priv->reset); + + priv->remap = of_property_read_bool(np, "brcm,remap"); + + reset_control_reset(priv->reset); + + pci_load_of_ranges(&bcm6348_pci_controller, np); + if (!bcm6348_pci_mem_resource.start) + return -EINVAL; + + of_pci_parse_bus_range(np, &bcm6348_pci_busn_resource); + + /* + * Configuration accesses are done through IO space, remap 4 + * first bytes to access it from CPU. + * + * This means that no IO access from CPU should happen while + * we do a configuration cycle, but there's no way we can add + * a spinlock for each io access, so this is currently kind of + * broken on SMP. + */ + priv->io = ioremap(bcm6348_pci_io_resource.start, sizeof(u32)); + if (!priv->io) + return -ENOMEM; + + bcm6348_pci_setup(priv); + + register_pci_controller(&bcm6348_pci_controller); + +#ifdef CONFIG_CARDBUS + priv->cb_bus = -1; + register_pci_controller(&bcm6348_cb_controller); +#endif /* CONFIG_CARDBUS */ + + /* Mark memory space used for IO mapping as reserved */ + request_mem_region(bcm6348_pci_io_resource.start, + resource_size(&bcm6348_pci_io_resource), + "BCM6348 PCI IO space"); + + return 0; +} + +static const struct of_device_id bcm6348_pci_of_match[] = { + { .compatible = "brcm,bcm6348-pci", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6348_pci_driver = { + .probe = bcm6348_pci_probe, + .driver = { + .name = "bcm6348-pci", + .of_match_table = bcm6348_pci_of_match, + }, +}; + +int __init bcm6348_pci_init(void) +{ + int ret = platform_driver_register(&bcm6348_pci_driver); + if (ret) + pr_err("pci-bcm6348: Error registering platform driver!\n"); + return ret; +} +late_initcall_sync(bcm6348_pci_init); diff --git a/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c new file mode 100644 index 0000000000..1df67b8389 --- /dev/null +++ b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6318.c @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * BCM6318 PCIe Controller Driver + * + * Copyright (C) 2020 Álvaro Fernández Rojas + * Copyright (C) 2015 Jonas Gorski + * Copyright (C) 2008 Maxime Bizon + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../pci.h" + +#define PCIE_BUS_BRIDGE 0 +#define PCIE_BUS_DEVICE 1 + +#define PCIE_SPECIFIC_REG 0x188 +#define SPECIFIC_ENDIAN_MODE_BAR1_SHIFT 0 +#define SPECIFIC_ENDIAN_MODE_BAR1_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT) +#define SPECIFIC_ENDIAN_MODE_BAR2_SHIFT 2 +#define SPECIFIC_ENDIAN_MODE_BAR2_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT) +#define SPECIFIC_ENDIAN_MODE_BAR3_SHIFT 4 +#define SPECIFIC_ENDIAN_MODE_BAR3_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT) +#define SPECIFIC_ENDIAN_MODE_WORD_ALIGN 0 +#define SPECIFIC_ENDIAN_MODE_HALFWORD_ALIGN 1 +#define SPECIFIC_ENDIAN_MODE_BYTE_ALIGN 2 + +#define PCIE_CONFIG2_REG 0x408 +#define CONFIG2_BAR1_SIZE_EN 1 +#define CONFIG2_BAR1_SIZE_MASK 0xf + +#define PCIE_IDVAL3_REG 0x43c +#define IDVAL3_CLASS_CODE_MASK 0xffffff +#define IDVAL3_SUBCLASS_SHIFT 8 +#define IDVAL3_CLASS_SHIFT 16 + +#define PCIE_DLSTATUS_REG 0x1048 +#define DLSTATUS_PHYLINKUP (1 << 13) + +#define PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG 0x400c +#define C2P_MEM_WIN_ENDIAN_MODE_MASK 0x3 +#define C2P_MEM_WIN_ENDIAN_NO_SWAP 0 +#define C2P_MEM_WIN_ENDIAN_HALF_WORD_SWAP 1 +#define C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP 2 +#define C2P_MEM_WIN_BASE_ADDR_SHIFT 20 +#define C2P_MEM_WIN_BASE_ADDR_MASK (0xfff << C2P_MEM_WIN_BASE_ADDR_SHIFT) + +#define PCIE_RC_BAR1_CONFIG_LO_REG 0x402c +#define RC_BAR_CFG_LO_SIZE_256MB 0xd +#define RC_BAR_CFG_LO_MATCH_ADDR_SHIFT 20 +#define RC_BAR_CFG_LO_MATCH_ADDR_MASK (0xfff << RC_BAR_CFG_LO_MATCH_ADDR_SHIFT) + +#define PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG 0x4070 +#define C2P_BASELIMIT_LIMIT_SHIFT 20 +#define C2P_BASELIMIT_LIMIT_MASK (0xfff << C2P_BASELIMIT_LIMIT_SHIFT) +#define C2P_BASELIMIT_BASE_SHIFT 4 +#define C2P_BASELIMIT_BASE_MASK (0xfff << C2P_BASELIMIT_BASE_SHIFT) + +#define PCIE_UBUS_BAR1_CFG_REMAP_REG 0x4088 +#define BAR1_CFG_REMAP_OFFSET_SHIFT 20 +#define BAR1_CFG_REMAP_OFFSET_MASK (0xfff << BAR1_CFG_REMAP_OFFSET_SHIFT) +#define BAR1_CFG_REMAP_ACCESS_EN 1 + +#define PCIE_HARD_DEBUG_REG 0x4204 +#define HARD_DEBUG_SERDES_IDDQ (1 << 23) + +#define PCIE_CPU_INT1_MASK_CLEAR_REG 0x830c +#define CPU_INT_PCIE_ERR_ATTN_CPU (1 << 0) +#define CPU_INT_PCIE_INTA (1 << 1) +#define CPU_INT_PCIE_INTB (1 << 2) +#define CPU_INT_PCIE_INTC (1 << 3) +#define CPU_INT_PCIE_INTD (1 << 4) +#define CPU_INT_PCIE_INTR (1 << 5) +#define CPU_INT_PCIE_NMI (1 << 6) +#define CPU_INT_PCIE_UBUS (1 << 7) +#define CPU_INT_IPI (1 << 8) + +#define PCIE_EXT_CFG_INDEX_REG 0x8400 +#define EXT_CFG_FUNC_NUM_SHIFT 12 +#define EXT_CFG_FUNC_NUM_MASK (0x7 << EXT_CFG_FUNC_NUM_SHIFT) +#define EXT_CFG_DEV_NUM_SHIFT 15 +#define EXT_CFG_DEV_NUM_MASK (0xf << EXT_CFG_DEV_NUM_SHIFT) +#define EXT_CFG_BUS_NUM_SHIFT 20 +#define EXT_CFG_BUS_NUM_MASK (0xff << EXT_CFG_BUS_NUM_SHIFT) + +#define PCIE_DEVICE_OFFSET 0x9000 + +struct bcm6318_pcie { + void __iomem *base; + int irq; + struct clk *clk; + struct clk *clk25; + struct clk *clk_ubus; + struct reset_control *reset; + struct reset_control *reset_ext; + struct reset_control *reset_core; + struct reset_control *reset_hard; +}; + +static struct bcm6318_pcie bcm6318_pcie; + +extern int bmips_pci_irq; + +/* + * swizzle 32bits data to return only the needed part + */ +static int postprocess_read(u32 data, int where, unsigned int size) +{ + u32 ret = 0; + + switch (size) { + case 1: + ret = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + ret = (data >> ((where & 3) << 3)) & 0xffff; + break; + case 4: + ret = data; + break; + } + + return ret; +} + +static int preprocess_write(u32 orig_data, u32 val, int where, + unsigned int size) +{ + u32 ret = 0; + + switch (size) { + case 1: + ret = (orig_data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 2: + ret = (orig_data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 4: + ret = val; + break; + } + + return ret; +} + +static int bcm6318_pcie_can_access(struct pci_bus *bus, int devfn) +{ + struct bcm6318_pcie *priv = &bcm6318_pcie; + + switch (bus->number) { + case PCIE_BUS_BRIDGE: + return PCI_SLOT(devfn) == 0; + case PCIE_BUS_DEVICE: + if (PCI_SLOT(devfn) == 0) + return __raw_readl(priv->base + PCIE_DLSTATUS_REG) + & DLSTATUS_PHYLINKUP; + /* else, fall through */ + default: + return false; + } +} + +static int bcm6318_pcie_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + struct bcm6318_pcie *priv = &bcm6318_pcie; + u32 data; + u32 reg = where & ~3; + + if (!bcm6318_pcie_can_access(bus, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (bus->number == PCIE_BUS_DEVICE) + reg += PCIE_DEVICE_OFFSET; + + data = __raw_readl(priv->base + reg); + *val = postprocess_read(data, where, size); + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm6318_pcie_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + struct bcm6318_pcie *priv = &bcm6318_pcie; + u32 data; + u32 reg = where & ~3; + + if (!bcm6318_pcie_can_access(bus, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (bus->number == PCIE_BUS_DEVICE) + reg += PCIE_DEVICE_OFFSET; + + data = __raw_readl(priv->base + reg); + data = preprocess_write(data, val, where, size); + __raw_writel(data, priv->base + reg); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops bcm6318_pcie_ops = { + .read = bcm6318_pcie_read, + .write = bcm6318_pcie_write, +}; + +static struct resource bcm6318_pcie_io_resource; +static struct resource bcm6318_pcie_mem_resource; +static struct resource bcm6318_pcie_busn_resource; + +static struct pci_controller bcm6318_pcie_controller = { + .pci_ops = &bcm6318_pcie_ops, + .io_resource = &bcm6318_pcie_io_resource, + .mem_resource = &bcm6318_pcie_mem_resource, + .busn_resource = &bcm6318_pcie_busn_resource, +}; + +static void bcm6318_pcie_reset(struct bcm6318_pcie *priv) +{ + u32 val; + + reset_control_deassert(priv->reset_hard); + + reset_control_assert(priv->reset); + reset_control_assert(priv->reset_core); + reset_control_assert(priv->reset_ext); + mdelay(10); + + reset_control_deassert(priv->reset_ext); + mdelay(10); + + reset_control_deassert(priv->reset); + mdelay(10); + + val = __raw_readl(priv->base + PCIE_HARD_DEBUG_REG); + val &= ~HARD_DEBUG_SERDES_IDDQ; + __raw_writel(val, priv->base + PCIE_HARD_DEBUG_REG); + mdelay(10); + + reset_control_deassert(priv->reset_core); + mdelay(200); +} + +static void bcm6318_pcie_setup(struct bcm6318_pcie *priv) +{ + u32 val; + + __raw_writel(CPU_INT_PCIE_INTA | CPU_INT_PCIE_INTB | + CPU_INT_PCIE_INTC | CPU_INT_PCIE_INTD, + priv->base + PCIE_CPU_INT1_MASK_CLEAR_REG); + + val = bcm6318_pcie_mem_resource.end & C2P_BASELIMIT_LIMIT_MASK; + val |= (bcm6318_pcie_mem_resource.start >> C2P_BASELIMIT_LIMIT_SHIFT) + << C2P_BASELIMIT_BASE_SHIFT; + __raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG); + + /* setup class code as bridge */ + val = __raw_readl(priv->base + PCIE_IDVAL3_REG); + val &= ~IDVAL3_CLASS_CODE_MASK; + val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT); + __raw_writel(val, priv->base + PCIE_IDVAL3_REG); + + /* disable bar1 size */ + val = __raw_readl(priv->base + PCIE_CONFIG2_REG); + val &= ~CONFIG2_BAR1_SIZE_MASK; + __raw_writel(val, priv->base + PCIE_CONFIG2_REG); + + /* set bar0 to little endian */ + val = __raw_readl(priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG); + val |= bcm6318_pcie_mem_resource.start & C2P_MEM_WIN_BASE_ADDR_MASK; + val |= C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP; + __raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG); + + __raw_writel(SPECIFIC_ENDIAN_MODE_BYTE_ALIGN, + priv->base + PCIE_SPECIFIC_REG); + + __raw_writel(RC_BAR_CFG_LO_SIZE_256MB, + priv->base + PCIE_RC_BAR1_CONFIG_LO_REG); + + __raw_writel(BAR1_CFG_REMAP_ACCESS_EN, + priv->base + PCIE_UBUS_BAR1_CFG_REMAP_REG); + + __raw_writel(PCIE_BUS_DEVICE << EXT_CFG_BUS_NUM_SHIFT, + priv->base + PCIE_EXT_CFG_INDEX_REG); +} + +static int bcm6318_pcie_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6318_pcie *priv = &bcm6318_pcie; + struct resource *res; + int ret; + + of_pci_check_probe_only(); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->irq = platform_get_irq(pdev, 0); + if (!priv->irq) + return -ENODEV; + + bmips_pci_irq = priv->irq; + + priv->reset = devm_reset_control_get(dev, "pcie"); + if (IS_ERR(priv->reset)) + return PTR_ERR(priv->reset); + + priv->reset_ext = devm_reset_control_get(dev, "pcie-ext"); + if (IS_ERR(priv->reset_ext)) + return PTR_ERR(priv->reset_ext); + + priv->reset_core = devm_reset_control_get(dev, "pcie-core"); + if (IS_ERR(priv->reset_core)) + return PTR_ERR(priv->reset_core); + + priv->reset_hard = devm_reset_control_get(dev, "pcie-hard"); + if (IS_ERR(priv->reset_hard)) + return PTR_ERR(priv->reset_hard); + + priv->clk = devm_clk_get(dev, "pcie"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + + priv->clk25 = devm_clk_get(dev, "pcie25"); + if (IS_ERR(priv->clk25)) + return PTR_ERR(priv->clk25); + + priv->clk_ubus = devm_clk_get(dev, "pcie-ubus"); + if (IS_ERR(priv->clk_ubus)) + return PTR_ERR(priv->clk_ubus); + + ret = clk_prepare_enable(priv->clk); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return ret; + } + + ret = clk_prepare_enable(priv->clk25); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return ret; + } + + ret = clk_prepare_enable(priv->clk_ubus); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return ret; + } + + pci_load_of_ranges(&bcm6318_pcie_controller, np); + if (!bcm6318_pcie_mem_resource.start) + return -EINVAL; + + of_pci_parse_bus_range(np, &bcm6318_pcie_busn_resource); + + bcm6318_pcie_reset(priv); + bcm6318_pcie_setup(priv); + + register_pci_controller(&bcm6318_pcie_controller); + + return 0; +} + +static const struct of_device_id bcm6318_pcie_of_match[] = { + { .compatible = "brcm,bcm6318-pcie", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6318_pcie_driver = { + .probe = bcm6318_pcie_probe, + .driver = { + .name = "bcm6318-pcie", + .of_match_table = bcm6318_pcie_of_match, + }, +}; + +int __init bcm6318_pcie_init(void) +{ + int ret = platform_driver_register(&bcm6318_pcie_driver); + if (ret) + pr_err("pci-bcm6318: Error registering platform driver!\n"); + return ret; +} +late_initcall_sync(bcm6318_pcie_init); diff --git a/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c new file mode 100644 index 0000000000..4c0d3723b8 --- /dev/null +++ b/target/linux/bmips/files/drivers/pci/controller/pcie-bcm6328.c @@ -0,0 +1,412 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * BCM6328 PCIe Controller Driver + * + * Copyright (C) 2020 Álvaro Fernández Rojas + * Copyright (C) 2015 Jonas Gorski + * Copyright (C) 2008 Maxime Bizon + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../pci.h" + +#define SERDES_PCIE_EXD_EN BIT(15) +#define SERDES_PCIE_EN BIT(0) + +#define PCIE_BUS_BRIDGE 0 +#define PCIE_BUS_DEVICE 1 + +#define PCIE_CONFIG2_REG 0x408 +#define CONFIG2_BAR1_SIZE_EN 1 +#define CONFIG2_BAR1_SIZE_MASK 0xf + +#define PCIE_IDVAL3_REG 0x43c +#define IDVAL3_CLASS_CODE_MASK 0xffffff +#define IDVAL3_SUBCLASS_SHIFT 8 +#define IDVAL3_CLASS_SHIFT 16 + +#define PCIE_DLSTATUS_REG 0x1048 +#define DLSTATUS_PHYLINKUP (1 << 13) + +#define PCIE_BRIDGE_OPT1_REG 0x2820 +#define OPT1_RD_BE_OPT_EN (1 << 7) +#define OPT1_RD_REPLY_BE_FIX_EN (1 << 9) +#define OPT1_PCIE_BRIDGE_HOLE_DET_EN (1 << 11) +#define OPT1_L1_INT_STATUS_MASK_POL (1 << 12) + +#define PCIE_BRIDGE_OPT2_REG 0x2824 +#define OPT2_UBUS_UR_DECODE_DIS (1 << 2) +#define OPT2_TX_CREDIT_CHK_EN (1 << 4) +#define OPT2_CFG_TYPE1_BD_SEL (1 << 7) +#define OPT2_CFG_TYPE1_BUS_NO_SHIFT 16 +#define OPT2_CFG_TYPE1_BUS_NO_MASK (0xff << OPT2_CFG_TYPE1_BUS_NO_SHIFT) + +#define PCIE_BRIDGE_BAR0_BASEMASK_REG 0x2828 +#define BASEMASK_REMAP_EN (1 << 0) +#define BASEMASK_SWAP_EN (1 << 1) +#define BASEMASK_MASK_SHIFT 4 +#define BASEMASK_MASK_MASK (0xfff << BASEMASK_MASK_SHIFT) +#define BASEMASK_BASE_SHIFT 20 +#define BASEMASK_BASE_MASK (0xfff << BASEMASK_BASE_SHIFT) + +#define PCIE_BRIDGE_BAR0_REBASE_ADDR_REG 0x282c +#define REBASE_ADDR_BASE_SHIFT 20 +#define REBASE_ADDR_BASE_MASK (0xfff << REBASE_ADDR_BASE_SHIFT) + +#define PCIE_BRIDGE_RC_INT_MASK_REG 0x2854 +#define PCIE_RC_INT_A (1 << 0) +#define PCIE_RC_INT_B (1 << 1) +#define PCIE_RC_INT_C (1 << 2) +#define PCIE_RC_INT_D (1 << 3) + +#define PCIE_DEVICE_OFFSET 0x8000 + +struct bcm6328_pcie { + void __iomem *base; + int irq; + struct regmap *serdes; + struct device **pm; + struct device_link **link_pm; + unsigned int num_pms; + struct clk *clk; + struct reset_control *reset; + struct reset_control *reset_ext; + struct reset_control *reset_core; + struct reset_control *reset_hard; +}; + +static struct bcm6328_pcie bcm6328_pcie; + +extern int bmips_pci_irq; + +/* + * swizzle 32bits data to return only the needed part + */ +static int postprocess_read(u32 data, int where, unsigned int size) +{ + u32 ret = 0; + + switch (size) { + case 1: + ret = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + ret = (data >> ((where & 3) << 3)) & 0xffff; + break; + case 4: + ret = data; + break; + } + + return ret; +} + +static int preprocess_write(u32 orig_data, u32 val, int where, + unsigned int size) +{ + u32 ret = 0; + + switch (size) { + case 1: + ret = (orig_data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 2: + ret = (orig_data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 4: + ret = val; + break; + } + + return ret; +} + +static int bcm6328_pcie_can_access(struct pci_bus *bus, int devfn) +{ + struct bcm6328_pcie *priv = &bcm6328_pcie; + + switch (bus->number) { + case PCIE_BUS_BRIDGE: + return PCI_SLOT(devfn) == 0; + case PCIE_BUS_DEVICE: + if (PCI_SLOT(devfn) == 0) + return __raw_readl(priv->base + PCIE_DLSTATUS_REG) + & DLSTATUS_PHYLINKUP; + /* else, fall through */ + default: + return false; + } +} + +static int bcm6328_pcie_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + struct bcm6328_pcie *priv = &bcm6328_pcie; + u32 data; + u32 reg = where & ~3; + + if (!bcm6328_pcie_can_access(bus, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (bus->number == PCIE_BUS_DEVICE) + reg += PCIE_DEVICE_OFFSET; + + data = __raw_readl(priv->base + reg); + *val = postprocess_read(data, where, size); + + return PCIBIOS_SUCCESSFUL; +} + +static int bcm6328_pcie_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + struct bcm6328_pcie *priv = &bcm6328_pcie; + u32 data; + u32 reg = where & ~3; + + if (!bcm6328_pcie_can_access(bus, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (bus->number == PCIE_BUS_DEVICE) + reg += PCIE_DEVICE_OFFSET; + + data = __raw_readl(priv->base + reg); + data = preprocess_write(data, val, where, size); + __raw_writel(data, priv->base + reg); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops bcm6328_pcie_ops = { + .read = bcm6328_pcie_read, + .write = bcm6328_pcie_write, +}; + +static struct resource bcm6328_pcie_io_resource; +static struct resource bcm6328_pcie_mem_resource; +static struct resource bcm6328_pcie_busn_resource; + +static struct pci_controller bcm6328_pcie_controller = { + .pci_ops = &bcm6328_pcie_ops, + .io_resource = &bcm6328_pcie_io_resource, + .mem_resource = &bcm6328_pcie_mem_resource, + .busn_resource = &bcm6328_pcie_busn_resource, +}; + +static void bcm6328_pcie_reset(struct bcm6328_pcie *priv) +{ + regmap_write_bits(priv->serdes, 0, + SERDES_PCIE_EXD_EN | SERDES_PCIE_EN, + SERDES_PCIE_EXD_EN | SERDES_PCIE_EN); + + reset_control_assert(priv->reset); + reset_control_assert(priv->reset_core); + reset_control_assert(priv->reset_ext); + if (priv->reset_hard) { + reset_control_assert(priv->reset_hard); + mdelay(10); + reset_control_deassert(priv->reset_hard); + } + mdelay(10); + + reset_control_deassert(priv->reset_core); + reset_control_deassert(priv->reset); + mdelay(10); + + reset_control_deassert(priv->reset_ext); + mdelay(200); +} + +static void bcm6328_pcie_setup(struct bcm6328_pcie *priv) +{ + u32 val; + + val = __raw_readl(priv->base + PCIE_BRIDGE_OPT1_REG); + val |= OPT1_RD_BE_OPT_EN; + val |= OPT1_RD_REPLY_BE_FIX_EN; + val |= OPT1_PCIE_BRIDGE_HOLE_DET_EN; + val |= OPT1_L1_INT_STATUS_MASK_POL; + __raw_writel(val, priv->base + PCIE_BRIDGE_OPT1_REG); + + val = __raw_readl(priv->base + PCIE_BRIDGE_RC_INT_MASK_REG); + val |= PCIE_RC_INT_A; + val |= PCIE_RC_INT_B; + val |= PCIE_RC_INT_C; + val |= PCIE_RC_INT_D; + __raw_writel(val, priv->base + PCIE_BRIDGE_RC_INT_MASK_REG); + + val = __raw_readl(priv->base + PCIE_BRIDGE_OPT2_REG); + /* enable credit checking and error checking */ + val |= OPT2_TX_CREDIT_CHK_EN; + val |= OPT2_UBUS_UR_DECODE_DIS; + /* set device bus/func for the pcie device */ + val |= (PCIE_BUS_DEVICE << OPT2_CFG_TYPE1_BUS_NO_SHIFT); + val |= OPT2_CFG_TYPE1_BD_SEL; + __raw_writel(val, priv->base + PCIE_BRIDGE_OPT2_REG); + + /* setup class code as bridge */ + val = __raw_readl(priv->base + PCIE_IDVAL3_REG); + val &= ~IDVAL3_CLASS_CODE_MASK; + val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT); + __raw_writel(val, priv->base + PCIE_IDVAL3_REG); + + /* disable bar1 size */ + val = __raw_readl(priv->base + PCIE_CONFIG2_REG); + val &= ~CONFIG2_BAR1_SIZE_MASK; + __raw_writel(val, priv->base + PCIE_CONFIG2_REG); + + /* set bar0 to little endian */ + val = (bcm6328_pcie_mem_resource.start >> 20) + << BASEMASK_BASE_SHIFT; + val |= (bcm6328_pcie_mem_resource.end >> 20) << BASEMASK_MASK_SHIFT; + val |= BASEMASK_REMAP_EN; + __raw_writel(val, priv->base + PCIE_BRIDGE_BAR0_BASEMASK_REG); + + val = (bcm6328_pcie_mem_resource.start >> 20) + << REBASE_ADDR_BASE_SHIFT; + __raw_writel(val, priv->base + PCIE_BRIDGE_BAR0_REBASE_ADDR_REG); +} + +static int bcm6328_pcie_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct bcm6328_pcie *priv = &bcm6328_pcie; + struct resource *res; + unsigned int i; + int ret; + + pm_runtime_enable(dev); + pm_runtime_no_callbacks(dev); + + priv->num_pms = of_count_phandle_with_args(np, "power-domains", + "#power-domain-cells"); + if (priv->num_pms > 1) { + priv->pm = devm_kcalloc(dev, priv->num_pms, + sizeof(struct device *), GFP_KERNEL); + if (!priv->pm) + return -ENOMEM; + + priv->link_pm = devm_kcalloc(dev, priv->num_pms, + sizeof(struct device_link *), + GFP_KERNEL); + if (!priv->link_pm) + return -ENOMEM; + + for (i = 0; i < priv->num_pms; i++) { + priv->pm[i] = genpd_dev_pm_attach_by_id(dev, i); + if (IS_ERR(priv->pm[i])) { + dev_err(dev, "error getting pm %d\n", i); + return -EINVAL; + } + + priv->link_pm[i] = device_link_add(dev, priv->pm[i], + DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); + } + } + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_disable(dev); + dev_info(dev, "PM prober defer: ret=%d\n", ret); + return -EPROBE_DEFER; + } + + of_pci_check_probe_only(); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->irq = platform_get_irq(pdev, 0); + if (!priv->irq) + return -ENODEV; + + bmips_pci_irq = priv->irq; + + priv->serdes = syscon_regmap_lookup_by_phandle(np, "brcm,serdes"); + if (IS_ERR(priv->serdes)) + return PTR_ERR(priv->serdes); + + priv->reset = devm_reset_control_get(dev, "pcie"); + if (IS_ERR(priv->reset)) + return PTR_ERR(priv->reset); + + priv->reset_ext = devm_reset_control_get(dev, "pcie-ext"); + if (IS_ERR(priv->reset_ext)) + return PTR_ERR(priv->reset_ext); + + priv->reset_core = devm_reset_control_get(dev, "pcie-core"); + if (IS_ERR(priv->reset_core)) + return PTR_ERR(priv->reset_core); + + priv->reset_hard = devm_reset_control_get_optional(dev, "pcie-hard"); + if (IS_ERR(priv->reset_hard)) + return PTR_ERR(priv->reset_hard); + + priv->clk = devm_clk_get(dev, "pcie"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + + ret = clk_prepare_enable(priv->clk); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return ret; + } + + pci_load_of_ranges(&bcm6328_pcie_controller, np); + if (!bcm6328_pcie_mem_resource.start) + return -EINVAL; + + of_pci_parse_bus_range(np, &bcm6328_pcie_busn_resource); + + bcm6328_pcie_reset(priv); + bcm6328_pcie_setup(priv); + + register_pci_controller(&bcm6328_pcie_controller); + + return 0; +} + +static const struct of_device_id bcm6328_pcie_of_match[] = { + { .compatible = "brcm,bcm6328-pcie", }, + { /* sentinel */ } +}; + +static struct platform_driver bcm6328_pcie_driver = { + .probe = bcm6328_pcie_probe, + .driver = { + .name = "bcm6328-pcie", + .of_match_table = bcm6328_pcie_of_match, + }, +}; + +int __init bcm6328_pcie_init(void) +{ + int ret = platform_driver_register(&bcm6328_pcie_driver); + if (ret) + pr_err("pci-bcm6328: Error registering platform driver!\n"); + return ret; +} +late_initcall_sync(bcm6328_pcie_init); diff --git a/target/linux/bmips/image/Makefile b/target/linux/bmips/image/Makefile index c1534a88db..89cd04b0ec 100644 --- a/target/linux/bmips/image/Makefile +++ b/target/linux/bmips/image/Makefile @@ -249,6 +249,8 @@ define Device/Default DEVICE_LOADADDR := endef +ATH9K_PACKAGES := kmod-ath9k wpad-basic-wolfssl +B43_PACKAGES := kmod-b43 wpad-basic-wolfssl USB1_PACKAGES := kmod-usb-ohci kmod-ledtrig-usbdev USB2_PACKAGES := $(USB1_PACKAGES) kmod-usb2 diff --git a/target/linux/bmips/image/bcm63xx_generic.mk b/target/linux/bmips/image/bcm63xx_generic.mk index 6f9a7b9a49..33282bd1a5 100644 --- a/target/linux/bmips/image/bcm63xx_generic.mk +++ b/target/linux/bmips/image/bcm63xx_generic.mk @@ -33,7 +33,7 @@ define Device/comtrend_ar-5315u CHIP_ID := 6318 CFE_BOARD_ID := 96318A-1441N1 FLASH_MB := 16 - DEVICE_PACKAGES += $(USB2_PACKAGES) + DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES) endef TARGET_DEVICES += comtrend_ar-5315u @@ -44,7 +44,7 @@ define Device/comtrend_ar-5387un CHIP_ID := 6328 CFE_BOARD_ID := 96328A-1441N1 FLASH_MB := 16 - DEVICE_PACKAGES += $(USB2_PACKAGES) + DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES) endef TARGET_DEVICES += comtrend_ar-5387un @@ -56,7 +56,7 @@ define Device/comtrend_vr-3025u CFE_BOARD_ID := 96368M-1541N BLOCKSIZE := 0x20000 FLASH_MB := 32 - DEVICE_PACKAGES += $(USB2_PACKAGES) + DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES) endef TARGET_DEVICES += comtrend_vr-3025u @@ -69,6 +69,6 @@ define Device/huawei_hg556a-b CFE_BOARD_ID := HW556 CFE_EXTRAS += --rsa-signature "EchoLife_HG556a" --tag-version 8 BLOCKSIZE := 0x20000 - DEVICE_PACKAGES += $(USB2_PACKAGES) + DEVICE_PACKAGES += $(USB2_PACKAGES) $(ATH9K_PACKAGES) endef TARGET_DEVICES += huawei_hg556a-b diff --git a/target/linux/bmips/image/bcm63xx_nand.mk b/target/linux/bmips/image/bcm63xx_nand.mk index a712cd0699..82b04891d5 100644 --- a/target/linux/bmips/image/bcm63xx_nand.mk +++ b/target/linux/bmips/image/bcm63xx_nand.mk @@ -74,7 +74,7 @@ define Device/netgear_dgnd3700-v2 CFE_RAM_JFFS2_PAD := 496k BLOCKSIZE := 16k PAGESIZE := 512 - DEVICE_PACKAGES += $(USB2_PACKAGES) + DEVICE_PACKAGES += $(USB2_PACKAGES) $(B43_PACKAGES) CFE_WFI_FLASH_TYPE := 2 CFE_WFI_VERSION := 0x5731 endef diff --git a/target/linux/bmips/patches-5.10/010-v5.11-net-dsa-implement-a-central-TX-reallocation-procedur.patch b/target/linux/bmips/patches-5.10/010-v5.11-net-dsa-implement-a-central-TX-reallocation-procedur.patch deleted file mode 100644 index 4171a69d1d..0000000000 --- a/target/linux/bmips/patches-5.10/010-v5.11-net-dsa-implement-a-central-TX-reallocation-procedur.patch +++ /dev/null @@ -1,104 +0,0 @@ -From a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sun, 1 Nov 2020 21:16:09 +0200 -Subject: [PATCH] net: dsa: implement a central TX reallocation procedure - -At the moment, taggers are left with the task of ensuring that the skb -headers are writable (which they aren't, if the frames were cloned for -TX timestamping, for flooding by the bridge, etc), and that there is -enough space in the skb data area for the DSA tag to be pushed. - -Moreover, the life of tail taggers is even harder, because they need to -ensure that short frames have enough padding, a problem that normal -taggers don't have. - -The principle of the DSA framework is that everything except for the -most intimate hardware specifics (like in this case, the actual packing -of the DSA tag bits) should be done inside the core, to avoid having -code paths that are very rarely tested. - -So provide a TX reallocation procedure that should cover the known needs -of DSA today. - -Note that this patch also gives the network stack a good hint about the -headroom/tailroom it's going to need. Up till now it wasn't doing that. -So the reallocation procedure should really be there only for the -exceptional cases, and for cloned packets which need to be unshared. - -Signed-off-by: Vladimir Oltean -Tested-by: Christian Eggers # For tail taggers only -Tested-by: Kurt Kanzenbach -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - net/dsa/slave.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - ---- a/net/dsa/slave.c -+++ b/net/dsa/slave.c -@@ -548,6 +548,30 @@ netdev_tx_t dsa_enqueue_skb(struct sk_bu - } - EXPORT_SYMBOL_GPL(dsa_enqueue_skb); - -+static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev) -+{ -+ int needed_headroom = dev->needed_headroom; -+ int needed_tailroom = dev->needed_tailroom; -+ -+ /* For tail taggers, we need to pad short frames ourselves, to ensure -+ * that the tail tag does not fail at its role of being at the end of -+ * the packet, once the master interface pads the frame. Account for -+ * that pad length here, and pad later. -+ */ -+ if (unlikely(needed_tailroom && skb->len < ETH_ZLEN)) -+ needed_tailroom += ETH_ZLEN - skb->len; -+ /* skb_headroom() returns unsigned int... */ -+ needed_headroom = max_t(int, needed_headroom - skb_headroom(skb), 0); -+ needed_tailroom = max_t(int, needed_tailroom - skb_tailroom(skb), 0); -+ -+ if (likely(!needed_headroom && !needed_tailroom && !skb_cloned(skb))) -+ /* No reallocation needed, yay! */ -+ return 0; -+ -+ return pskb_expand_head(skb, needed_headroom, needed_tailroom, -+ GFP_ATOMIC); -+} -+ - static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct dsa_slave_priv *p = netdev_priv(dev); -@@ -567,6 +591,17 @@ static netdev_tx_t dsa_slave_xmit(struct - */ - dsa_skb_tx_timestamp(p, skb); - -+ if (dsa_realloc_skb(skb, dev)) { -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+ } -+ -+ /* needed_tailroom should still be 'warm' in the cache line from -+ * dsa_realloc_skb(), which has also ensured that padding is safe. -+ */ -+ if (dev->needed_tailroom) -+ eth_skb_pad(skb); -+ - /* Transmit function may have to reallocate the original SKB, - * in which case it must have freed it. Only free it here on error. - */ -@@ -1825,6 +1860,16 @@ int dsa_slave_create(struct dsa_port *po - slave_dev->netdev_ops = &dsa_slave_netdev_ops; - if (ds->ops->port_max_mtu) - slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index); -+ if (cpu_dp->tag_ops->tail_tag) -+ slave_dev->needed_tailroom = cpu_dp->tag_ops->overhead; -+ else -+ slave_dev->needed_headroom = cpu_dp->tag_ops->overhead; -+ /* Try to save one extra realloc later in the TX path (in the master) -+ * by also inheriting the master's needed headroom and tailroom. -+ * The 8021q driver also does this. -+ */ -+ slave_dev->needed_headroom += master->needed_headroom; -+ slave_dev->needed_tailroom += master->needed_tailroom; - SET_NETDEV_DEVTYPE(slave_dev, &dsa_type); - - netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one, diff --git a/target/linux/bmips/patches-5.10/049-v5.13-net-dsa-tag_brcm-add-support-for-legacy-tags.patch b/target/linux/bmips/patches-5.10/049-v5.13-net-dsa-tag_brcm-add-support-for-legacy-tags.patch index a9b689ca9c..c689bc84d1 100644 --- a/target/linux/bmips/patches-5.10/049-v5.13-net-dsa-tag_brcm-add-support-for-legacy-tags.patch +++ b/target/linux/bmips/patches-5.10/049-v5.13-net-dsa-tag_brcm-add-support-for-legacy-tags.patch @@ -80,7 +80,7 @@ Signed-off-by: David S. Miller #define BRCM_TAG_LEN 4 /* Tag is constructed and desconstructed using byte by byte access -@@ -197,6 +214,87 @@ DSA_TAG_DRIVER(brcm_netdev_ops); +@@ -194,6 +211,87 @@ DSA_TAG_DRIVER(brcm_netdev_ops); MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM); #endif @@ -168,7 +168,7 @@ Signed-off-by: David S. Miller #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND) static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb, struct net_device *dev) -@@ -229,6 +327,9 @@ static struct dsa_tag_driver *dsa_tag_dr +@@ -226,6 +324,9 @@ static struct dsa_tag_driver *dsa_tag_dr #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM) &DSA_TAG_DRIVER_NAME(brcm_netdev_ops), #endif diff --git a/target/linux/bmips/patches-5.10/050-v5.13-net-dsa-b53-support-legacy-tags.patch b/target/linux/bmips/patches-5.10/050-v5.13-net-dsa-b53-support-legacy-tags.patch index 59a7217663..269c2895af 100644 --- a/target/linux/bmips/patches-5.10/050-v5.13-net-dsa-b53-support-legacy-tags.patch +++ b/target/linux/bmips/patches-5.10/050-v5.13-net-dsa-b53-support-legacy-tags.patch @@ -28,7 +28,7 @@ Signed-off-by: David S. Miller This driver adds support for Broadcom managed switch chips. It supports --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c -@@ -2010,15 +2010,17 @@ enum dsa_tag_protocol b53_get_tag_protoc +@@ -2028,15 +2028,17 @@ enum dsa_tag_protocol b53_get_tag_protoc { struct b53_device *dev = ds->priv; diff --git a/target/linux/bmips/patches-5.10/204-wdt-bcm7038-add-big-endian-compatibility.patch b/target/linux/bmips/patches-5.10/120-wdt-bcm7038-add-big-endian-compatibility.patch similarity index 100% rename from target/linux/bmips/patches-5.10/204-wdt-bcm7038-add-big-endian-compatibility.patch rename to target/linux/bmips/patches-5.10/120-wdt-bcm7038-add-big-endian-compatibility.patch diff --git a/target/linux/bmips/patches-5.10/208-mips-bmips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch b/target/linux/bmips/patches-5.10/202-mips-bmips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch similarity index 100% rename from target/linux/bmips/patches-5.10/208-mips-bmips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch rename to target/linux/bmips/patches-5.10/202-mips-bmips-disable-ARCH_HAS_SYNC_DMA_FOR_CPU_ALL.patch diff --git a/target/linux/bmips/patches-5.10/300-usb-host-generic-ehci-ignore-oc-device-tree.patch b/target/linux/bmips/patches-5.10/300-usb-host-generic-ehci-ignore-oc-device-tree.patch deleted file mode 100644 index e65dbd9027..0000000000 --- a/target/linux/bmips/patches-5.10/300-usb-host-generic-ehci-ignore-oc-device-tree.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/drivers/usb/host/ehci-platform.c -+++ b/drivers/usb/host/ehci-platform.c -@@ -286,6 +286,9 @@ static int ehci_platform_probe(struct pl - if (of_property_read_bool(dev->dev.of_node, "big-endian")) - ehci->big_endian_mmio = ehci->big_endian_desc = 1; - -+ if (of_property_read_bool(dev->dev.of_node, "ignore-oc")) -+ ehci->ignore_oc = 1; -+ - if (of_property_read_bool(dev->dev.of_node, - "needs-reset-on-resume")) - priv->reset_on_resume = true; diff --git a/target/linux/bmips/patches-5.10/503-net-broadcom-add-BCM6368-enetsw-controller-driver.patch b/target/linux/bmips/patches-5.10/500-net-broadcom-add-BCM6368-enetsw-controller-driver.patch similarity index 100% rename from target/linux/bmips/patches-5.10/503-net-broadcom-add-BCM6368-enetsw-controller-driver.patch rename to target/linux/bmips/patches-5.10/500-net-broadcom-add-BCM6368-enetsw-controller-driver.patch diff --git a/target/linux/bmips/patches-5.10/505-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch b/target/linux/bmips/patches-5.10/510-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch similarity index 91% rename from target/linux/bmips/patches-5.10/505-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch rename to target/linux/bmips/patches-5.10/510-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch index f5bc8807b1..0b69f45360 100644 --- a/target/linux/bmips/patches-5.10/505-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch +++ b/target/linux/bmips/patches-5.10/510-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch @@ -13,7 +13,7 @@ Signed-off-by: Álvaro Fernández Rojas --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c -@@ -1140,6 +1140,36 @@ static void b53_force_port_config(struct +@@ -1155,6 +1155,36 @@ static void b53_force_port_config(struct b53_write8(dev, B53_CTRL_PAGE, off, reg); } @@ -50,7 +50,7 @@ Signed-off-by: Álvaro Fernández Rojas static void b53_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phydev) { -@@ -1166,6 +1196,9 @@ static void b53_adjust_link(struct dsa_s +@@ -1181,6 +1211,9 @@ static void b53_adjust_link(struct dsa_s tx_pause, rx_pause); b53_force_link(dev, port, phydev->link); @@ -60,7 +60,7 @@ Signed-off-by: Álvaro Fernández Rojas if (is531x5(dev) && phy_interface_is_rgmii(phydev)) { if (port == 8) off = B53_RGMII_CTRL_IMP; -@@ -1358,6 +1391,9 @@ void b53_phylink_mac_link_up(struct dsa_ +@@ -1373,6 +1406,9 @@ void b53_phylink_mac_link_up(struct dsa_ { struct b53_device *dev = ds->priv; diff --git a/target/linux/bmips/patches-5.10/600-mips-bmips-add-pci-support.patch b/target/linux/bmips/patches-5.10/600-mips-bmips-add-pci-support.patch new file mode 100644 index 0000000000..b4e7b7cfca --- /dev/null +++ b/target/linux/bmips/patches-5.10/600-mips-bmips-add-pci-support.patch @@ -0,0 +1,20 @@ +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -262,6 +262,7 @@ config BMIPS_GENERIC + select BCM7038_L1_IRQ + select BCM7120_L2_IRQ + select BRCMSTB_L2_IRQ ++ select HAVE_PCI + select IRQ_MIPS_CPU + select DMA_NONCOHERENT + select SYS_SUPPORTS_32BIT_KERNEL +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -28,6 +28,7 @@ obj-$(CONFIG_PCI_XTALK_BRIDGE) += pci-xt + # These are still pretty much in the old state, watch, go blind. + # + obj-$(CONFIG_ATH79) += fixup-ath79.o ++obj-$(CONFIG_BMIPS_GENERIC) += fixup-bmips.o + obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o + obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o + obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o diff --git a/target/linux/bmips/patches-5.10/601-pci-controllers-add-bcm6328-pcie-support.patch b/target/linux/bmips/patches-5.10/601-pci-controllers-add-bcm6328-pcie-support.patch new file mode 100644 index 0000000000..d7e2fe113e --- /dev/null +++ b/target/linux/bmips/patches-5.10/601-pci-controllers-add-bcm6328-pcie-support.patch @@ -0,0 +1,22 @@ +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -3,6 +3,11 @@ + menu "PCI controller drivers" + depends on PCI + ++config PCIE_BCM6328 ++ bool "BCM6328 PCIe controller" ++ depends on BMIPS_GENERIC || COMPILE_TEST ++ depends on OF ++ + config PCI_MVEBU + bool "Marvell EBU PCIe controller" + depends on ARCH_MVEBU || ARCH_DOVE || COMPILE_TEST +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 ++obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o + obj-$(CONFIG_PCIE_CADENCE) += cadence/ + obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o + obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o diff --git a/target/linux/bmips/patches-5.10/602-pci-controllers-add-bcm6318-pcie-support.patch b/target/linux/bmips/patches-5.10/602-pci-controllers-add-bcm6318-pcie-support.patch new file mode 100644 index 0000000000..3674028aec --- /dev/null +++ b/target/linux/bmips/patches-5.10/602-pci-controllers-add-bcm6318-pcie-support.patch @@ -0,0 +1,22 @@ +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -3,6 +3,11 @@ + menu "PCI controller drivers" + depends on PCI + ++config PCIE_BCM6318 ++ bool "BCM6318 PCIe controller" ++ depends on BMIPS_GENERIC || COMPILE_TEST ++ depends on OF ++ + config PCIE_BCM6328 + bool "BCM6328 PCIe controller" + depends on BMIPS_GENERIC || COMPILE_TEST +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 ++obj-$(CONFIG_PCIE_BCM6318) += pcie-bcm6318.o + obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o + obj-$(CONFIG_PCIE_CADENCE) += cadence/ + obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o diff --git a/target/linux/bmips/patches-5.10/603-pci-controllers-add-bcm6348-pci-support.patch b/target/linux/bmips/patches-5.10/603-pci-controllers-add-bcm6348-pci-support.patch new file mode 100644 index 0000000000..c0572604ee --- /dev/null +++ b/target/linux/bmips/patches-5.10/603-pci-controllers-add-bcm6348-pci-support.patch @@ -0,0 +1,22 @@ +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -3,6 +3,11 @@ + menu "PCI controller drivers" + depends on PCI + ++config PCI_BCM6348 ++ bool "BCM6348 PCI controller" ++ depends on BMIPS_GENERIC || COMPILE_TEST ++ depends on OF ++ + config PCIE_BCM6318 + bool "BCM6318 PCIe controller" + depends on BMIPS_GENERIC || COMPILE_TEST +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 ++obj-$(CONFIG_PCI_BCM6348) += pci-bcm6348.o + obj-$(CONFIG_PCIE_BCM6318) += pcie-bcm6318.o + obj-$(CONFIG_PCIE_BCM6328) += pcie-bcm6328.o + obj-$(CONFIG_PCIE_CADENCE) += cadence/ diff --git a/target/linux/bmips/patches-5.10/610-mips-bmips-add-pci-fixups.patch b/target/linux/bmips/patches-5.10/610-mips-bmips-add-pci-fixups.patch new file mode 100644 index 0000000000..5f68308986 --- /dev/null +++ b/target/linux/bmips/patches-5.10/610-mips-bmips-add-pci-fixups.patch @@ -0,0 +1,6 @@ +--- a/arch/mips/bmips/Makefile ++++ b/arch/mips/bmips/Makefile +@@ -1,2 +1,3 @@ + # SPDX-License-Identifier: GPL-2.0-only + obj-y += setup.o irq.o dma.o ++obj-y += ath9k-fixup.o b43-sprom.o diff --git a/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch b/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch index e4fd9eb2e4..ecb81004cb 100644 --- a/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch +++ b/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch @@ -25,7 +25,7 @@ Signed-off-by: Jakub Kicinski --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2030,7 +2030,9 @@ static void dsa_slave_switchdev_event_wo +@@ -2075,7 +2075,9 @@ static void dsa_slave_switchdev_event_wo err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid); if (err) { @@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski break; } fdb_info->offloaded = true; -@@ -2045,9 +2047,11 @@ static void dsa_slave_switchdev_event_wo +@@ -2090,9 +2092,11 @@ static void dsa_slave_switchdev_event_wo err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid); if (err) { diff --git a/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch b/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch index 31502f5b23..bb943f1312 100644 --- a/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch +++ b/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch @@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski struct sk_buff * (*xmit)(struct sk_buff *skb, --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2005,76 +2005,66 @@ static int dsa_slave_netdevice_event(str +@@ -2050,76 +2050,66 @@ static int dsa_slave_netdevice_event(str return NOTIFY_DONE; } @@ -167,7 +167,7 @@ Signed-off-by: Jakub Kicinski } /* Called under rcu_read_lock() */ -@@ -2082,7 +2072,9 @@ static int dsa_slave_switchdev_event(str +@@ -2127,7 +2117,9 @@ static int dsa_slave_switchdev_event(str unsigned long event, void *ptr) { struct net_device *dev = switchdev_notifier_info_to_dev(ptr); @@ -177,7 +177,7 @@ Signed-off-by: Jakub Kicinski int err; if (event == SWITCHDEV_PORT_ATTR_SET) { -@@ -2095,20 +2087,32 @@ static int dsa_slave_switchdev_event(str +@@ -2140,20 +2132,32 @@ static int dsa_slave_switchdev_event(str if (!dsa_slave_dev_check(dev)) return NOTIFY_DONE; @@ -213,7 +213,7 @@ Signed-off-by: Jakub Kicinski dev_hold(dev); break; default: -@@ -2118,10 +2122,6 @@ static int dsa_slave_switchdev_event(str +@@ -2163,10 +2167,6 @@ static int dsa_slave_switchdev_event(str dsa_schedule_work(&switchdev_work->work); return NOTIFY_OK; diff --git a/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch b/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch index 49e095a587..48c2af770b 100644 --- a/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch +++ b/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch @@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2077,31 +2077,29 @@ static int dsa_slave_switchdev_event(str +@@ -2122,31 +2122,29 @@ static int dsa_slave_switchdev_event(str struct dsa_port *dp; int err; @@ -68,7 +68,7 @@ Signed-off-by: Jakub Kicinski fdb_info = ptr; if (!fdb_info->added_by_user) { -@@ -2114,13 +2112,12 @@ static int dsa_slave_switchdev_event(str +@@ -2159,13 +2157,12 @@ static int dsa_slave_switchdev_event(str switchdev_work->vid = fdb_info->vid; dev_hold(dev); diff --git a/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch b/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch index cbf2739469..a1f56353ea 100644 --- a/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch +++ b/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch @@ -30,7 +30,7 @@ Signed-off-by: Jakub Kicinski --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2090,6 +2090,9 @@ static int dsa_slave_switchdev_event(str +@@ -2135,6 +2135,9 @@ static int dsa_slave_switchdev_event(str dp = dsa_slave_to_port(dev); diff --git a/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch b/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch index 978ece93b3..e576ff8ce2 100644 --- a/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch +++ b/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch @@ -170,7 +170,7 @@ Signed-off-by: Jakub Kicinski */ --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2067,6 +2067,28 @@ static void dsa_slave_switchdev_event_wo +@@ -2112,6 +2112,28 @@ static void dsa_slave_switchdev_event_wo dev_put(dp->slave); } @@ -199,7 +199,7 @@ Signed-off-by: Jakub Kicinski /* Called under rcu_read_lock() */ static int dsa_slave_switchdev_event(struct notifier_block *unused, unsigned long event, void *ptr) -@@ -2085,10 +2107,37 @@ static int dsa_slave_switchdev_event(str +@@ -2130,10 +2152,37 @@ static int dsa_slave_switchdev_event(str return notifier_from_errno(err); case SWITCHDEV_FDB_ADD_TO_DEVICE: case SWITCHDEV_FDB_DEL_TO_DEVICE: @@ -240,7 +240,7 @@ Signed-off-by: Jakub Kicinski if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del) return NOTIFY_DONE; -@@ -2103,18 +2152,13 @@ static int dsa_slave_switchdev_event(str +@@ -2148,18 +2197,13 @@ static int dsa_slave_switchdev_event(str switchdev_work->port = dp->index; switchdev_work->event = event; diff --git a/target/linux/generic/pending-5.10/110-ehci_hcd_ignore_oc.patch b/target/linux/generic/backport-5.10/810-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch similarity index 69% rename from target/linux/generic/pending-5.10/110-ehci_hcd_ignore_oc.patch rename to target/linux/generic/backport-5.10/810-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch index 138d4fa1c5..8f2021a0fc 100644 --- a/target/linux/generic/pending-5.10/110-ehci_hcd_ignore_oc.patch +++ b/target/linux/generic/backport-5.10/810-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch @@ -1,5 +1,11 @@ +From 2d5ba37461013253d2ff0a3641b727fd32ea97a9 Mon Sep 17 00:00:00 2001 From: Florian Fainelli -Subject: USB: EHCI: add ignore_oc flag to disable overcurrent checking +Date: Tue, 23 Feb 2021 18:44:53 +0100 +Subject: [PATCH 1/3] usb: ehci: add spurious flag to disable overcurrent + checking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit This patch adds an ignore_oc flag which can be set by EHCI controller not supporting or wanting to disable overcurrent checking. The EHCI @@ -7,13 +13,16 @@ platform data in include/linux/usb/ehci_pdriver.h is also augmented to take advantage of this new flag. Signed-off-by: Florian Fainelli +Signed-off-by: Álvaro Fernández Rojas +Link: https://lore.kernel.org/r/20210223174455.1378-2-noltari@gmail.com +Signed-off-by: Greg Kroah-Hartman --- - drivers/usb/host/ehci-hcd.c | 2 +- - drivers/usb/host/ehci-hub.c | 4 ++-- - drivers/usb/host/ehci-platform.c | 1 + - drivers/usb/host/ehci.h | 1 + - include/linux/usb/ehci_pdriver.h | 1 + - 5 files changed, 6 insertions(+), 3 deletions(-) + drivers/usb/host/ehci-hcd.c | 2 +- + drivers/usb/host/ehci-hub.c | 4 ++-- + drivers/usb/host/ehci-platform.c | 2 ++ + drivers/usb/host/ehci.h | 1 + + include/linux/usb/ehci_pdriver.h | 1 + + 5 files changed, 7 insertions(+), 3 deletions(-) --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -22,7 +31,7 @@ Signed-off-by: Florian Fainelli ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), temp >> 8, temp & 0xff, - ignore_oc ? ", overcurrent ignored" : ""); -+ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : ""); ++ (ignore_oc || ehci->spurious_oc) ? ", overcurrent ignored" : ""); ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ @@ -33,7 +42,7 @@ Signed-off-by: Florian Fainelli * PORT_POWER; that's surprising, but maybe within-spec. */ - if (!ignore_oc) -+ if (!ignore_oc && !ehci->ignore_oc) ++ if (!ignore_oc && !ehci->spurious_oc) mask = PORT_CSC | PORT_PEC | PORT_OCC; else mask = PORT_CSC | PORT_PEC; @@ -42,7 +51,7 @@ Signed-off-by: Florian Fainelli status |= USB_PORT_STAT_C_ENABLE << 16; - if ((temp & PORT_OCC) && !ignore_oc){ -+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){ ++ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){ status |= USB_PORT_STAT_C_OVERCURRENT << 16; /* @@ -52,8 +61,8 @@ Signed-off-by: Florian Fainelli hcd->has_tt = 1; if (pdata->reset_on_resume) priv->reset_on_resume = true; -+ if (pdata->ignore_oc) -+ ehci->ignore_oc = 1; ++ if (pdata->spurious_oc) ++ ehci->spurious_oc = 1; #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO if (ehci->big_endian_mmio) { @@ -63,7 +72,7 @@ Signed-off-by: Florian Fainelli unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ -+ unsigned ignore_oc:1; ++ unsigned spurious_oc:1; /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) @@ -73,7 +82,7 @@ Signed-off-by: Florian Fainelli unsigned no_io_watchdog:1; unsigned reset_on_resume:1; unsigned dma_mask_64:1; -+ unsigned ignore_oc:1; ++ unsigned spurious_oc:1; /* Turn on all power and clocks */ int (*power_on)(struct platform_device *pdev); diff --git a/target/linux/generic/backport-5.10/811-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch b/target/linux/generic/backport-5.10/811-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch new file mode 100644 index 0000000000..0094d47718 --- /dev/null +++ b/target/linux/generic/backport-5.10/811-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch @@ -0,0 +1,31 @@ +From 4da57dbbffdfa7fe4e2b70b047fc5ff95ff25a3d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Tue, 23 Feb 2021 18:44:55 +0100 +Subject: [PATCH 3/3] usb: host: ehci-platform: add spurious_oc DT support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Over-current reporting isn't supported on some platforms such as bcm63xx. +These devices will incorrectly report over-current if this flag isn't properly +activated. + +Signed-off-by: Álvaro Fernández Rojas +Link: https://lore.kernel.org/r/20210223174455.1378-4-noltari@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/ehci-platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/ehci-platform.c ++++ b/drivers/usb/host/ehci-platform.c +@@ -286,6 +286,9 @@ static int ehci_platform_probe(struct pl + if (of_property_read_bool(dev->dev.of_node, "big-endian")) + ehci->big_endian_mmio = ehci->big_endian_desc = 1; + ++ if (of_property_read_bool(dev->dev.of_node, "spurious-oc")) ++ ehci->spurious_oc = 1; ++ + if (of_property_read_bool(dev->dev.of_node, + "needs-reset-on-resume")) + priv->reset_on_resume = true; diff --git a/target/linux/generic/pending-5.4/110-ehci_hcd_ignore_oc.patch b/target/linux/generic/backport-5.4/850-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch similarity index 69% rename from target/linux/generic/pending-5.4/110-ehci_hcd_ignore_oc.patch rename to target/linux/generic/backport-5.4/850-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch index ce583ceac5..bda1d1df36 100644 --- a/target/linux/generic/pending-5.4/110-ehci_hcd_ignore_oc.patch +++ b/target/linux/generic/backport-5.4/850-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch @@ -1,5 +1,11 @@ +From 2d5ba37461013253d2ff0a3641b727fd32ea97a9 Mon Sep 17 00:00:00 2001 From: Florian Fainelli -Subject: USB: EHCI: add ignore_oc flag to disable overcurrent checking +Date: Tue, 23 Feb 2021 18:44:53 +0100 +Subject: [PATCH 1/3] usb: ehci: add spurious flag to disable overcurrent + checking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit This patch adds an ignore_oc flag which can be set by EHCI controller not supporting or wanting to disable overcurrent checking. The EHCI @@ -7,13 +13,16 @@ platform data in include/linux/usb/ehci_pdriver.h is also augmented to take advantage of this new flag. Signed-off-by: Florian Fainelli +Signed-off-by: Álvaro Fernández Rojas +Link: https://lore.kernel.org/r/20210223174455.1378-2-noltari@gmail.com +Signed-off-by: Greg Kroah-Hartman --- - drivers/usb/host/ehci-hcd.c | 2 +- - drivers/usb/host/ehci-hub.c | 4 ++-- - drivers/usb/host/ehci-platform.c | 1 + - drivers/usb/host/ehci.h | 1 + - include/linux/usb/ehci_pdriver.h | 1 + - 5 files changed, 6 insertions(+), 3 deletions(-) + drivers/usb/host/ehci-hcd.c | 2 +- + drivers/usb/host/ehci-hub.c | 4 ++-- + drivers/usb/host/ehci-platform.c | 2 ++ + drivers/usb/host/ehci.h | 1 + + include/linux/usb/ehci_pdriver.h | 1 + + 5 files changed, 7 insertions(+), 3 deletions(-) --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -22,7 +31,7 @@ Signed-off-by: Florian Fainelli ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), temp >> 8, temp & 0xff, - ignore_oc ? ", overcurrent ignored" : ""); -+ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : ""); ++ (ignore_oc || ehci->spurious_oc) ? ", overcurrent ignored" : ""); ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ @@ -33,7 +42,7 @@ Signed-off-by: Florian Fainelli * PORT_POWER; that's surprising, but maybe within-spec. */ - if (!ignore_oc) -+ if (!ignore_oc && !ehci->ignore_oc) ++ if (!ignore_oc && !ehci->spurious_oc) mask = PORT_CSC | PORT_PEC | PORT_OCC; else mask = PORT_CSC | PORT_PEC; @@ -42,7 +51,7 @@ Signed-off-by: Florian Fainelli status |= USB_PORT_STAT_C_ENABLE << 16; - if ((temp & PORT_OCC) && !ignore_oc){ -+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){ ++ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){ status |= USB_PORT_STAT_C_OVERCURRENT << 16; /* @@ -52,8 +61,8 @@ Signed-off-by: Florian Fainelli hcd->has_tt = 1; if (pdata->reset_on_resume) priv->reset_on_resume = true; -+ if (pdata->ignore_oc) -+ ehci->ignore_oc = 1; ++ if (pdata->spurious_oc) ++ ehci->spurious_oc = 1; #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO if (ehci->big_endian_mmio) { @@ -63,7 +72,7 @@ Signed-off-by: Florian Fainelli unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ -+ unsigned ignore_oc:1; ++ unsigned spurious_oc:1; /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) @@ -73,7 +82,7 @@ Signed-off-by: Florian Fainelli unsigned no_io_watchdog:1; unsigned reset_on_resume:1; unsigned dma_mask_64:1; -+ unsigned ignore_oc:1; ++ unsigned spurious_oc:1; /* Turn on all power and clocks */ int (*power_on)(struct platform_device *pdev); diff --git a/target/linux/generic/backport-5.4/851-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch b/target/linux/generic/backport-5.4/851-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch new file mode 100644 index 0000000000..6faefeb79c --- /dev/null +++ b/target/linux/generic/backport-5.4/851-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch @@ -0,0 +1,31 @@ +From 4da57dbbffdfa7fe4e2b70b047fc5ff95ff25a3d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Tue, 23 Feb 2021 18:44:55 +0100 +Subject: [PATCH 3/3] usb: host: ehci-platform: add spurious_oc DT support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Over-current reporting isn't supported on some platforms such as bcm63xx. +These devices will incorrectly report over-current if this flag isn't properly +activated. + +Signed-off-by: Álvaro Fernández Rojas +Link: https://lore.kernel.org/r/20210223174455.1378-4-noltari@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/ehci-platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/ehci-platform.c ++++ b/drivers/usb/host/ehci-platform.c +@@ -278,6 +278,9 @@ static int ehci_platform_probe(struct pl + if (of_property_read_bool(dev->dev.of_node, "big-endian")) + ehci->big_endian_mmio = ehci->big_endian_desc = 1; + ++ if (of_property_read_bool(dev->dev.of_node, "spurious-oc")) ++ ehci->spurious_oc = 1; ++ + if (of_property_read_bool(dev->dev.of_node, + "needs-reset-on-resume")) + priv->reset_on_resume = true; diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c index 5c8a5e1b9b..a3474c9dc2 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c @@ -17,7 +17,7 @@ #define je16_to_cpu(x) ((x).v16) #define je32_to_cpu(x) ((x).v32) -#define NR_PARTS 1 +#define NR_PARTS 2 static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd, const struct mtd_partition **pparts, @@ -58,12 +58,16 @@ static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd, if (!parts) return -ENOMEM; + parts[0].name = "bootfs"; + parts[0].offset = 0; + parts[0].size = rootfs_offset; + if (type == MTDSPLIT_PART_TYPE_UBI) - parts[0].name = UBI_PART_NAME; + parts[1].name = UBI_PART_NAME; else - parts[0].name = ROOTFS_PART_NAME; - parts[0].offset = rootfs_offset; - parts[0].size = mtd->size - rootfs_offset; + parts[1].name = ROOTFS_PART_NAME; + parts[1].offset = rootfs_offset; + parts[1].size = mtd->size - rootfs_offset; *pparts = parts; diff --git a/target/linux/generic/hack-5.10/204-module_strip.patch b/target/linux/generic/hack-5.10/204-module_strip.patch index 2a162600fc..06159b0120 100644 --- a/target/linux/generic/hack-5.10/204-module_strip.patch +++ b/target/linux/generic/hack-5.10/204-module_strip.patch @@ -104,7 +104,7 @@ Signed-off-by: Felix Fietkau config MODULES_TREE_LOOKUP --- a/kernel/module.c +++ b/kernel/module.c -@@ -3161,9 +3161,11 @@ static int setup_load_info(struct load_i +@@ -3243,9 +3243,11 @@ static int setup_load_info(struct load_i static int check_modinfo(struct module *mod, struct load_info *info, int flags) { @@ -117,7 +117,7 @@ Signed-off-by: Felix Fietkau if (flags & MODULE_INIT_IGNORE_VERMAGIC) modmagic = NULL; -@@ -3184,6 +3186,7 @@ static int check_modinfo(struct module * +@@ -3266,6 +3268,7 @@ static int check_modinfo(struct module * mod->name); add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); } diff --git a/target/linux/generic/hack-5.10/902-debloat_proc.patch b/target/linux/generic/hack-5.10/902-debloat_proc.patch index 5a6d7d058e..3208e5554f 100644 --- a/target/linux/generic/hack-5.10/902-debloat_proc.patch +++ b/target/linux/generic/hack-5.10/902-debloat_proc.patch @@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau --- a/fs/locks.c +++ b/fs/locks.c -@@ -2996,6 +2996,8 @@ static const struct seq_operations locks +@@ -2993,6 +2993,8 @@ static const struct seq_operations locks static int __init proc_locks_init(void) { diff --git a/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch index 4e83b98724..c0482dfee5 100644 --- a/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +++ b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch @@ -71,7 +71,7 @@ Signed-off-by: Tobias Wolf --- a/mm/page_alloc.c +++ b/mm/page_alloc.c -@@ -6951,7 +6951,7 @@ static void __ref alloc_node_mem_map(str +@@ -7026,7 +7026,7 @@ static void __ref alloc_node_mem_map(str if (pgdat == NODE_DATA(0)) { mem_map = NODE_DATA(0)->node_mem_map; if (page_to_pfn(mem_map) != pgdat->node_start_pfn) diff --git a/target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch b/target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch index c8f0a32dd9..0b85742290 100644 --- a/target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch +++ b/target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch @@ -28,7 +28,7 @@ Add .ndo_fill_forward_path for dsa slave port devices --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -1582,6 +1582,21 @@ static struct devlink_port *dsa_slave_ge +@@ -1617,6 +1617,21 @@ static struct devlink_port *dsa_slave_ge return dp->ds->devlink ? &dp->devlink_port : NULL; } @@ -50,7 +50,7 @@ Add .ndo_fill_forward_path for dsa slave port devices static const struct net_device_ops dsa_slave_netdev_ops = { .ndo_open = dsa_slave_open, .ndo_stop = dsa_slave_close, -@@ -1607,6 +1622,7 @@ static const struct net_device_ops dsa_s +@@ -1642,6 +1657,7 @@ static const struct net_device_ops dsa_s .ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid, .ndo_get_devlink_port = dsa_slave_get_devlink_port, .ndo_change_mtu = dsa_slave_change_mtu, diff --git a/target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch b/target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch index 58a2064c03..4dade26f60 100644 --- a/target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch +++ b/target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch @@ -17,7 +17,7 @@ Signed-off-by: Pablo Neira Ayuso --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -1202,14 +1202,32 @@ static int dsa_slave_setup_tc_block(stru +@@ -1237,14 +1237,32 @@ static int dsa_slave_setup_tc_block(stru } } diff --git a/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch index ec77d59cf0..69b82c2635 100644 --- a/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ b/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1644,6 +1644,9 @@ void phy_detach(struct phy_device *phyde +@@ -1642,6 +1642,9 @@ void phy_detach(struct phy_device *phyde struct module *ndev_owner = NULL; struct mii_bus *bus; diff --git a/target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch b/target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch index 9246d1fa40..c86a854212 100644 --- a/target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch +++ b/target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch @@ -18,7 +18,7 @@ Signed-off-by: Tobias Waldekranz --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2144,10 +2144,12 @@ static int dsa_slave_switchdev_event(str +@@ -2189,10 +2189,12 @@ static int dsa_slave_switchdev_event(str fdb_info = ptr; if (dsa_slave_dev_check(dev)) { diff --git a/target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch b/target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch index 77f0dca252..bf356422de 100644 --- a/target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch +++ b/target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch @@ -15,7 +15,7 @@ Signed-off-by: Tobias Waldekranz --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2158,7 +2158,11 @@ static int dsa_slave_switchdev_event(str +@@ -2203,7 +2203,11 @@ static int dsa_slave_switchdev_event(str struct net_device *br_dev; struct dsa_slave_priv *p; diff --git a/target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch b/target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch index 39271108ec..84ad38f6eb 100644 --- a/target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch +++ b/target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch @@ -28,7 +28,7 @@ Signed-off-by: Tobias Waldekranz --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -2151,9 +2151,12 @@ static int dsa_slave_switchdev_event(str +@@ -2196,9 +2196,12 @@ static int dsa_slave_switchdev_event(str else if (!fdb_info->added_by_user) return NOTIFY_OK; } else { @@ -44,7 +44,7 @@ Signed-off-by: Tobias Waldekranz */ struct net_device *br_dev; struct dsa_slave_priv *p; -@@ -2175,7 +2178,8 @@ static int dsa_slave_switchdev_event(str +@@ -2220,7 +2223,8 @@ static int dsa_slave_switchdev_event(str dp = p->dp->cpu_dp; diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk index 88d71600b2..143db964db 100644 --- a/target/linux/mediatek/image/mt7622.mk +++ b/target/linux/mediatek/image/mt7622.mk @@ -75,12 +75,17 @@ define Device/bananapi_bpi-r64 DEVICE_DTS := mt7622-bananapi-bpi-r64 DEVICE_DTS_OVERLAY := mt7622-bananapi-bpi-r64-pcie1 mt7622-bananapi-bpi-r64-sata DEVICE_PACKAGES := kmod-ata-ahci-mtk kmod-btmtkuart kmod-usb3 e2fsprogs mkf2fs f2fsck - ARTIFACTS := sdcard.img + ARTIFACTS := sdcard.img.gz IMAGES := sysupgrade.itb KERNEL_INITRAMFS_SUFFIX := -recovery.itb - ARTIFACT/sdcard.img := mt7622-gpt sdmmc | pad-to 128k | mt7622-gpt emmc | pad-to 256k |\ - bl2 emmc-2ddr | pad-to 512k | bl2 sdmmc-2ddr | pad-to 1024k | bl31-uboot bananapi_bpi-r64-emmc | pad-to 2048k |\ - bl31-uboot bananapi_bpi-r64-sdmmc | pad-to 6144k + ARTIFACT/sdcard.img.gz := mt7622-gpt sdmmc |\ + pad-to 128k | mt7622-gpt emmc |\ + pad-to 256k | bl2 emmc-2ddr |\ + pad-to 512k | bl2 sdmmc-2ddr |\ + pad-to 1024k | bl31-uboot bananapi_bpi-r64-emmc |\ + pad-to 2048k | bl31-uboot bananapi_bpi-r64-sdmmc |\ + pad-to 6144k | append-image initramfs-recovery.itb |\ + pad-to 40960k | append-image squashfs-sysupgrade.itb | gzip KERNEL := kernel-bin | gzip KERNEL_INITRAMFS := kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb with-initrd | pad-to 128k IMAGE/sysupgrade.itb := append-kernel | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb external-static-with-rootfs | append-metadata diff --git a/target/linux/ramips/dts/mt7620a_youku_yk1.dts b/target/linux/ramips/dts/mt7620a_youku_yk1.dts index 8727b011d4..3b84b07b8b 100644 --- a/target/linux/ramips/dts/mt7620a_youku_yk1.dts +++ b/target/linux/ramips/dts/mt7620a_youku_yk1.dts @@ -69,7 +69,7 @@ flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <25000000>; + spi-max-frequency = <80000000>; m25p,fast-read; partitions { diff --git a/target/linux/ramips/patches-5.10/720-Revert-net-phy-simplify-phy_link_change-arguments.patch b/target/linux/ramips/patches-5.10/720-Revert-net-phy-simplify-phy_link_change-arguments.patch index c53b11ea31..b0bdf374d9 100644 --- a/target/linux/ramips/patches-5.10/720-Revert-net-phy-simplify-phy_link_change-arguments.patch +++ b/target/linux/ramips/patches-5.10/720-Revert-net-phy-simplify-phy_link_change-arguments.patch @@ -33,7 +33,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c phy_led_trigger_change_speed(phydev); } -@@ -616,7 +616,7 @@ int phy_start_cable_test(struct phy_devi +@@ -618,7 +618,7 @@ int phy_start_cable_test(struct phy_devi goto out; /* Mark the carrier down until the test is complete */ @@ -42,7 +42,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c netif_testing_on(dev); err = phydev->drv->cable_test_start(phydev); -@@ -687,7 +687,7 @@ int phy_start_cable_test_tdr(struct phy_ +@@ -689,7 +689,7 @@ int phy_start_cable_test_tdr(struct phy_ goto out; /* Mark the carrier down until the test is complete */ @@ -51,7 +51,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c netif_testing_on(dev); err = phydev->drv->cable_test_tdr_start(phydev, config); -@@ -758,7 +758,7 @@ static int phy_check_link_status(struct +@@ -760,7 +760,7 @@ static int phy_check_link_status(struct phy_link_up(phydev); } else if (!phydev->link && phydev->state != PHY_NOLINK) { phydev->state = PHY_NOLINK; @@ -60,7 +60,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c } return 0; -@@ -1162,7 +1162,7 @@ void phy_state_machine(struct work_struc +@@ -1164,7 +1164,7 @@ void phy_state_machine(struct work_struc case PHY_HALTED: if (phydev->link) { phydev->link = 0; @@ -71,7 +71,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c break; --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -937,14 +937,16 @@ struct phy_device *phy_find_first(struct +@@ -935,14 +935,16 @@ struct phy_device *phy_find_first(struct } EXPORT_SYMBOL(phy_find_first); diff --git a/target/linux/ramips/patches-5.10/721-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-5.10/721-NET-no-auto-carrier-off-support.patch index 09170ab632..59041f0420 100644 --- a/target/linux/ramips/patches-5.10/721-NET-no-auto-carrier-off-support.patch +++ b/target/linux/ramips/patches-5.10/721-NET-no-auto-carrier-off-support.patch @@ -11,7 +11,7 @@ Signed-off-by: John Crispin --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c -@@ -758,7 +758,10 @@ static int phy_check_link_status(struct +@@ -760,7 +760,10 @@ static int phy_check_link_status(struct phy_link_up(phydev); } else if (!phydev->link && phydev->state != PHY_NOLINK) { phydev->state = PHY_NOLINK; @@ -23,7 +23,7 @@ Signed-off-by: John Crispin } return 0; -@@ -1162,7 +1165,10 @@ void phy_state_machine(struct work_struc +@@ -1164,7 +1167,10 @@ void phy_state_machine(struct work_struc case PHY_HALTED: if (phydev->link) { phydev->link = 0; diff --git a/target/linux/ramips/patches-5.10/800-GPIO-add-named-gpio-exports.patch b/target/linux/ramips/patches-5.10/800-GPIO-add-named-gpio-exports.patch index fe34f0b21b..09bad30109 100644 --- a/target/linux/ramips/patches-5.10/800-GPIO-add-named-gpio-exports.patch +++ b/target/linux/ramips/patches-5.10/800-GPIO-add-named-gpio-exports.patch @@ -141,7 +141,7 @@ Signed-off-by: John Crispin { --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h -@@ -713,6 +713,7 @@ static inline void devm_acpi_dev_remove_ +@@ -715,6 +715,7 @@ static inline void devm_acpi_dev_remove_ #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) @@ -149,7 +149,7 @@ Signed-off-by: John Crispin int gpiod_export(struct gpio_desc *desc, bool direction_may_change); int gpiod_export_link(struct device *dev, const char *name, struct gpio_desc *desc); -@@ -720,6 +721,13 @@ void gpiod_unexport(struct gpio_desc *de +@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ diff --git a/target/linux/realtek/image/Makefile b/target/linux/realtek/image/Makefile index d867d2a3d9..18e5fedb9b 100644 --- a/target/linux/realtek/image/Makefile +++ b/target/linux/realtek/image/Makefile @@ -6,6 +6,8 @@ include $(INCLUDE_DIR)/image.mk KERNEL_LOADADDR = 0x80000000 KERNEL_ENTRY = 0x80000400 +DEVICE_VARS += ZYXEL_VERS + define Build/zyxel-vers ( echo VERS;\ for hw in $(1); do\ diff --git a/target/linux/x86/patches-5.10/200-pcengines-apu2-reboot.patch b/target/linux/x86/patches-5.10/200-pcengines-apu2-reboot.patch deleted file mode 100644 index bc57806c74..0000000000 --- a/target/linux/x86/patches-5.10/200-pcengines-apu2-reboot.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/arch/x86/kernel/reboot.c -+++ b/arch/x86/kernel/reboot.c -@@ -477,6 +477,16 @@ static const struct dmi_system_id reboot - }, - }, - -+ /* PC Engines */ -+ { /* Handle problems with rebooting on PC Engines apu2 */ -+ .callback = set_pci_reboot, -+ .ident = "PC Engines apu2", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "PC Engines"), -+ DMI_MATCH(DMI_BOARD_NAME, "apu2"), -+ }, -+ }, -+ - /* Sony */ - { /* Handle problems with rebooting on Sony VGN-Z540N */ - .callback = set_bios_reboot, diff --git a/target/linux/x86/patches-5.4/200-pcengines-apu2-reboot.patch b/target/linux/x86/patches-5.4/200-pcengines-apu2-reboot.patch deleted file mode 100644 index 742b6d6ad5..0000000000 --- a/target/linux/x86/patches-5.4/200-pcengines-apu2-reboot.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/arch/x86/kernel/reboot.c -+++ b/arch/x86/kernel/reboot.c -@@ -486,6 +486,16 @@ static const struct dmi_system_id reboot - }, - }, - -+ /* PC Engines */ -+ { /* Handle problems with rebooting on PC Engines apu2 */ -+ .callback = set_pci_reboot, -+ .ident = "PC Engines apu2", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "PC Engines"), -+ DMI_MATCH(DMI_BOARD_NAME, "apu2"), -+ }, -+ }, -+ - /* Sony */ - { /* Handle problems with rebooting on Sony VGN-Z540N */ - .callback = set_bios_reboot, diff --git a/tools/firmware-utils/src/bcm4908img.c b/tools/firmware-utils/src/bcm4908img.c index 86a187b146..cb1913fdb1 100644 --- a/tools/firmware-utils/src/bcm4908img.c +++ b/tools/firmware-utils/src/bcm4908img.c @@ -27,12 +27,26 @@ #error "Unsupported endianness" #endif +#define WFI_VERSION 0x00005732 +#define WFI_VERSION_NAND_1MB_DATA 0x00005731 + +#define WFI_NOR_FLASH 1 +#define WFI_NAND16_FLASH 2 +#define WFI_NAND128_FLASH 3 +#define WFI_NAND256_FLASH 4 +#define WFI_NAND512_FLASH 5 +#define WFI_NAND1024_FLASH 6 +#define WFI_NAND2048_FLASH 7 + +#define WFI_FLAG_HAS_PMC 0x1 +#define WFI_FLAG_SUPPORTS_BTRM 0x2 + struct bcm4908img_tail { uint32_t crc32; - uint32_t unk1; - uint32_t family; - uint32_t unk2; - uint32_t unk3; + uint32_t version; + uint32_t chip_id; + uint32_t flash_type; + uint32_t flags; }; char *pathname; @@ -272,10 +286,10 @@ static ssize_t bcm4908img_create_align(FILE *trx, size_t cur_offset, size_t alig static int bcm4908img_create(int argc, char **argv) { struct bcm4908img_tail tail = { - .unk1 = cpu_to_le32(0x5732), - .family = cpu_to_le32(0x4908), - .unk2 = cpu_to_le32(0x03), - .unk3 = cpu_to_le32(0x02), + .version = cpu_to_le32(WFI_VERSION), + .chip_id = cpu_to_le32(0x4908), + .flash_type = cpu_to_le32(WFI_NAND128_FLASH), + .flags = cpu_to_le32(WFI_FLAG_SUPPORTS_BTRM), }; uint32_t crc32 = 0xffffffff; size_t cur_offset = 0; diff --git a/tools/firmware-utils/src/bcm4908kernel.c b/tools/firmware-utils/src/bcm4908kernel.c index fc5b2812ef..eaf04a0a48 100644 --- a/tools/firmware-utils/src/bcm4908kernel.c +++ b/tools/firmware-utils/src/bcm4908kernel.c @@ -27,11 +27,11 @@ #endif struct bcm4908kernel_header { - uint32_t unk1; - uint32_t unk2; - uint32_t length; + uint32_t boot_load_addr; /* AKA la_address */ + uint32_t boot_addr; /* AKA la_entrypt */ + uint32_t data_len; uint8_t magic[4]; - uint32_t unused; + uint32_t uncomplen; /* Empty for LZMA, used for LZ4 */ }; static void usage() { @@ -103,14 +103,14 @@ int main(int argc, char **argv) { length += bytes; } - header.unk1 = cpu_to_le32(0x00080000); - header.unk2 = cpu_to_le32(0x00080000); - header.length = cpu_to_le32(length); + header.boot_load_addr = cpu_to_le32(0x00080000); + header.boot_addr = cpu_to_le32(0x00080000); + header.data_len = cpu_to_le32(length); header.magic[0] = 'B'; header.magic[1] = 'R'; header.magic[2] = 'C'; header.magic[3] = 'M'; - header.unused = 0; + header.uncomplen = 0; fseek(out, 0, SEEK_SET);