LINUX_RELEASE?=1
LINUX_VERSION-3.18 = .43
-LINUX_VERSION-4.4 = .52
+LINUX_VERSION-4.4 = .87
-LINUX_KERNEL_HASH-3.18.43 = f61362192b74424539f062a21aa7080f5d66fd8d4cfe2a38f33fab8889bf072c
-LINUX_KERNEL_HASH-4.4.52 = 0f1faafdae47da5f29e740ff655f91c2eb13c8cdfc4d039d903176bd56c2ecbb
+LINUX_KERNEL_HASH-3.18.43 = 1236e8123a6ce537d5029232560966feed054ae31776fe8481dd7d18cdd5492c
+LINUX_KERNEL_HASH-4.4.87 = f2e26505e3aecf622d4f4e1ede44b3b97a38739ad8b78ede14eb354f22d1387a
ifdef KERNEL_PATCHVER
LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER)))
$(curdir)/merge-index: $(curdir)/merge
(cd $(PACKAGE_DIR_ALL) && $(SCRIPT_DIR)/ipkg-make-index.sh . 2>&1 > Packages; )
-$(curdir)/install: $(TMP_DIR)/.build $(curdir)/system/opkg/host/install $(curdir)/merge $(if $(CONFIG_TARGET_PER_DEVICE_ROOTFS),$(curdir)/merge-index)
+$(curdir)/install: $(TMP_DIR)/.build $(curdir)/system/opkg/host/compile $(curdir)/merge $(if $(CONFIG_TARGET_PER_DEVICE_ROOTFS),$(curdir)/merge-index)
- find $(STAGING_DIR_ROOT) -type d | $(XARGS) chmod 0755
rm -rf $(TARGET_DIR) $(TARGET_DIR_ORIG)
[ -d $(TARGET_DIR)/tmp ] || mkdir -p $(TARGET_DIR)/tmp
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=u-boot
-PKG_VERSION:=2010.03-libre
+PKG_VERSION:=2010.03
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_HASH:=902d1b2c15787df55186fae4033685fb0c5a5a12755a08383e97c4a3e255925b
PKG_SOURCE_URL:= \
- https://librecmc.org/librecmc/downloads/sources/archive/v1.2.1/ \
+ http://mirror2.openwrt.org/sources \
ftp://ftp.denx.de/pub/u-boot
-
-PKG_MD5SUM:=526e01c8564ab8d1fd2c0e787a014b17
PKG_TARGETS:=bin
PKG_LICENSE:=GPL-2.0 GPL-2.0+
PKG_NAME:=uboot-envtools
PKG_DISTNAME:=u-boot
-PKG_VERSION:=2015.10-librecmc
+PKG_VERSION:=2015.10
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/u-boot-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=\
- https://librecmc.org/librecmc/downloads/sources/v1.3.4/ \
+ http://mirror2.openwrt.org/sources \
ftp://ftp.denx.de/pub/u-boot
-PKG_MD5SUM:=5e60d710ce19d2cd20c197ade9bbbc72
+PKG_HASH:=bdc68d5f9455ad933b059c735d983f2c8b6b552dafb062e5ff1444f623021955
PKG_BUILD_DEPENDS:=+fstools
board=$(ar71xx_board_name)
case "$board" in
-alfa-ap120c | \
-all0258n | \
-ap90q | \
-cap324 | \
-cap4200ag | \
-carambola2 | \
-cpe830 | \
-cpe870 | \
-cr3000 | \
-cr5000 | \
-eap300v2 | \
-gl-ar300m | \
-hornet-ub | \
-hornet-ub-x2 | \
-jwap230 | \
-mr1750 | \
-mr1750v2 | \
-mr600 | \
-mr600v2 | \
-mr900 | \
-mr900v2 | \
-nbg6716 | \
-om5p-an | \
-om5p-ac | \
-om5p-acv2 | \
-om5p | \
-tube2h | \
-wndr3700)
+a40|\
+a60|\
+alfa-ap120c|\
+all0258n|\
+ap121f|\
+ap90q|\
+cap324|\
+cap4200ag|\
+carambola2|\
+cpe830|\
+cpe870|\
+cr3000|\
+cr5000|\
+eap300v2|\
+gl-ar300m|\
+hornet-ub|\
+hornet-ub-x2|\
+jwap230|\
+mr1750|\
+mr1750v2|\
+mr600|\
+mr600v2|\
+mr900|\
+mr900v2|\
+nbg6716|\
+om5p|\
+om5p-ac|\
+om5p-acv2|\
+om5p-an|\
+sr3200|\
+tube2h|\
+wndr3700|\
+xd3200)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000"
;;
-alfa-ap96 | \
-all0315n | \
-om2p | \
-om2pv2 | \
-om2p-hs | \
-om2p-hsv2 | \
-om2p-hsv3 | \
-om2p-lc)
+alfa-ap96|\
+all0315n|\
+om2p|\
+om2p-hs|\
+om2p-hsv2|\
+om2p-hsv3|\
+om2p-hsv4|\
+om2p-lc|\
+om2pv2|\
+om2pv4)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x40000"
;;
-dr531)
- ubootenv_add_uci_config "/dev/mtd1" "0x0" "0xf800" "0x10000"
- ;;
-dap-2695-a1 | \
+dap-2695-a1|\
wzr-hp-ag300h)
ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x10000"
;;
+dr531)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0xf800" "0x10000"
+ ;;
qihoo-c301)
ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x10000" "0x10000"
;;
ubootenv_add_uci_config /dev/mmcblk0 0xd1400 0x20000 0x20000
fi
;;
-"wandboard")
+wandboard)
ubootenv_add_uci_config "/dev/mmcblk0" "0x60000" "0x2000" "0x2000"
;;
esac
board=$(ipq806x_board_name)
-
case "$board" in
-"ea8500")
+ea8500)
ubootenv_add_uci_config "/dev/mtd10" "0x0" "0x20000" "0x20000"
;;
-"nbg6817")
+nbg6817)
ubootenv_add_uci_config "/dev/mtdblock9" "0x0" "0x10000" "0x10000"
;;
esac
board=$(kirkwood_board_name)
case "$board" in
-"dockstar" | \
-"guruplug-server-plus" | \
-"ib62x0" | \
-"linksys-viper" | \
-"pogo_e02" | \
-"sheevaplug" | \
-"sheevaplug-esata" )
+dockstar|\
+guruplug-server-plus|\
+ib62x0|\
+linksys-viper|\
+pogo_e02|\
+sheevaplug|\
+sheevaplug-esata)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000"
;;
-"linksys-audi")
+linksys-audi)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x4000" "0x4000"
;;
esac
board=$(lantiq_board_name)
case "$board" in
-GIGASX76X)
- ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1"
- ;;
BTHOMEHUBV2B)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1"
;;
BTHOMEHUBV3A)
ubootenv_add_uci_config "/dev/mtd2" "0x0" "0x4000" "0x4000" "1"
;;
+GIGASX76X)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1"
+ ;;
P2812HNUF1)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x2000" "0x20000" "1"
;;
board=$(mvebu_board_name)
case "$board" in
-armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-shelby)
+armada-385-linksys-caiman|\
+armada-385-linksys-cobra|\
+armada-385-linksys-shelby)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x40000"
;;
armada-385-linksys-rango)
board=$(oxnas_board_name)
case "$board" in
-akitio | \
-stg212 | \
-kd20)
+akitio|\
+kd20|\
+stg212)
ubootenv_add_uci_config "/dev/ubi0_0" "0x0" "0x4000" "0x1F000" "1"
ubootenv_add_uci_config "/dev/ubi0_1" "0x0" "0x4000" "0x1F000" "1"
;;
board=$(ramips_board_name)
case "$board" in
-all0239-3g | \
-all0256n | \
+all0239-3g|\
+all0256n|\
all5002)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000"
;;
-linkits7688 | \
-linkits7688d | \
-wsr-600 | \
-wsr-1166 | \
-br6425 | \
-miwifi-nano | \
-sk-wb8 | \
+br-6425|\
+linkits7688|\
+linkits7688d|\
+miwifi-nano|\
+sk-wb8|\
+wsr-1166|\
+wsr-600|\
zbt-wg2626)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x10000"
;;
#
# Copyright (C) 2013-2016 OpenWrt.org
+# Copyright (C) 2017 Yousong Zhou
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
PKG_NAME:=u-boot
PKG_VERSION:=2016.03
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:= \
- http://mirror2.openwrt.org/sources \
- ftp://ftp.denx.de/pub/u-boot
-
-PKG_MD5SUM:=973c1d896be751321cc3aafa564f64b2
-
-PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
-
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_HASH:=e49337262ecac44dbdeac140f2c6ebd1eba345e0162b0464172e7f05583ed7bb
+PKG_MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
PKG_LICENSE:=GPL-2.0 GPL-2.0+
PKG_LICENSE_FILES:=Licenses/README
-include $(INCLUDE_DIR)/package.mk
-
-define uboot/Default
- TITLE:=
- CONFIG:=
- IMAGE:=
-endef
-
-define uboot/A10-OLinuXino-Lime
- TITLE:=U-Boot for the A10 OLinuXino LIME
-endef
-
-define uboot/A13-OLinuXino
- TITLE:=U-Boot for the A13 OlinuXino
-endef
-
-define uboot/A20-OLinuXino-Lime
- TITLE:=U-Boot for the A20 OLinuXino LIME
-endef
-
-define uboot/A20-OLinuXino_MICRO
- TITLE:=U-Boot for A20 OLinuXino MICRO
-endef
+PKG_BUILD_PARALLEL:=1
-define uboot/Bananapi
- TITLE:=U-Boot for Bananapi
-endef
-
-define uboot/Bananapro
- TITLE:=U-Boot for Bananapro
-endef
-
-define uboot/Cubieboard
- TITLE:=U-Boot for Cubieboard
-endef
-
-define uboot/Cubieboard2
- TITLE:=U-Boot for Cubieboard2
-endef
-
-define uboot/Cubietruck
- TITLE:=U-Boot for Cubietruck
-endef
-
-define uboot/Hummingbird_A31
- TITLE:=U-Boot for the Hummingbird A31 board
-endef
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
-define uboot/Mele_M9
- TITLE:=U-Boot for the Mele M9 (A31)
-endef
+include $(INCLUDE_DIR)/package.mk
-define uboot/OLIMEX_A13_SOM
- TITLE:=U-Boot for the Olimex A13 SOM
+define Package/uboot/template
+define Package/uboot-sunxi-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_sunxi
+ TITLE:=U-Boot for $(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
endef
-define uboot/Linksprite_pcDuino
- TITLE:=U-Boot for Linksprite pcDuino
-endef
-
-define uboot/Linksprite_pcDuino3
- TITLE:=U-Boot for Linksprite pcDuino3
-endef
-
-define uboot/Lamobo_R1
- TITLE:=U-Boot for Lamobo R1
+define Package/uboot-sunxi-$(1)/install
+ $(CP) $(PKG_BUILD_DIR)/u-boot-sunxi-with-spl.bin \
+ $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-u-boot-with-spl.bin
+ mkimage -C none -A arm -T script -d uEnv-$(if $(3),$(3),default).txt \
+ $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-boot.scr
endef
-define uboot/pangolin
- TITLE:=U-Boot for Theobroma A31-yQ7 devboard
-endef
+UBOOT_SUNXI_PACKAGES += uboot-sunxi-$(1)
-define uboot/orangepi_plus
- TITLE:=U-Boot for Orange Pi Plus (H3)
endef
-UBOOTS:= \
- A10-OLinuXino-Lime \
- A13-OLinuXino \
- A20-OLinuXino-Lime \
- A20-OLinuXino_MICRO \
- Bananapi \
- Bananapro \
- Cubieboard \
- Cubieboard2 \
- Cubietruck \
- Hummingbird_A31 \
- Mele_M9 \
- OLIMEX_A13_SOM \
- Linksprite_pcDuino \
- Linksprite_pcDuino3 \
- Lamobo_R1 \
- orangepi_plus \
- pangolin
+$(eval $(call Package/uboot/template,A10-OLinuXino-Lime,the A10 OLinuXino LIME))
+$(eval $(call Package/uboot/template,A13-OLinuXino,the A13 OlinuXino))
+$(eval $(call Package/uboot/template,A20-OLinuXino-Lime,the A20 OLinuXino LIME))
+$(eval $(call Package/uboot/template,A20-OLinuXino_MICRO,A20 OLinuXino MICRO))
+$(eval $(call Package/uboot/template,Bananapi,Bananapi))
+$(eval $(call Package/uboot/template,Bananapro,Bananapro))
+$(eval $(call Package/uboot/template,Cubieboard,Cubieboard))
+$(eval $(call Package/uboot/template,Cubieboard2,Cubieboard2))
+$(eval $(call Package/uboot/template,Cubietruck,Cubietruck))
+$(eval $(call Package/uboot/template,Hummingbird_A31,the Hummingbird A31 board))
+$(eval $(call Package/uboot/template,Mele_M9,the Mele M9 (A31)))
+$(eval $(call Package/uboot/template,OLIMEX_A13_SOM,the Olimex A13 SOM))
+$(eval $(call Package/uboot/template,Linksprite_pcDuino,Linksprite pcDuino))
+$(eval $(call Package/uboot/template,Linksprite_pcDuino3,Linksprite pcDuino3))
+$(eval $(call Package/uboot/template,Lamobo_R1,Lamobo R1))
+$(eval $(call Package/uboot/template,orangepi_plus,Orange Pi Plus (H3)))
+$(eval $(call Package/uboot/template,pangolin,Theobroma A31-yQ7 devboard,pangolin))
-define Package/uboot/template
-define Package/uboot-sunxi-$(1)
+define Package/uboot-sunxi-all
SECTION:=boot
CATEGORY:=Boot Loaders
DEPENDS:=@TARGET_sunxi
- TITLE:=$(2)
+ TITLE:=Meta package for selecting all variants of uboot-sunxi
URL:=http://www.denx.de/wiki/U-Boot
- VARIANT:=$(1)
- MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
-endef
-endef
-
-define BuildUBootPackage
- $(eval $(uboot/Default))
- $(eval $(uboot/$(1)))
- $(call Package/uboot/template,$(1),$(TITLE))
+ DEPENDS:=$(patsubst %,+%,$(UBOOT_SUNXI_PACKAGES))
endef
ifdef BUILD_VARIANT
-$(eval $(call uboot/$(BUILD_VARIANT)))
-UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
-UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
-endif
-
-# check if any specialized uEnv bootconfig is required
-ifeq ($(UBOOT_CONFIG),pangolin)
- UENV:=pangolin
-else
- UENV:=default
-endif
-
define Build/Configure
- $(MAKE) -C $(PKG_BUILD_DIR) \
- USE_PRIVATE_LIBGCC=yes $(UBOOT_CONFIG)_defconfig
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ USE_PRIVATE_LIBGCC=yes $(BUILD_VARIANT)_defconfig
endef
define Build/Compile
- $(MAKE) -C $(PKG_BUILD_DIR) \
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
CROSS_COMPILE=$(TARGET_CROSS) \
DTCDIR=$(LINUX_DIR)/scripts/dtc/
endef
-
-define Package/uboot/install/default
- $(CP) $(PKG_BUILD_DIR)/u-boot.bin \
- $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-u-boot.bin
- $(CP) $(PKG_BUILD_DIR)/spl/sunxi-spl.bin \
- $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-spl.bin
- $(CP) $(PKG_BUILD_DIR)/u-boot-sunxi-with-spl.bin \
- $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-u-boot-with-spl.bin
- $(CP) uEnv-$(UENV).txt \
- $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-uEnv.txt
- mkimage -C none -A arm -T script -d $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-uEnv.txt \
- $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-boot.scr
+else # BUILD_VARIANT
+define Build/Prepare
endef
-
-define Package/uboot/install/template
-define Package/uboot-sunxi-$(1)/install
- $(call Package/uboot/install/default,$(2))
+define Build/Configure
endef
+define Build/Compile
endef
+endif # BUILD_VARIANT
-$(foreach u,$(UBOOTS), \
- $(eval $(call Package/uboot/install/template,$(u),$(u))) \
-)
-
-$(foreach u,$(UBOOTS), \
- $(eval $(call BuildUBootPackage,$(u))) \
- $(eval $(call BuildPackage,uboot-sunxi-$(u))) \
+$(foreach pkg,$(UBOOT_SUNXI_PACKAGES), \
+ $(eval $(call BuildPackage,$(pkg))) \
)
+$(eval $(call BuildPackage,uboot-sunxi-all))
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=u-boot
-PKG_VERSION:=2012.10-rc2-libre
+PKG_VERSION:=2012.10-rc2
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
- https://librecmc.org/librecmc/downloads/sources/archive/ \
-
-
-PKG_MD5SUM:=ffd6e3795d221bc43c70bed97c919f70
+ http://mirror2.openwrt.org/sources \
+ ftp://ftp.denx.de/pub/u-boot
+PKG_HASH:=6d094cafa7ecea8b671fbdcd21130b6a4f5744fc47dd263e101ed5d3629dffd4
PKG_TARGETS:=bin
PKG_LICENSE:=GPL-2.0 GPL-2.0+
--- /dev/null
+From 183eb37e25d903ccd68cc2d8f8a37e75872c03d2 Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc@redhat.com>
+Date: Tue, 6 Sep 2016 17:35:35 +0100
+Subject: [PATCH 1/2] Do not pass host compiler sanitization flags on to linker
+ testsuite.
+
+ * Makefile.am (CFLAGS_FOR_TARGET): Define as a copy of CFLAGS but
+ without any sanitization options.
+ (CXXFLAGS_FOR_TARGET): Define as a copy of CXXFLAGS but without
+ any sanitization options.
+ (check-DEJAGNU): Pass CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET
+ as CFLAGS and CXXFLAGS respectively.
+---
+ ld/Makefile.am | 8 ++++++--
+ ld/Makefile.in | 8 ++++++--
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+
+--- a/ld/Makefile.am
++++ b/ld/Makefile.am
+@@ -136,6 +136,10 @@ CXX_FOR_TARGET = ` \
+ fi; \
+ fi`
+
++# Strip out sanitization options as we want to test building binaries without any extra paraphernalia
++CFLAGS_FOR_TARGET = `echo $(CFLAGS) | sed -e 's/-fsanitize=address//g' -e 's/-fsanitize=undefined//g'`
++CXXFLAGS_FOR_TARGET = `echo $(CXXFLAGS) | sed -e 's/-fsanitize=address//g' -e 's/-fsanitize=undefined//g'`
++
+ transform = s/^ld-new$$/$(installed_linker)/;@program_transform_name@
+ bin_PROGRAMS = ld-new
+ info_TEXINFOS = ld.texinfo
+@@ -2075,8 +2079,8 @@ check-DEJAGNU: site.exp
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \
+- CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS)" \
+- CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS)" \
++ CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS_FOR_TARGET)" \
++ CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \
+ OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \
+ LIBIBERTY="$(LIBIBERTY) $(LIBINTL)" LIBS="$(LIBS)" \
+--- a/ld/Makefile.in
++++ b/ld/Makefile.in
+@@ -507,6 +507,10 @@ CXX_FOR_TARGET = ` \
+ fi; \
+ fi`
+
++
++# Strip out sanitization options as they require special host libraries.
++CFLAGS_FOR_TARGET = `echo $(CFLAGS) | sed -e 's/-fsanitize=address//g' -e 's/-fsanitize=undefined//g'`
++CXXFLAGS_FOR_TARGET = `echo $(CXXFLAGS) | sed -e 's/-fsanitize=address//g' -e 's/-fsanitize=undefined//g'`
+ info_TEXINFOS = ld.texinfo
+ ld_TEXINFOS = configdoc.texi
+ noinst_TEXINFOS = ldint.texinfo
+@@ -3644,8 +3648,8 @@ check-DEJAGNU: site.exp
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \
+- CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS)" \
+- CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS)" \
++ CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS_FOR_TARGET)" \
++ CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \
+ OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \
+ LIBIBERTY="$(LIBIBERTY) $(LIBINTL)" LIBS="$(LIBS)" \
--- /dev/null
+From b8ff24c72174effd5c5527866313982e28507275 Mon Sep 17 00:00:00 2001
+From: Vlad Zakharov <vzakhar@synopsys.com>
+Date: Mon, 26 Sep 2016 16:36:08 +0100
+Subject: [PATCH 2/2] When building target binaries, ensure that the warning
+ flags selected for the command line match the target compiler.
+
+bfd * warning.m4 (AC_EGREP_CPP_FOR_BUILD): Introduce macro
+ to verify CC_FOR_BUILD compiler.
+ (AM_BINUTILS_WARNINGS): Introduce ac_cpp_for_build variable
+ and add CC_FOR_BUILD compiler checks.
+ * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * doc/Makefile.in: Likewise.
+
+binutils * Makefile.am: Replace AM_CLFAGS with AM_CFLAGS_FOR_BUILD
+ when building with CC_FOR_BUILD compiler.
+ * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * doc/Makefile.in: Likewise.
+
+gas * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * doc/Makefile.in: Likewise.
+
+gold * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * testsuite/Makefile.in: Likewise.
+
+gprof * Makefile.in: Regenerate.
+ * configure: Likewise.
+
+ld * Makefile.in: Regenerate.
+ * configure: Likewise.
+
+opcodes * Makefile.in: Regenerate.
+ * configure: Likewise.
+---
+ bfd/Makefile.in | 1 +
+ bfd/configure | 56 +++++++++++++++++++++++++++++++++++++++++-----
+ bfd/doc/Makefile.in | 1 +
+ bfd/warning.m4 | 47 ++++++++++++++++++++++++++++++++++----
+ binutils/Makefile.am | 10 +++++----
+ binutils/Makefile.in | 10 +++++----
+ binutils/configure | 56 +++++++++++++++++++++++++++++++++++++++++-----
+ binutils/doc/Makefile.in | 1 +
+ gas/Makefile.in | 1 +
+ gas/configure | 56 +++++++++++++++++++++++++++++++++++++++++-----
+ gas/doc/Makefile.in | 1 +
+ gold/Makefile.in | 5 +++--
+ gold/configure | 52 ++++++++++++++++++++++++++++++++++++++----
+ gold/testsuite/Makefile.in | 1 +
+ gprof/Makefile.in | 1 +
+ gprof/configure | 56 +++++++++++++++++++++++++++++++++++++++++-----
+ ld/Makefile.in | 3 ++-
+ ld/configure | 56 +++++++++++++++++++++++++++++++++++++++++-----
+ opcodes/Makefile.in | 1 +
+ opcodes/configure | 56 +++++++++++++++++++++++++++++++++++++++++-----
+ 20 files changed, 416 insertions(+), 55 deletions(-)
+
+--- a/bfd/Makefile.in
++++ b/bfd/Makefile.in
+@@ -288,6 +288,7 @@ TDEFINES = @TDEFINES@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ abs_builddir = @abs_builddir@
+--- a/bfd/configure
++++ b/bfd/configure
+@@ -659,6 +659,7 @@ MAINTAINER_MODE_FALSE
+ MAINTAINER_MODE_TRUE
+ WARN_WRITE_STRINGS
+ NO_WERROR
++WARN_CFLAGS_FOR_BUILD
+ WARN_CFLAGS
+ REPORT_BUGS_TEXI
+ REPORT_BUGS_TO
+@@ -11427,7 +11428,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11430 "configure"
++#line 11431 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11533,7 +11534,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11536 "configure"
++#line 11537 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -12240,8 +12241,12 @@ fi
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -12286,6 +12291,36 @@ fi
+ rm -f conftest*
+
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow"
++fi
++rm -f conftest*
++
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-4]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144"
++fi
++rm -f conftest*
++
++
+ # Check whether --enable-werror was given.
+ if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+@@ -12301,6 +12336,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -12314,25 +12350,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ # Check whether --enable-build-warnings was given.
+ if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac
+ fi
+
+@@ -12343,6 +12386,7 @@ fi
+
+
+
++
+
+
+
+--- a/bfd/doc/Makefile.in
++++ b/bfd/doc/Makefile.in
+@@ -248,6 +248,7 @@ TDEFINES = @TDEFINES@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ abs_builddir = @abs_builddir@
+--- a/bfd/warning.m4
++++ b/bfd/warning.m4
+@@ -17,12 +17,34 @@ dnl along with this program; see the fil
+ dnl <http://www.gnu.org/licenses/>.
+ dnl
+
++# AC_EGREP_CPP_FOR_BUILD(PATTERN, PROGRAM,
++# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
++# ------------------------------------------------------
++AC_DEFUN([AC_EGREP_CPP_FOR_BUILD],
++[AC_LANG_PREPROC_REQUIRE()dnl
++AC_REQUIRE([AC_PROG_EGREP])dnl
++AC_LANG_CONFTEST([AC_LANG_SOURCE([[$2]])])
++AS_IF([dnl eval is necessary to expand ac_cpp.
++dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell.
++(eval "$ac_cpp_for_build conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD |
++dnl Quote $1 to prevent m4 from eating character classes
++ $EGREP "[$1]" >/dev/null 2>&1],
++ [$3],
++ [$4])
++rm -f conftest*
++])# AC_EGREP_CPP_FOR_BUILD
++
++
+ AC_DEFUN([AM_BINUTILS_WARNINGS],[
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ AC_EGREP_CPP([^[0-3]$],[__GNUC__],,GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wshadow")
+@@ -34,6 +56,14 @@ AC_EGREP_CPP([^[0-4]$],[__GNUC__],,GCC_W
+ WARN_WRITE_STRINGS=""
+ AC_EGREP_CPP([^[0-3]$],[__GNUC__],,WARN_WRITE_STRINGS="-Wwrite-strings")
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++AC_EGREP_CPP_FOR_BUILD([^[0-3]$],[__GNUC__],,GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow")
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++AC_EGREP_CPP_FOR_BUILD([^[0-4]$],[__GNUC__],,GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144")
++
+ AC_ARG_ENABLE(werror,
+ [ --enable-werror treat compile warnings as errors],
+ [case "${enableval}" in
+@@ -47,6 +77,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -60,25 +91,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ AC_ARG_ENABLE(build-warnings,
+ [ --enable-build-warnings enable build-time compiler warnings],
+ [case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac])
+
+ if test x"$silent" != x"yes" && test x"$WARN_CFLAGS" != x""; then
+@@ -86,6 +124,7 @@ if test x"$silent" != x"yes" && test x"$
+ fi
+
+ AC_SUBST(WARN_CFLAGS)
++AC_SUBST(WARN_CFLAGS_FOR_BUILD)
+ AC_SUBST(NO_WERROR)
+ AC_SUBST(WARN_WRITE_STRINGS)
+ ])
+--- a/binutils/Makefile.am
++++ b/binutils/Makefile.am
+@@ -47,8 +47,10 @@ ZLIB = @zlibdir@ -lz
+ ZLIBINC = @zlibinc@
+
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ NO_WERROR = @NO_WERROR@
+ AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
++AM_CFLAGS_FOR_BUILD = $(WARN_CFLAGS_FOR_BUILD) $(ZLIBINC)
+ LIBICONV = @LIBICONV@
+
+ # these two are almost the same program
+@@ -305,17 +307,17 @@ sysinfo$(EXEEXT_FOR_BUILD): sysinfo.@OBJ
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $@ sysinfo.@OBJEXT@ syslex_wrap.@OBJEXT@
+
+ syslex_wrap.@OBJEXT@: syslex_wrap.c syslex.c sysinfo.h config.h
+- $(CC_FOR_BUILD) -c -I. -I$(srcdir) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/syslex_wrap.c
++ $(CC_FOR_BUILD) -c -I. -I$(srcdir) $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/syslex_wrap.c
+
+ sysinfo.@OBJEXT@: sysinfo.c
+ if [ -r sysinfo.c ]; then \
+- $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(NO_WERROR) sysinfo.c ; \
++ $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(NO_WERROR) sysinfo.c ; \
+ else \
+- $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/sysinfo.c ; \
++ $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/sysinfo.c ; \
+ fi
+
+ bin2c$(EXEEXT_FOR_BUILD): bin2c.c
+- $(CC_FOR_BUILD) -o $@ $(AM_CPPFLAGS) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $(srcdir)/bin2c.c
++ $(CC_FOR_BUILD) -o $@ $(AM_CPPFLAGS) $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $(srcdir)/bin2c.c
+
+ embedspu: embedspu.sh Makefile
+ awk '/^program_transform_name=/ {print "program_transform_name=\"$(program_transform_name)\""; next} {print}' < $< > $@
+--- a/binutils/Makefile.in
++++ b/binutils/Makefile.in
+@@ -401,6 +401,7 @@ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ YACC = `if [ -f ../bison/bison ]; then echo ../bison/bison -y -L$(srcdir)/../bison/; else echo @YACC@; fi`
+@@ -478,6 +479,7 @@ am__skipyacc =
+ ZLIB = @zlibdir@ -lz
+ ZLIBINC = @zlibinc@
+ AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
++AM_CFLAGS_FOR_BUILD = $(WARN_CFLAGS_FOR_BUILD) $(ZLIBINC)
+
+ # these two are almost the same program
+ AR_PROG = ar
+@@ -1370,17 +1372,17 @@ sysinfo$(EXEEXT_FOR_BUILD): sysinfo.@OBJ
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $@ sysinfo.@OBJEXT@ syslex_wrap.@OBJEXT@
+
+ syslex_wrap.@OBJEXT@: syslex_wrap.c syslex.c sysinfo.h config.h
+- $(CC_FOR_BUILD) -c -I. -I$(srcdir) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/syslex_wrap.c
++ $(CC_FOR_BUILD) -c -I. -I$(srcdir) $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/syslex_wrap.c
+
+ sysinfo.@OBJEXT@: sysinfo.c
+ if [ -r sysinfo.c ]; then \
+- $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(NO_WERROR) sysinfo.c ; \
++ $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(NO_WERROR) sysinfo.c ; \
+ else \
+- $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/sysinfo.c ; \
++ $(CC_FOR_BUILD) -c -I. $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(NO_WERROR) $(srcdir)/sysinfo.c ; \
+ fi
+
+ bin2c$(EXEEXT_FOR_BUILD): bin2c.c
+- $(CC_FOR_BUILD) -o $@ $(AM_CPPFLAGS) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $(srcdir)/bin2c.c
++ $(CC_FOR_BUILD) -o $@ $(AM_CPPFLAGS) $(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $(srcdir)/bin2c.c
+
+ embedspu: embedspu.sh Makefile
+ awk '/^program_transform_name=/ {print "program_transform_name=\"$(program_transform_name)\""; next} {print}' < $< > $@
+--- a/binutils/configure
++++ b/binutils/configure
+@@ -652,6 +652,7 @@ YFLAGS
+ YACC
+ WARN_WRITE_STRINGS
+ NO_WERROR
++WARN_CFLAGS_FOR_BUILD
+ WARN_CFLAGS
+ OTOOL64
+ OTOOL
+@@ -11225,7 +11226,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11228 "configure"
++#line 11229 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11331,7 +11332,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11334 "configure"
++#line 11335 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11945,8 +11946,12 @@ _ACEOF
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -11991,6 +11996,36 @@ fi
+ rm -f conftest*
+
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow"
++fi
++rm -f conftest*
++
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-4]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144"
++fi
++rm -f conftest*
++
++
+ # Check whether --enable-werror was given.
+ if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+@@ -12006,6 +12041,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -12019,25 +12055,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ # Check whether --enable-build-warnings was given.
+ if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac
+ fi
+
+@@ -12048,6 +12091,7 @@ fi
+
+
+
++
+
+
+
+--- a/binutils/doc/Makefile.in
++++ b/binutils/doc/Makefile.in
+@@ -249,6 +249,7 @@ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ YACC = @YACC@
+--- a/gas/Makefile.in
++++ b/gas/Makefile.in
+@@ -255,6 +255,7 @@ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@ @WARN_WRITE_STRINGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo @YACC@ ; fi`
+--- a/gas/configure
++++ b/gas/configure
+@@ -642,6 +642,7 @@ cgen_cpu_prefix
+ GDBINIT
+ WARN_WRITE_STRINGS
+ NO_WERROR
++WARN_CFLAGS_FOR_BUILD
+ WARN_CFLAGS
+ OTOOL64
+ OTOOL
+@@ -10985,7 +10986,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 10988 "configure"
++#line 10989 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11091,7 +11092,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11094 "configure"
++#line 11095 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11721,8 +11722,12 @@ using_cgen=no
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -11767,6 +11772,36 @@ fi
+ rm -f conftest*
+
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow"
++fi
++rm -f conftest*
++
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-4]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144"
++fi
++rm -f conftest*
++
++
+ # Check whether --enable-werror was given.
+ if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+@@ -11782,6 +11817,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -11795,25 +11831,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ # Check whether --enable-build-warnings was given.
+ if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac
+ fi
+
+@@ -11824,6 +11867,7 @@ fi
+
+
+
++
+
+
+
+--- a/gas/doc/Makefile.in
++++ b/gas/doc/Makefile.in
+@@ -230,6 +230,7 @@ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ YACC = @YACC@
+--- a/gold/Makefile.in
++++ b/gold/Makefile.in
+@@ -87,8 +87,8 @@ subdir = .
+ DIST_COMMON = NEWS README ChangeLog $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(srcdir)/config.in \
+- $(srcdir)/../mkinstalldirs $(top_srcdir)/po/Make-in \
+- ftruncate.c pread.c mremap.c ffsll.c yyscript.h yyscript.c \
++ $(srcdir)/../mkinstalldirs $(top_srcdir)/po/Make-in ffsll.c \
++ mremap.c ftruncate.c pread.c yyscript.h yyscript.c \
+ $(srcdir)/../depcomp $(srcdir)/../ylwrap
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
+@@ -409,6 +409,7 @@ TARGETOBJS = @TARGETOBJS@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_CXXFLAGS = @WARN_CXXFLAGS@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+--- a/gold/configure
++++ b/gold/configure
+@@ -609,6 +609,7 @@ GOLD_LDFLAGS
+ WARN_CXXFLAGS
+ WARN_WRITE_STRINGS
+ NO_WERROR
++WARN_CFLAGS_FOR_BUILD
+ WARN_CFLAGS
+ IFUNC_STATIC_FALSE
+ IFUNC_STATIC_TRUE
+@@ -6723,8 +6724,12 @@ fi
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -6769,6 +6774,36 @@ fi
+ rm -f conftest*
+
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow"
++fi
++rm -f conftest*
++
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-4]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144"
++fi
++rm -f conftest*
++
++
+ # Check whether --enable-werror was given.
+ if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+@@ -6784,6 +6819,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -6797,25 +6833,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ # Check whether --enable-build-warnings was given.
+ if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac
+ fi
+
+@@ -6826,6 +6869,7 @@ fi
+
+
+
++
+
+
+
+--- a/gold/testsuite/Makefile.in
++++ b/gold/testsuite/Makefile.in
+@@ -2568,6 +2568,7 @@ TARGETOBJS = @TARGETOBJS@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_CXXFLAGS = @WARN_CXXFLAGS@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+--- a/gprof/Makefile.in
++++ b/gprof/Makefile.in
+@@ -267,6 +267,7 @@ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ abs_builddir = @abs_builddir@
+--- a/gprof/configure
++++ b/gprof/configure
+@@ -604,6 +604,7 @@ LTLIBOBJS
+ LIBOBJS
+ WARN_WRITE_STRINGS
+ NO_WERROR
++WARN_CFLAGS_FOR_BUILD
+ WARN_CFLAGS
+ GENINSRC_NEVER_FALSE
+ GENINSRC_NEVER_TRUE
+@@ -10901,7 +10902,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 10904 "configure"
++#line 10905 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11007,7 +11008,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11010 "configure"
++#line 11011 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -12101,8 +12102,12 @@ fi
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -12147,6 +12152,36 @@ fi
+ rm -f conftest*
+
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow"
++fi
++rm -f conftest*
++
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-4]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144"
++fi
++rm -f conftest*
++
++
+ # Check whether --enable-werror was given.
+ if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+@@ -12162,6 +12197,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -12175,25 +12211,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ # Check whether --enable-build-warnings was given.
+ if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac
+ fi
+
+@@ -12204,6 +12247,7 @@ fi
+
+
+
++
+
+
+
+--- a/ld/Makefile.in
++++ b/ld/Makefile.in
+@@ -354,6 +354,7 @@ TESTBFDLIB = @TESTBFDLIB@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ YACC = `if [ -f ../bison/bison ]; then echo ../bison/bison -y -L$(srcdir)/../bison/; else echo @YACC@; fi`
+@@ -508,7 +509,7 @@ CXX_FOR_TARGET = ` \
+ fi`
+
+
+-# Strip out sanitization options as they require special host libraries.
++# Strip out sanitization options as we want to test building binaries without any extra paraphernalia
+ CFLAGS_FOR_TARGET = `echo $(CFLAGS) | sed -e 's/-fsanitize=address//g' -e 's/-fsanitize=undefined//g'`
+ CXXFLAGS_FOR_TARGET = `echo $(CXXFLAGS) | sed -e 's/-fsanitize=address//g' -e 's/-fsanitize=undefined//g'`
+ info_TEXINFOS = ld.texinfo
+--- a/ld/configure
++++ b/ld/configure
+@@ -646,6 +646,7 @@ LIBINTL
+ USE_NLS
+ WARN_WRITE_STRINGS
+ NO_WERROR
++WARN_CFLAGS_FOR_BUILD
+ WARN_CFLAGS
+ installed_linker
+ install_as_default
+@@ -11723,7 +11724,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11726 "configure"
++#line 11727 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11829,7 +11830,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11832 "configure"
++#line 11833 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -15558,8 +15559,12 @@ fi
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -15604,6 +15609,36 @@ fi
+ rm -f conftest*
+
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow"
++fi
++rm -f conftest*
++
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-4]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144"
++fi
++rm -f conftest*
++
++
+ # Check whether --enable-werror was given.
+ if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+@@ -15619,6 +15654,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -15632,25 +15668,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ # Check whether --enable-build-warnings was given.
+ if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac
+ fi
+
+@@ -15661,6 +15704,7 @@ fi
+
+
+
++
+
+
+
+--- a/opcodes/Makefile.in
++++ b/opcodes/Makefile.in
+@@ -267,6 +267,7 @@ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
+ WARN_CFLAGS = @WARN_CFLAGS@
++WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
+ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
+ XGETTEXT = @XGETTEXT@
+ abs_builddir = @abs_builddir@
+--- a/opcodes/configure
++++ b/opcodes/configure
+@@ -643,6 +643,7 @@ MAINTAINER_MODE_TRUE
+ NO_WMISSING_FIELD_INITIALIZERS
+ WARN_WRITE_STRINGS
+ NO_WERROR
++WARN_CFLAGS_FOR_BUILD
+ WARN_CFLAGS
+ OTOOL64
+ OTOOL
+@@ -11150,7 +11151,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11153 "configure"
++#line 11154 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11256,7 +11257,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 11259 "configure"
++#line 11260 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11508,8 +11509,12 @@ fi
+ # Set the 'development' global.
+ . $srcdir/../bfd/development.sh
+
++# Set acp_cpp_for_build variable
++ac_cpp_for_build="$CC_FOR_BUILD -E $CPPFLAGS_FOR_BUILD"
++
+ # Default set of GCC warnings to enable.
+ GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
++GCC_WARN_CFLAGS_FOR_BUILD="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+
+ # Add -Wshadow if the compiler is a sufficiently recent version of GCC.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -11554,6 +11559,36 @@ fi
+ rm -f conftest*
+
+
++# Verify CC_FOR_BUILD to be compatible with waring flags
++
++# Add -Wshadow if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wshadow"
++fi
++rm -f conftest*
++
++
++# Add -Wstack-usage if the compiler is a sufficiently recent version of GCC.
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++__GNUC__
++_ACEOF
++if (eval "$ac_cpp_for_build conftest.$ac_ext") 2>&5 |
++ $EGREP "^[0-4]$" >/dev/null 2>&1; then :
++
++else
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wstack-usage=262144"
++fi
++rm -f conftest*
++
++
+ # Check whether --enable-werror was given.
+ if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+@@ -11569,6 +11604,7 @@ case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Wno-format"
+ fi
+ ;;
+ *) ;;
+@@ -11582,25 +11618,32 @@ fi
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS_FOR_BUILD="$GCC_WARN_CFLAGS_FOR_BUILD -Werror"
+ NO_WERROR="-Wno-error"
+ fi
+
+ if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}"
+ fi
+
+ # Check whether --enable-build-warnings was given.
+ if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+- yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
++ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
++ WARN_CFLAGS_FOR_BUILD="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
++ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}"
++ WARN_CFLAGS_FOR_BUILD="${GCC_WARN_CFLAGS_FOR_BUILD} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+- WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+- *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
++ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}"
++ WARN_CFLAGS_FOR_BUILD="${t} ${GCC_WARN_CFLAGS_FOR_BUILD}";;
++ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`
++ WARN_CFLAGS_FOR_BUILD=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+ esac
+ fi
+
+@@ -11611,6 +11654,7 @@ fi
+
+
+
++
+
+
+ ac_ext=c
--- /dev/null
+From 6232c17438ed01f43665197db5a98a4a4f77ef47 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Thu, 2 Feb 2017 10:57:40 +0100
+Subject: [PATCH 01/19] rt2x00: avoid introducing a USB dependency in the
+ rt2x00lib module
+
+As reported by Felix:
+
+Though protected by an ifdef, introducing an usb symbol dependency in
+the rt2x00lib module is a major inconvenience for distributions that
+package kernel modules split into individual packages.
+
+Get rid of this unnecessary dependency by calling the usb related
+function from a more suitable place.
+
+Cc: Vishal Thanki <vishalthanki@gmail.com>
+Reported-by: Felix Fietkau <nbd@nbd.name>
+Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 23 ++++++++---------------
+ drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 5 +++++
+ 2 files changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index 8fcbc8dc94c1..4b08007f93f7 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -1436,21 +1436,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
+ cancel_work_sync(&rt2x00dev->intf_work);
+ cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+ cancel_work_sync(&rt2x00dev->sleep_work);
+-#if IS_ENABLED(CPTCFG_RT2X00_LIB_USB)
+- if (rt2x00_is_usb(rt2x00dev)) {
+- usb_kill_anchored_urbs(rt2x00dev->anchor);
+- hrtimer_cancel(&rt2x00dev->txstatus_timer);
+- cancel_work_sync(&rt2x00dev->rxdone_work);
+- cancel_work_sync(&rt2x00dev->txdone_work);
+- }
+-#endif
+- if (rt2x00dev->workqueue)
+- destroy_workqueue(rt2x00dev->workqueue);
+-
+- /*
+- * Free the tx status fifo.
+- */
+- kfifo_free(&rt2x00dev->txstatus_fifo);
+
+ /*
+ * Kill the tx status tasklet.
+@@ -1466,6 +1451,14 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
+ */
+ rt2x00lib_uninitialize(rt2x00dev);
+
++ if (rt2x00dev->workqueue)
++ destroy_workqueue(rt2x00dev->workqueue);
++
++ /*
++ * Free the tx status fifo.
++ */
++ kfifo_free(&rt2x00dev->txstatus_fifo);
++
+ /*
+ * Free extra components
+ */
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+index 838ca58d2dd6..5a2bf9f63cd7 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+@@ -744,6 +744,11 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev)
+ {
+ struct data_queue *queue;
+
++ usb_kill_anchored_urbs(rt2x00dev->anchor);
++ hrtimer_cancel(&rt2x00dev->txstatus_timer);
++ cancel_work_sync(&rt2x00dev->rxdone_work);
++ cancel_work_sync(&rt2x00dev->txdone_work);
++
+ queue_for_each(rt2x00dev, queue)
+ rt2x00usb_free_entries(queue);
+ }
+--
+2.12.1
+
--- /dev/null
+From 93c7018ec16bb83399dd4db61c361a6d6aba0d5a Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 8 Feb 2017 12:18:09 +0100
+Subject: [PATCH 02/19] rt2x00usb: do not anchor rx and tx urb's
+
+We might kill TX or RX urb during rt2x00usb_flush_entry(), what can
+cause anchor list corruption like shown below:
+
+[ 2074.035633] WARNING: CPU: 2 PID: 14480 at lib/list_debug.c:33 __list_add+0xac/0xc0
+[ 2074.035634] list_add corruption. prev->next should be next (ffff88020f362c28), but was dead000000000100. (prev=ffff8801d161bb70).
+<snip>
+[ 2074.035670] Call Trace:
+[ 2074.035672] [<ffffffff813bde47>] dump_stack+0x63/0x8c
+[ 2074.035674] [<ffffffff810a2231>] __warn+0xd1/0xf0
+[ 2074.035676] [<ffffffff810a22af>] warn_slowpath_fmt+0x5f/0x80
+[ 2074.035678] [<ffffffffa073855d>] ? rt2x00usb_register_write_lock+0x3d/0x60 [rt2800usb]
+[ 2074.035679] [<ffffffff813dbe4c>] __list_add+0xac/0xc0
+[ 2074.035681] [<ffffffff81591c6c>] usb_anchor_urb+0x4c/0xa0
+[ 2074.035683] [<ffffffffa07322af>] rt2x00usb_kick_rx_entry+0xaf/0x100 [rt2x00usb]
+[ 2074.035684] [<ffffffffa0732322>] rt2x00usb_clear_entry+0x22/0x30 [rt2x00usb]
+
+To fix do not anchor TX and RX urb's, it is not needed as during
+shutdown we kill those urbs in rt2x00usb_free_entries().
+
+Cc: Vishal Thanki <vishalthanki@gmail.com>
+Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+index 5a2bf9f63cd7..fe13dd07cc2a 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+@@ -319,10 +319,8 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data)
+ entry->skb->data, length,
+ rt2x00usb_interrupt_txdone, entry);
+
+- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor);
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ if (status) {
+- usb_unanchor_urb(entry_priv->urb);
+ if (status == -ENODEV)
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+@@ -410,10 +408,8 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data)
+ entry->skb->data, entry->skb->len,
+ rt2x00usb_interrupt_rxdone, entry);
+
+- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor);
+ status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ if (status) {
+- usb_unanchor_urb(entry_priv->urb);
+ if (status == -ENODEV)
+ clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+--
+2.12.1
+
--- /dev/null
+From 0488a6121dfe6cbd44de15ea3627913b7549a1e9 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 8 Feb 2017 12:18:10 +0100
+Subject: [PATCH 03/19] rt2x00usb: fix anchor initialization
+
+If device fail to initialize we can OOPS in rt2x00lib_remove_dev(), due
+to using uninitialized usb_anchor structure:
+
+[ 855.435820] ieee80211 phy3: rt2x00usb_vendor_request: Error - Vendor Request 0x07 failed for offset 0x1000 with error -19
+[ 855.435826] ieee80211 phy3: rt2800_probe_rt: Error - Invalid RT chipset 0x0000, rev 0000 detected
+[ 855.435829] ieee80211 phy3: rt2x00lib_probe_dev: Error - Failed to allocate device
+[ 855.435845] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
+[ 855.435900] IP: _raw_spin_lock_irq+0xd/0x30
+[ 855.435926] PGD 0
+[ 855.435953] Oops: 0002 [#1] SMP
+<snip>
+[ 855.437011] Call Trace:
+[ 855.437029] ? usb_kill_anchored_urbs+0x27/0xc0
+[ 855.437061] rt2x00lib_remove_dev+0x190/0x1c0 [rt2x00lib]
+[ 855.437097] rt2x00lib_probe_dev+0x246/0x7a0 [rt2x00lib]
+[ 855.437149] ? ieee80211_roc_setup+0x9e/0xd0 [mac80211]
+[ 855.437183] ? __kmalloc+0x1af/0x1f0
+[ 855.437207] ? rt2x00usb_probe+0x13d/0xc50 [rt2x00usb]
+[ 855.437240] rt2x00usb_probe+0x155/0xc50 [rt2x00usb]
+[ 855.437273] rt2800usb_probe+0x15/0x20 [rt2800usb]
+[ 855.437304] usb_probe_interface+0x159/0x2d0
+[ 855.437333] driver_probe_device+0x2bb/0x460
+
+Patch changes initialization sequence to fix the problem.
+
+Cc: Vishal Thanki <vishalthanki@gmail.com>
+Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+index fe13dd07cc2a..c696f0ad6a68 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+@@ -825,10 +825,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
+ if (retval)
+ goto exit_free_device;
+
+- retval = rt2x00lib_probe_dev(rt2x00dev);
+- if (retval)
+- goto exit_free_reg;
+-
+ rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev,
+ sizeof(struct usb_anchor),
+ GFP_KERNEL);
+@@ -836,10 +832,17 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
+ retval = -ENOMEM;
+ goto exit_free_reg;
+ }
+-
+ init_usb_anchor(rt2x00dev->anchor);
++
++ retval = rt2x00lib_probe_dev(rt2x00dev);
++ if (retval)
++ goto exit_free_anchor;
++
+ return 0;
+
++exit_free_anchor:
++ usb_kill_anchored_urbs(rt2x00dev->anchor);
++
+ exit_free_reg:
+ rt2x00usb_free_reg(rt2x00dev);
+
+--
+2.12.1
+
--- /dev/null
+From 80a97eae304631f57ff8560f87c0b18b95321443 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 8 Feb 2017 13:51:29 +0100
+Subject: [PATCH 04/19] rt61pci: use entry directly
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt61pci.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+index 5306a3b2622d..8adb5f3abe15 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+@@ -1903,8 +1903,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
+
+ rt2x00_desc_read(txd, 5, &word);
+ rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid);
+- rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE,
+- skbdesc->entry->entry_idx);
++ rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx);
+ rt2x00_set_field32(&word, TXD_W5_TX_POWER,
+ TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));
+ rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
+--
+2.12.1
+
--- /dev/null
+From 2ceb813798e1fd33e71a574771828c0f298e077b Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 8 Feb 2017 13:51:30 +0100
+Subject: [PATCH 05/19] rt2x00: call entry directly in rt2x00_dump_frame
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2400pci.c | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt2500pci.c | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 4 ++--
+ drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | 7 ++++---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 4 ++--
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt61pci.c | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt73usb.c | 2 +-
+ 10 files changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
+index 085c5b423bdf..19874439ac40 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
+@@ -1200,7 +1200,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
+ out:
+ /*
+ * Enable beaconing again.
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
+index 9832fd50c793..791434de8052 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
+@@ -1349,7 +1349,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
+ out:
+ /*
+ * Enable beaconing again.
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
+index cd3ab5a9e98d..62357465fe29 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
+@@ -1170,7 +1170,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
+
+ /*
+ * USB devices cannot blindly pass the skb->len as the
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 572cdea4ca25..8223a1520316 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -1014,7 +1014,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
+
+ /*
+ * Write entire beacon with TXWI and padding to register.
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+index ea299c4e7ada..26869b3bef45 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -1400,11 +1400,11 @@ void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop);
+ */
+ #ifdef CPTCFG_RT2X00_LIB_DEBUGFS
+ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+- enum rt2x00_dump_type type, struct sk_buff *skb);
++ enum rt2x00_dump_type type, struct queue_entry *entry);
+ #else
+ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+ enum rt2x00_dump_type type,
+- struct sk_buff *skb)
++ struct queue_entry *entry)
+ {
+ }
+ #endif /* CPTCFG_RT2X00_LIB_DEBUGFS */
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
+index 72ae530e4a3b..964aefdc11f0 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
+@@ -157,9 +157,10 @@ void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
+ }
+
+ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+- enum rt2x00_dump_type type, struct sk_buff *skb)
++ enum rt2x00_dump_type type, struct queue_entry *entry)
+ {
+ struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
++ struct sk_buff *skb = entry->skb;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ struct sk_buff *skbcopy;
+ struct rt2x00dump_hdr *dump_hdr;
+@@ -196,8 +197,8 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+ dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
+ dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
+ dump_hdr->type = cpu_to_le16(type);
+- dump_hdr->queue_index = skbdesc->entry->queue->qid;
+- dump_hdr->entry_index = skbdesc->entry->entry_idx;
++ dump_hdr->queue_index = entry->queue->qid;
++ dump_hdr->entry_index = entry->entry_idx;
+ dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
+ dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index 4b08007f93f7..dd6678109b7e 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -363,7 +363,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
+ * Send frame to debugfs immediately, after this call is completed
+ * we are going to overwrite the skb->cb array.
+ */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
+
+ /*
+ * Determine if the frame has been successfully transmitted and
+@@ -772,7 +772,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
+ */
+ rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
+ rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry);
+
+ /*
+ * Initialize RX status information, and send frame
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+index b2364d378774..380daf4e1b8d 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+@@ -544,7 +544,7 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
+ * All processing on the frame has been completed, this means
+ * it is now ready to be dumped to userspace through debugfs.
+ */
+- rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
++ rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry);
+ }
+
+ static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+index 8adb5f3abe15..973d418b8113 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+@@ -1988,7 +1988,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
+
+ /*
+ * Write entire beacon with descriptor and padding to register.
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt73usb.c b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
+index 1a29c4d205a5..bb8d307a789f 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
+@@ -1557,7 +1557,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
+
+ /*
+ * Write entire beacon with descriptor and padding to register.
+--
+2.12.1
+
--- /dev/null
+From cf81db30a6edcca791b1bfa5348a162471121d11 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 8 Feb 2017 13:51:31 +0100
+Subject: [PATCH 06/19] rt2x00: remove queue_entry from skbdesc
+
+queue_entry field of skbdesc is not read any more, remove it to allow
+skbdesc contain other data.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 3 ---
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 2 --
+ 2 files changed, 5 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+index 380daf4e1b8d..e1660b92b20c 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+@@ -83,7 +83,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp)
+ */
+ skbdesc = get_skb_frame_desc(skb);
+ memset(skbdesc, 0, sizeof(*skbdesc));
+- skbdesc->entry = entry;
+
+ if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DMA)) {
+ dma_addr_t skb_dma;
+@@ -689,7 +688,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
+ goto out;
+ }
+
+- skbdesc->entry = entry;
+ entry->skb = skb;
+
+ /*
+@@ -774,7 +772,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
+ */
+ skbdesc = get_skb_frame_desc(intf->beacon->skb);
+ memset(skbdesc, 0, sizeof(*skbdesc));
+- skbdesc->entry = intf->beacon;
+
+ /*
+ * Send beacon to hardware.
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+index 2233b911a1d7..22d18818e850 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+@@ -116,8 +116,6 @@ struct skb_frame_desc {
+ __le32 iv[2];
+
+ dma_addr_t skb_dma;
+-
+- struct queue_entry *entry;
+ };
+
+ /**
+--
+2.12.1
+
--- /dev/null
+From 7272416609126e8910b7f0d0e3dba008aa87830c Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 14 Feb 2017 22:28:33 +0100
+Subject: [PATCH 07/19] rt2500usb: don't mark register accesses as inline
+
+When CONFIG_KASAN is set, we get a rather large stack here:
+
+drivers/net/wireless/ralink/rt2x00/rt2500usb.c: In function 'rt2500usb_set_device_state':
+drivers/net/wireless/ralink/rt2x00/rt2500usb.c:1074:1: error: the frame size of 3032 bytes is larger than 100 bytes [-Werror=frame-larger-than=]
+
+If we don't force those functions to be inline, the compiler can figure this
+out better itself and not inline the functions when doing so would be harmful,
+reducing the stack size to a merge 256 bytes.
+
+Note that there is another problem that manifests in this driver, as a result
+of the typecheck() macro causing even larger stack frames.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
+index 62357465fe29..0d2670a56c4c 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
+@@ -55,7 +55,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+ * If the csr_mutex is already held then the _lock variants must
+ * be used instead.
+ */
+-static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
++static void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u16 *value)
+ {
+@@ -66,7 +66,7 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
+ *value = le16_to_cpu(reg);
+ }
+
+-static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
++static void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u16 *value)
+ {
+@@ -77,16 +77,7 @@ static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
+ *value = le16_to_cpu(reg);
+ }
+
+-static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
+- const unsigned int offset,
+- void *value, const u16 length)
+-{
+- rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
+- USB_VENDOR_REQUEST_IN, offset,
+- value, length);
+-}
+-
+-static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
++static void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u16 value)
+ {
+@@ -96,7 +87,7 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
+ ®, sizeof(reg));
+ }
+
+-static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
++static void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u16 value)
+ {
+@@ -106,7 +97,7 @@ static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
+ ®, sizeof(reg), REGISTER_TIMEOUT);
+ }
+
+-static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
++static void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ void *value, const u16 length)
+ {
+--
+2.12.1
+
--- /dev/null
+From 96609f366c6f792421e1939c5c834abbe24eb88a Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Wed, 15 Feb 2017 10:25:04 +0100
+Subject: [PATCH 08/19] rt2x00: rt2800lib: move rt2800_drv_data declaration
+ into rt2800lib.h
+
+The rt2800_drv_data structure contains driver specific
+information. Move the declaration into the rt2800lib.h
+header which is a more logical place for it. Also fix
+the comment style to avoid checkpatch warning.
+
+The patch contains no functional changes, it is in
+preparation for the next patch.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800.h | 25 -------------------------
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 23 +++++++++++++++++++++++
+ 2 files changed, 23 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+index 256496bfbafb..0e7051d8132f 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+@@ -2987,29 +2987,4 @@ enum rt2800_eeprom_word {
+ */
+ #define BCN_TBTT_OFFSET 64
+
+-/*
+- * Hardware has 255 WCID table entries. First 32 entries are reserved for
+- * shared keys. Since parts of the pairwise key table might be shared with
+- * the beacon frame buffers 6 & 7 we could only use the first 222 entries.
+- */
+-#define WCID_START 33
+-#define WCID_END 222
+-#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
+-
+-/*
+- * RT2800 driver data structure
+- */
+-struct rt2800_drv_data {
+- u8 calibration_bw20;
+- u8 calibration_bw40;
+- u8 bbp25;
+- u8 bbp26;
+- u8 txmixer_gain_24g;
+- u8 txmixer_gain_5g;
+- u8 max_psdu;
+- unsigned int tbtt_tick;
+- unsigned int ampdu_factor_cnt[4];
+- DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
+-};
+-
+ #endif /* RT2800_H */
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+index 0a8b4df665fe..8e1ae138c3f1 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -20,6 +20,29 @@
+ #ifndef RT2800LIB_H
+ #define RT2800LIB_H
+
++/*
++ * Hardware has 255 WCID table entries. First 32 entries are reserved for
++ * shared keys. Since parts of the pairwise key table might be shared with
++ * the beacon frame buffers 6 & 7 we could only use the first 222 entries.
++ */
++#define WCID_START 33
++#define WCID_END 222
++#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
++
++/* RT2800 driver data structure */
++struct rt2800_drv_data {
++ u8 calibration_bw20;
++ u8 calibration_bw40;
++ u8 bbp25;
++ u8 bbp26;
++ u8 txmixer_gain_24g;
++ u8 txmixer_gain_5g;
++ u8 max_psdu;
++ unsigned int tbtt_tick;
++ unsigned int ampdu_factor_cnt[4];
++ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
++};
++
+ struct rt2800_ops {
+ void (*register_read)(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset, u32 *value);
+--
+2.12.1
+
--- /dev/null
+From a13d985f26f6df07d5c5c0e190477628e236babc Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:05 +0100
+Subject: [PATCH 09/19] rt2800: identify station based on status WCID
+
+Add framework to identify sta based on tx status WCID. This is currently
+not used, will start be utilized in the future patch.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 +++++
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 1 +
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 3 ++-
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 8223a1520316..46405cce35e0 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -855,11 +855,13 @@ EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
+ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
+ {
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct txdone_entry_desc txdesc;
+ u32 word;
+ u16 mcs, real_mcs;
+ int aggr, ampdu;
++ int wcid;
+
+ /*
+ * Obtain the status about this packet.
+@@ -872,6 +874,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
+
+ real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
+ aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
++ wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);
+
+ /*
+ * If a frame was meant to be sent as a single non-aggregated MPDU
+@@ -1468,6 +1471,7 @@ int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif,
+ return 0;
+
+ __set_bit(wcid - WCID_START, drv_data->sta_ids);
++ drv_data->wcid_to_sta[wcid - WCID_START] = sta;
+
+ /*
+ * Clean up WCID attributes and write STA address to the device.
+@@ -1498,6 +1502,7 @@ int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, struct ieee80211_sta *sta)
+ * get renewed when the WCID is reused.
+ */
+ rt2800_config_wcid(rt2x00dev, NULL, wcid);
++ drv_data->wcid_to_sta[wcid - WCID_START] = NULL;
+ __clear_bit(wcid - WCID_START, drv_data->sta_ids);
+
+ return 0;
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+index 8e1ae138c3f1..6811d677a6e7 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -41,6 +41,7 @@ struct rt2800_drv_data {
+ unsigned int tbtt_tick;
+ unsigned int ampdu_factor_cnt[4];
+ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
++ struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE];
+ };
+
+ struct rt2800_ops {
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+index 22d18818e850..9b297fce4692 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+@@ -102,7 +102,7 @@ enum skb_frame_desc_flags {
+ * of the scope of the skb->data pointer.
+ * @iv: IV/EIV data used during encryption/decryption.
+ * @skb_dma: (PCI-only) the DMA address associated with the sk buffer.
+- * @entry: The entry to which this sk buffer belongs.
++ * @sta: The station where sk buffer was sent.
+ */
+ struct skb_frame_desc {
+ u8 flags;
+@@ -116,6 +116,7 @@ struct skb_frame_desc {
+ __le32 iv[2];
+
+ dma_addr_t skb_dma;
++ struct ieee80211_sta *sta;
+ };
+
+ /**
+--
+2.12.1
+
--- /dev/null
+From 5edb05afebba8f488a30db29550e55c42eea6d6a Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:06 +0100
+Subject: [PATCH 10/19] rt2x00: separte filling tx status from rt2x00lib_txdone
+
+This makes rt2x00lib_txdone a bit simpler and will allow to reuse code
+in different variant of txdone which I'm preparing.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 141 +++++++++++++------------
+ 1 file changed, 76 insertions(+), 65 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index dd6678109b7e..b5d90fefc96b 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -313,73 +313,14 @@ static inline int rt2x00lib_txdone_bar_status(struct queue_entry *entry)
+ return ret;
+ }
+
+-void rt2x00lib_txdone(struct queue_entry *entry,
+- struct txdone_entry_desc *txdesc)
++static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
++ struct ieee80211_tx_info *tx_info,
++ struct skb_frame_desc *skbdesc,
++ struct txdone_entry_desc *txdesc,
++ bool success)
+ {
+- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+- unsigned int header_length, i;
+ u8 rate_idx, rate_flags, retry_rates;
+- u8 skbdesc_flags = skbdesc->flags;
+- bool success;
+-
+- /*
+- * Unmap the skb.
+- */
+- rt2x00queue_unmap_skb(entry);
+-
+- /*
+- * Remove the extra tx headroom from the skb.
+- */
+- skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
+-
+- /*
+- * Signal that the TX descriptor is no longer in the skb.
+- */
+- skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
+-
+- /*
+- * Determine the length of 802.11 header.
+- */
+- header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+-
+- /*
+- * Remove L2 padding which was added during
+- */
+- if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD))
+- rt2x00queue_remove_l2pad(entry->skb, header_length);
+-
+- /*
+- * If the IV/EIV data was stripped from the frame before it was
+- * passed to the hardware, we should now reinsert it again because
+- * mac80211 will expect the same data to be present it the
+- * frame as it was passed to us.
+- */
+- if (rt2x00_has_cap_hw_crypto(rt2x00dev))
+- rt2x00crypto_tx_insert_iv(entry->skb, header_length);
+-
+- /*
+- * Send frame to debugfs immediately, after this call is completed
+- * we are going to overwrite the skb->cb array.
+- */
+- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
+-
+- /*
+- * Determine if the frame has been successfully transmitted and
+- * remove BARs from our check list while checking for their
+- * TX status.
+- */
+- success =
+- rt2x00lib_txdone_bar_status(entry) ||
+- test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
+- test_bit(TXDONE_UNKNOWN, &txdesc->flags);
+-
+- /*
+- * Update TX statistics.
+- */
+- rt2x00dev->link.qual.tx_success += success;
+- rt2x00dev->link.qual.tx_failed += !success;
++ int i;
+
+ rate_idx = skbdesc->tx_rate_idx;
+ rate_flags = skbdesc->tx_rate_flags;
+@@ -448,6 +389,76 @@ void rt2x00lib_txdone(struct queue_entry *entry,
+ else
+ rt2x00dev->low_level_stats.dot11RTSFailureCount++;
+ }
++}
++
++void rt2x00lib_txdone(struct queue_entry *entry,
++ struct txdone_entry_desc *txdesc)
++{
++ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
++ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
++ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
++ u8 skbdesc_flags = skbdesc->flags;
++ unsigned int header_length;
++ bool success;
++
++ /*
++ * Unmap the skb.
++ */
++ rt2x00queue_unmap_skb(entry);
++
++ /*
++ * Remove the extra tx headroom from the skb.
++ */
++ skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
++
++ /*
++ * Signal that the TX descriptor is no longer in the skb.
++ */
++ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
++
++ /*
++ * Determine the length of 802.11 header.
++ */
++ header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
++
++ /*
++ * Remove L2 padding which was added during
++ */
++ if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD))
++ rt2x00queue_remove_l2pad(entry->skb, header_length);
++
++ /*
++ * If the IV/EIV data was stripped from the frame before it was
++ * passed to the hardware, we should now reinsert it again because
++ * mac80211 will expect the same data to be present it the
++ * frame as it was passed to us.
++ */
++ if (rt2x00_has_cap_hw_crypto(rt2x00dev))
++ rt2x00crypto_tx_insert_iv(entry->skb, header_length);
++
++ /*
++ * Send frame to debugfs immediately, after this call is completed
++ * we are going to overwrite the skb->cb array.
++ */
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
++
++ /*
++ * Determine if the frame has been successfully transmitted and
++ * remove BARs from our check list while checking for their
++ * TX status.
++ */
++ success =
++ rt2x00lib_txdone_bar_status(entry) ||
++ test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
++ test_bit(TXDONE_UNKNOWN, &txdesc->flags);
++
++ /*
++ * Update TX statistics.
++ */
++ rt2x00dev->link.qual.tx_success += success;
++ rt2x00dev->link.qual.tx_failed += !success;
++
++ rt2x00lib_fill_tx_status(rt2x00dev, tx_info, skbdesc, txdesc, success);
+
+ /*
+ * Only send the status report to mac80211 when it's a frame
+--
+2.12.1
+
--- /dev/null
+From 56646adf9cd60b488ddc5633a2d9aa1f30efa5db Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:07 +0100
+Subject: [PATCH 11/19] rt2x00: separte clearing entry from rt2x00lib_txdone
+
+This makes rt2x00lib_txdone a bit simpler and will allow to reuse
+code in different variant of txdone which I'm preparing.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 51 +++++++++++++++-----------
+ 1 file changed, 29 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index b5d90fefc96b..03b368ac9cb6 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -391,6 +391,32 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
+ }
+ }
+
++static void rt2x00lib_clear_entry(struct rt2x00_dev *rt2x00dev,
++ struct queue_entry *entry)
++{
++ /*
++ * Make this entry available for reuse.
++ */
++ entry->skb = NULL;
++ entry->flags = 0;
++
++ rt2x00dev->ops->lib->clear_entry(entry);
++
++ rt2x00queue_index_inc(entry, Q_INDEX_DONE);
++
++ /*
++ * If the data queue was below the threshold before the txdone
++ * handler we must make sure the packet queue in the mac80211 stack
++ * is reenabled when the txdone handler has finished. This has to be
++ * serialized with rt2x00mac_tx(), otherwise we can wake up queue
++ * before it was stopped.
++ */
++ spin_lock_bh(&entry->queue->tx_lock);
++ if (!rt2x00queue_threshold(entry->queue))
++ rt2x00queue_unpause_queue(entry->queue);
++ spin_unlock_bh(&entry->queue->tx_lock);
++}
++
+ void rt2x00lib_txdone(struct queue_entry *entry,
+ struct txdone_entry_desc *txdesc)
+ {
+@@ -471,30 +497,11 @@ void rt2x00lib_txdone(struct queue_entry *entry,
+ ieee80211_tx_status(rt2x00dev->hw, entry->skb);
+ else
+ ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
+- } else
++ } else {
+ dev_kfree_skb_any(entry->skb);
++ }
+
+- /*
+- * Make this entry available for reuse.
+- */
+- entry->skb = NULL;
+- entry->flags = 0;
+-
+- rt2x00dev->ops->lib->clear_entry(entry);
+-
+- rt2x00queue_index_inc(entry, Q_INDEX_DONE);
+-
+- /*
+- * If the data queue was below the threshold before the txdone
+- * handler we must make sure the packet queue in the mac80211 stack
+- * is reenabled when the txdone handler has finished. This has to be
+- * serialized with rt2x00mac_tx(), otherwise we can wake up queue
+- * before it was stopped.
+- */
+- spin_lock_bh(&entry->queue->tx_lock);
+- if (!rt2x00queue_threshold(entry->queue))
+- rt2x00queue_unpause_queue(entry->queue);
+- spin_unlock_bh(&entry->queue->tx_lock);
++ rt2x00lib_clear_entry(rt2x00dev, entry);
+ }
+ EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
+
+--
+2.12.1
+
--- /dev/null
+From a09305d052166cb489402a63a5d275e954e0b923 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:08 +0100
+Subject: [PATCH 12/19] rt2x00: add txdone nomatch function
+
+This txdone nomatch function will be used when we get status from the HW,
+but we could not match it with any sent skb.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 ++
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 50 ++++++++++++++++++++++++++
+ 2 files changed, 52 insertions(+)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+index 340787894c69..91ba10fdf732 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -1425,6 +1425,8 @@ void rt2x00lib_dmastart(struct queue_entry *entry);
+ void rt2x00lib_dmadone(struct queue_entry *entry);
+ void rt2x00lib_txdone(struct queue_entry *entry,
+ struct txdone_entry_desc *txdesc);
++void rt2x00lib_txdone_nomatch(struct queue_entry *entry,
++ struct txdone_entry_desc *txdesc);
+ void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
+ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp);
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index 03b368ac9cb6..90fc259fb5bc 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -417,6 +417,56 @@ static void rt2x00lib_clear_entry(struct rt2x00_dev *rt2x00dev,
+ spin_unlock_bh(&entry->queue->tx_lock);
+ }
+
++void rt2x00lib_txdone_nomatch(struct queue_entry *entry,
++ struct txdone_entry_desc *txdesc)
++{
++ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
++ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
++ struct ieee80211_tx_info txinfo = {};
++ bool success;
++
++ /*
++ * Unmap the skb.
++ */
++ rt2x00queue_unmap_skb(entry);
++
++ /*
++ * Signal that the TX descriptor is no longer in the skb.
++ */
++ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
++
++ /*
++ * Send frame to debugfs immediately, after this call is completed
++ * we are going to overwrite the skb->cb array.
++ */
++ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
++
++ /*
++ * Determine if the frame has been successfully transmitted and
++ * remove BARs from our check list while checking for their
++ * TX status.
++ */
++ success =
++ rt2x00lib_txdone_bar_status(entry) ||
++ test_bit(TXDONE_SUCCESS, &txdesc->flags);
++
++ if (!test_bit(TXDONE_UNKNOWN, &txdesc->flags)) {
++ /*
++ * Update TX statistics.
++ */
++ rt2x00dev->link.qual.tx_success += success;
++ rt2x00dev->link.qual.tx_failed += !success;
++
++ rt2x00lib_fill_tx_status(rt2x00dev, &txinfo, skbdesc, txdesc,
++ success);
++ ieee80211_tx_status_noskb(rt2x00dev->hw, skbdesc->sta, &txinfo);
++ }
++
++ dev_kfree_skb_any(entry->skb);
++ rt2x00lib_clear_entry(rt2x00dev, entry);
++}
++EXPORT_SYMBOL_GPL(rt2x00lib_txdone_nomatch);
++
+ void rt2x00lib_txdone(struct queue_entry *entry,
+ struct txdone_entry_desc *txdesc)
+ {
+--
+2.12.1
+
--- /dev/null
+From ec80ad70d778af7665992672896633ebd3b02ac8 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:09 +0100
+Subject: [PATCH 13/19] rt2x00: fixup fill_tx_status for nomatch case
+
+Add bits rt2x00lib_fill_tx_status() when filling status in nomatch
+case and hopefully do not break the function for existing cases.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 6 +++++-
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 1 +
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index 90fc259fb5bc..e95d2aad3b3f 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -357,6 +357,9 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
+ if (i < (IEEE80211_TX_MAX_RATES - 1))
+ tx_info->status.rates[i].idx = -1; /* terminate */
+
++ if (test_bit(TXDONE_NO_ACK_REQ, &txdesc->flags))
++ tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
++
+ if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ if (success)
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+@@ -375,7 +378,8 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
+ */
+ if (test_bit(TXDONE_AMPDU, &txdesc->flags) ||
+ tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+- tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
++ tx_info->flags |= IEEE80211_TX_STAT_AMPDU |
++ IEEE80211_TX_CTL_AMPDU;
+ tx_info->status.ampdu_len = 1;
+ tx_info->status.ampdu_ack_len = success ? 1 : 0;
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+index 9b297fce4692..c78fb8c8838a 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+@@ -215,6 +215,7 @@ enum txdone_entry_desc_flags {
+ TXDONE_FAILURE,
+ TXDONE_EXCESSIVE_RETRY,
+ TXDONE_AMPDU,
++ TXDONE_NO_ACK_REQ,
+ };
+
+ /**
+--
+2.12.1
+
--- /dev/null
+From 293dff78ee058ec1e0b90e05a803c512b6a2097f Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:10 +0100
+Subject: [PATCH 14/19] rt2x00: use txdone_nomatch on rt2800usb
+
+If we do not match skb entry, provide tx status via nomatch procedure.
+
+Currently in that case we do rt2x00lib_txdone_noinfo(TXDONE_NOINFO),
+which actually assume that entry->skb was posted without retries and
+provide rate saved in skb desc as successful. Patch changed that to
+rate read from TX_STAT_FIFO, however still do not provide correct
+number of retries.
+
+On SoC/PCI devices we keep providing status via standard txdone
+procedure, no change in those devices, though we should thing about it.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 31 ++++++++++++++++++++-----
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 3 ++-
+ drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 18 ++++++--------
+ 4 files changed, 35 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 46405cce35e0..4a7bec708a13 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -852,7 +852,8 @@ void rt2800_process_rxwi(struct queue_entry *entry,
+ }
+ EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
+
+-void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
++void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
++ bool match)
+ {
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+@@ -860,8 +861,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
+ struct txdone_entry_desc txdesc;
+ u32 word;
+ u16 mcs, real_mcs;
+- int aggr, ampdu;
+- int wcid;
++ int aggr, ampdu, wcid, ack_req;
+
+ /*
+ * Obtain the status about this packet.
+@@ -875,6 +875,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
+ real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
+ aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
+ wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);
++ ack_req = rt2x00_get_field32(status, TX_STA_FIFO_TX_ACK_REQUIRED);
+
+ /*
+ * If a frame was meant to be sent as a single non-aggregated MPDU
+@@ -891,8 +892,12 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
+ * Hence, replace the requested rate with the real tx rate to not
+ * confuse the rate control algortihm by providing clearly wrong
+ * data.
+- */
+- if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) {
++ *
++ * FIXME: if we do not find matching entry, we tell that frame was
++ * posted without any retries. We need to find a way to fix that
++ * and provide retry count.
++ */
++ if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) {
+ skbdesc->tx_rate_idx = real_mcs;
+ mcs = real_mcs;
+ }
+@@ -900,6 +905,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
+ if (aggr == 1 || ampdu == 1)
+ __set_bit(TXDONE_AMPDU, &txdesc.flags);
+
++ if (!ack_req)
++ __set_bit(TXDONE_NO_ACK_REQ, &txdesc.flags);
++
+ /*
+ * Ralink has a retry mechanism using a global fallback
+ * table. We setup this fallback table to try the immediate
+@@ -931,7 +939,18 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
+ if (txdesc.retry)
+ __set_bit(TXDONE_FALLBACK, &txdesc.flags);
+
+- rt2x00lib_txdone(entry, &txdesc);
++ if (!match) {
++ /* RCU assures non-null sta will not be freed by mac80211. */
++ rcu_read_lock();
++ if (likely(wcid >= WCID_START && wcid <= WCID_END))
++ skbdesc->sta = drv_data->wcid_to_sta[wcid - WCID_START];
++ else
++ skbdesc->sta = NULL;
++ rt2x00lib_txdone_nomatch(entry, &txdesc);
++ rcu_read_unlock();
++ } else {
++ rt2x00lib_txdone(entry, &txdesc);
++ }
+ }
+ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+index 6811d677a6e7..d9ef260d542a 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -191,7 +191,8 @@ void rt2800_write_tx_data(struct queue_entry *entry,
+ struct txentry_desc *txdesc);
+ void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
+
+-void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32* txwi);
++void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
++ bool match);
+
+ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
+ void rt2800_clear_beacon(struct queue_entry *entry);
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+index de4790b41be7..3ab3b5323897 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+@@ -239,7 +239,7 @@ static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry,
+ {
+ if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
+ rt2800_txdone_entry(entry, entry->status,
+- rt2800mmio_get_txwi(entry));
++ rt2800mmio_get_txwi(entry), true);
+ return false;
+ }
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+index 205a7b8ac8a7..f11e3f532a84 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+@@ -501,8 +501,7 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+ /*
+ * TX control handlers
+ */
+-static enum txdone_entry_desc_flags
+-rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
++static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
+ {
+ __le32 *txwi;
+ u32 word;
+@@ -515,7 +514,7 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
+ * frame.
+ */
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+- return TXDONE_FAILURE;
++ return false;
+
+ wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
+ ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
+@@ -537,10 +536,10 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
+ rt2x00_dbg(entry->queue->rt2x00dev,
+ "TX status report missed for queue %d entry %d\n",
+ entry->queue->qid, entry->entry_idx);
+- return TXDONE_UNKNOWN;
++ return false;
+ }
+
+- return TXDONE_SUCCESS;
++ return true;
+ }
+
+ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
+@@ -549,7 +548,7 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
+ struct queue_entry *entry;
+ u32 reg;
+ u8 qid;
+- enum txdone_entry_desc_flags done_status;
++ bool match;
+
+ while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
+ /*
+@@ -574,11 +573,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
+ break;
+ }
+
+- done_status = rt2800usb_txdone_entry_check(entry, reg);
+- if (likely(done_status == TXDONE_SUCCESS))
+- rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry));
+- else
+- rt2x00lib_txdone_noinfo(entry, done_status);
++ match = rt2800usb_txdone_entry_check(entry, reg);
++ rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match);
+ }
+ }
+
+--
+2.12.1
+
--- /dev/null
+From 9d7a7a4d2b02bcd30fb5fe4270278212353cc332 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:11 +0100
+Subject: [PATCH 15/19] rt2800: status based rate flags for nomatch case
+
+We use skb_desc->tx_rate_flags from entry as rate[].flags even if
+skb does not match status. Patch corrects flags and also fixes
+mcs for legacy rates.
+
+rt2800_rate_from_status() is based on Felix's mt76
+mt76x2_mac_process_tx_rate() function.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800.h | 2 ++
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 35 +++++++++++++++++++++++++-
+ 2 files changed, 36 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+index 0e7051d8132f..480b08601785 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+@@ -1760,6 +1760,8 @@
+ #define TX_STA_FIFO_WCID FIELD32(0x0000ff00)
+ #define TX_STA_FIFO_SUCCESS_RATE FIELD32(0xffff0000)
+ #define TX_STA_FIFO_MCS FIELD32(0x007f0000)
++#define TX_STA_FIFO_BW FIELD32(0x00800000)
++#define TX_STA_FIFO_SGI FIELD32(0x01000000)
+ #define TX_STA_FIFO_PHYMODE FIELD32(0xc0000000)
+
+ /*
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 4a7bec708a13..8d00c599e47a 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -852,6 +852,39 @@ void rt2800_process_rxwi(struct queue_entry *entry,
+ }
+ EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
+
++static void rt2800_rate_from_status(struct skb_frame_desc *skbdesc,
++ u32 status, enum nl80211_band band)
++{
++ u8 flags = 0;
++ u8 idx = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
++
++ switch (rt2x00_get_field32(status, TX_STA_FIFO_PHYMODE)) {
++ case RATE_MODE_HT_GREENFIELD:
++ flags |= IEEE80211_TX_RC_GREEN_FIELD;
++ /* fall through */
++ case RATE_MODE_HT_MIX:
++ flags |= IEEE80211_TX_RC_MCS;
++ break;
++ case RATE_MODE_OFDM:
++ if (band == NL80211_BAND_2GHZ)
++ idx += 4;
++ break;
++ case RATE_MODE_CCK:
++ if (idx >= 8)
++ idx -= 8;
++ break;
++ }
++
++ if (rt2x00_get_field32(status, TX_STA_FIFO_BW))
++ flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
++
++ if (rt2x00_get_field32(status, TX_STA_FIFO_SGI))
++ flags |= IEEE80211_TX_RC_SHORT_GI;
++
++ skbdesc->tx_rate_idx = idx;
++ skbdesc->tx_rate_flags = flags;
++}
++
+ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
+ bool match)
+ {
+@@ -898,7 +931,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
+ * and provide retry count.
+ */
+ if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) {
+- skbdesc->tx_rate_idx = real_mcs;
++ rt2800_rate_from_status(skbdesc, status, rt2x00dev->curr_band);
+ mcs = real_mcs;
+ }
+
+--
+2.12.1
+
--- /dev/null
+From fb47ada8dc3c30c8e7b415da155742b49536c61e Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:12 +0100
+Subject: [PATCH 16/19] rt2800: use TXOP_BACKOFF for probe frames
+
+Even if we do not set AMPDU bit in TXWI, device still can aggregate
+frame and send it with rate not corresponding to requested. That mean
+we can do not sent probe frames with requested rate. To prevent that
+use TXOP_BACKOFF for probe frames.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+index e1660b92b20c..a2c1ca5c76d1 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+@@ -372,15 +372,16 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev,
+
+ /*
+ * Determine IFS values
+- * - Use TXOP_BACKOFF for management frames except beacons
++ * - Use TXOP_BACKOFF for probe and management frames except beacons
+ * - Use TXOP_SIFS for fragment bursts
+ * - Use TXOP_HTTXOP for everything else
+ *
+ * Note: rt2800 devices won't use CTS protection (if used)
+ * for frames not transmitted with TXOP_HTTXOP
+ */
+- if (ieee80211_is_mgmt(hdr->frame_control) &&
+- !ieee80211_is_beacon(hdr->frame_control))
++ if ((ieee80211_is_mgmt(hdr->frame_control) &&
++ !ieee80211_is_beacon(hdr->frame_control)) ||
++ (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
+ txdesc->u.ht.txop = TXOP_BACKOFF;
+ else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
+ txdesc->u.ht.txop = TXOP_SIFS;
+--
+2.12.1
+
--- /dev/null
+From dd35cc0896faff5ed9d22eac9ea4a1920e2eec0c Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 15 Feb 2017 10:25:13 +0100
+Subject: [PATCH 17/19] rt2x00: fix rt2x00debug_dump_frame comment
+
+Reported-by: Jeroen Roovers <jer@airfi.aero>
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+index 91ba10fdf732..ce340bfd71a0 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -1396,7 +1396,7 @@ void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop);
+ * rt2x00debug_dump_frame - Dump a frame to userspace through debugfs.
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @type: The type of frame that is being dumped.
+- * @skb: The skb containing the frame to be dumped.
++ * @entry: The queue entry containing the frame to be dumped.
+ */
+ #ifdef CPTCFG_RT2X00_LIB_DEBUGFS
+ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+--
+2.12.1
+
--- /dev/null
+From 5ce33b603063f36272fcfb1b4a5fde69f46eca88 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 9 Mar 2017 00:54:22 +0100
+Subject: [PATCH 18/19] rt2x00: fix TX_PWR_CFG_4 register definition
+
+Some of the macros used to describe the TX_PWR_CFG_4 register accidentally
+refer to TX_PWR_CFG_3, probably a copy&paste error. Fix that.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+index 480b08601785..fd1dbd956bad 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+@@ -1171,10 +1171,10 @@
+ #define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00)
+ #define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000)
+ /* bits for 3T devices */
+-#define TX_PWR_CFG_3_STBC4_CH0 FIELD32(0x0000000f)
+-#define TX_PWR_CFG_3_STBC4_CH1 FIELD32(0x000000f0)
+-#define TX_PWR_CFG_3_STBC6_CH0 FIELD32(0x00000f00)
+-#define TX_PWR_CFG_3_STBC6_CH1 FIELD32(0x0000f000)
++#define TX_PWR_CFG_4_STBC4_CH0 FIELD32(0x0000000f)
++#define TX_PWR_CFG_4_STBC4_CH1 FIELD32(0x000000f0)
++#define TX_PWR_CFG_4_STBC6_CH0 FIELD32(0x00000f00)
++#define TX_PWR_CFG_4_STBC6_CH1 FIELD32(0x0000f000)
+
+ /*
+ * TX_PIN_CFG:
+--
+2.12.1
+
--- /dev/null
+From 41977e86c984fcdddb454a3d7887de5d47b5f530 Mon Sep 17 00:00:00 2001
+From: Roman Yeryomin <roman@advem.lv>
+Date: Tue, 21 Mar 2017 00:43:00 +0100
+Subject: [PATCH 19/19] rt2x00: add support for MT7620
+
+Basic support for MT7620 built-in wireless radio was added to
+OpenWrt in r41441. It has seen some heavy cleaning and refactoring
+since in order to match the Kernel's code quality standards.
+
+Signed-off-by: Roman Yeryomin <roman@advem.lv>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +-
+ drivers/net/wireless/ralink/rt2x00/rt2800.h | 177 +++
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1421 +++++++++++++++++++++++-
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 4 +
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
+ 5 files changed, 1578 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/Kconfig b/drivers/net/wireless/ralink/rt2x00/Kconfig
+index de62f5dcb62f..a1d1cfe214d2 100644
+--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
+@@ -210,7 +210,7 @@ endif
+ config RT2800SOC
+ tristate "Ralink WiSoC support"
+ depends on m
+- depends on SOC_RT288X || SOC_RT305X
++ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
+ select RT2X00_LIB_SOC
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_CRYPTO
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+index fd1dbd956bad..6a8c93fb6a43 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
+@@ -79,6 +79,7 @@
+ #define RF5372 0x5372
+ #define RF5390 0x5390
+ #define RF5392 0x5392
++#define RF7620 0x7620
+
+ /*
+ * Chipset revisions.
+@@ -639,6 +640,24 @@
+ #define RF_CSR_CFG_BUSY FIELD32(0x00020000)
+
+ /*
++ * MT7620 RF registers (reversed order)
++ */
++#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00)
++#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000)
++#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010)
++#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001)
++
++/* undocumented registers for calibration of new MAC */
++#define RF_CONTROL0 0x0518
++#define RF_BYPASS0 0x051c
++#define RF_CONTROL1 0x0520
++#define RF_BYPASS1 0x0524
++#define RF_CONTROL2 0x0528
++#define RF_BYPASS2 0x052c
++#define RF_CONTROL3 0x0530
++#define RF_BYPASS3 0x0534
++
++/*
+ * EFUSE_CSR: RT30x0 EEPROM
+ */
+ #define EFUSE_CTRL 0x0580
+@@ -1022,6 +1041,16 @@
+ #define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000)
+
+ /*
++ * MIMO_PS_CFG: MIMO Power-save Configuration
++ */
++#define MIMO_PS_CFG 0x1210
++#define MIMO_PS_CFG_MMPS_BB_EN FIELD32(0x00000001)
++#define MIMO_PS_CFG_MMPS_RX_ANT_NUM FIELD32(0x00000006)
++#define MIMO_PS_CFG_MMPS_RF_EN FIELD32(0x00000008)
++#define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010)
++#define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020)
++
++/*
+ * EDCA_AC0_CFG:
+ */
+ #define EDCA_AC0_CFG 0x1300
+@@ -1095,6 +1124,12 @@
+ #define TX_PWR_CFG_0_OFDM6_CH1 FIELD32(0x00f00000)
+ #define TX_PWR_CFG_0_OFDM12_CH0 FIELD32(0x0f000000)
+ #define TX_PWR_CFG_0_OFDM12_CH1 FIELD32(0xf0000000)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_0B_1MBS_2MBS FIELD32(0x000000ff)
++#define TX_PWR_CFG_0B_5MBS_11MBS FIELD32(0x0000ff00)
++#define TX_PWR_CFG_0B_6MBS_9MBS FIELD32(0x00ff0000)
++#define TX_PWR_CFG_0B_12MBS_18MBS FIELD32(0xff000000)
++
+
+ /*
+ * TX_PWR_CFG_1:
+@@ -1117,6 +1152,11 @@
+ #define TX_PWR_CFG_1_MCS0_CH1 FIELD32(0x00f00000)
+ #define TX_PWR_CFG_1_MCS2_CH0 FIELD32(0x0f000000)
+ #define TX_PWR_CFG_1_MCS2_CH1 FIELD32(0xf0000000)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_1B_24MBS_36MBS FIELD32(0x000000ff)
++#define TX_PWR_CFG_1B_48MBS FIELD32(0x0000ff00)
++#define TX_PWR_CFG_1B_MCS0_MCS1 FIELD32(0x00ff0000)
++#define TX_PWR_CFG_1B_MCS2_MCS3 FIELD32(0xff000000)
+
+ /*
+ * TX_PWR_CFG_2:
+@@ -1139,6 +1179,11 @@
+ #define TX_PWR_CFG_2_MCS8_CH1 FIELD32(0x00f00000)
+ #define TX_PWR_CFG_2_MCS10_CH0 FIELD32(0x0f000000)
+ #define TX_PWR_CFG_2_MCS10_CH1 FIELD32(0xf0000000)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_2B_MCS4_MCS5 FIELD32(0x000000ff)
++#define TX_PWR_CFG_2B_MCS6_MCS7 FIELD32(0x0000ff00)
++#define TX_PWR_CFG_2B_MCS8_MCS9 FIELD32(0x00ff0000)
++#define TX_PWR_CFG_2B_MCS10_MCS11 FIELD32(0xff000000)
+
+ /*
+ * TX_PWR_CFG_3:
+@@ -1161,6 +1206,11 @@
+ #define TX_PWR_CFG_3_STBC0_CH1 FIELD32(0x00f00000)
+ #define TX_PWR_CFG_3_STBC2_CH0 FIELD32(0x0f000000)
+ #define TX_PWR_CFG_3_STBC2_CH1 FIELD32(0xf0000000)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_3B_MCS12_MCS13 FIELD32(0x000000ff)
++#define TX_PWR_CFG_3B_MCS14 FIELD32(0x0000ff00)
++#define TX_PWR_CFG_3B_STBC_MCS0_MCS1 FIELD32(0x00ff0000)
++#define TX_PWR_CFG_3B_STBC_MCS2_MSC3 FIELD32(0xff000000)
+
+ /*
+ * TX_PWR_CFG_4:
+@@ -1175,6 +1225,9 @@
+ #define TX_PWR_CFG_4_STBC4_CH1 FIELD32(0x000000f0)
+ #define TX_PWR_CFG_4_STBC6_CH0 FIELD32(0x00000f00)
+ #define TX_PWR_CFG_4_STBC6_CH1 FIELD32(0x0000f000)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_4B_STBC_MCS4_MCS5 FIELD32(0x000000ff)
++#define TX_PWR_CFG_4B_STBC_MCS6 FIELD32(0x0000ff00)
+
+ /*
+ * TX_PIN_CFG:
+@@ -1201,6 +1254,8 @@
+ #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000)
+ #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000)
+ #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000)
++#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000)
++#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000)
+ #define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000)
+ #define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000)
+ #define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000)
+@@ -1547,6 +1602,95 @@
+ #define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f)
+ #define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00)
+
++/* TXn_RF_GAIN_CORRECT: RF Gain Correction for each RF_ALC[3:2]
++ * Unit: 0.1 dB, Range: -3.2 dB to 3.1 dB
++ */
++#define TX0_RF_GAIN_CORRECT 0x13a0
++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f)
++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00)
++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000)
++#define TX0_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000)
++
++#define TX1_RF_GAIN_CORRECT 0x13a4
++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_0 FIELD32(0x0000003f)
++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_1 FIELD32(0x00003f00)
++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_2 FIELD32(0x003f0000)
++#define TX1_RF_GAIN_CORRECT_GAIN_CORR_3 FIELD32(0x3f000000)
++
++/* TXn_RF_GAIN_ATTEN: TXn RF Gain Attenuation Level
++ * Format: 7-bit, signed value
++ * Unit: 0.5 dB, Range: -20 dB to -5 dB
++ */
++#define TX0_RF_GAIN_ATTEN 0x13a8
++#define TX0_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f)
++#define TX0_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00)
++#define TX0_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000)
++#define TX0_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000)
++#define TX1_RF_GAIN_ATTEN 0x13ac
++#define TX1_RF_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000007f)
++#define TX1_RF_GAIN_ATTEN_LEVEL_1 FIELD32(0x00007f00)
++#define TX1_RF_GAIN_ATTEN_LEVEL_2 FIELD32(0x007f0000)
++#define TX1_RF_GAIN_ATTEN_LEVEL_3 FIELD32(0x7f000000)
++
++/* TX_ALC_CFG_0: TX Automatic Level Control Configuration 0
++ * TX_ALC_LIMIT_n: TXn upper limit
++ * TX_ALC_CH_INIT_n: TXn channel initial transmission gain
++ * Unit: 0.5 dB, Range: 0 to 23.5 dB
++ */
++#define TX_ALC_CFG_0 0x13b0
++#define TX_ALC_CFG_0_CH_INIT_0 FIELD32(0x0000003f)
++#define TX_ALC_CFG_0_CH_INIT_1 FIELD32(0x00003f00)
++#define TX_ALC_CFG_0_LIMIT_0 FIELD32(0x003f0000)
++#define TX_ALC_CFG_0_LIMIT_1 FIELD32(0x3f000000)
++
++/* TX_ALC_CFG_1: TX Automatic Level Control Configuration 1
++ * TX_TEMP_COMP: TX Power Temperature Compensation
++ * Unit: 0.5 dB, Range: -10 dB to 10 dB
++ * TXn_GAIN_FINE: TXn Gain Fine Adjustment
++ * Unit: 0.1 dB, Range: -0.8 dB to 0.7 dB
++ * RF_TOS_DLY: Sets the RF_TOS_EN assertion delay after
++ * deassertion of PA_PE.
++ * Unit: 0.25 usec
++ * TXn_RF_GAIN_ATTEN: TXn RF gain attentuation selector
++ * RF_TOS_TIMEOUT: time-out value for RF_TOS_ENABLE
++ * deassertion if RF_TOS_DONE is missing.
++ * Unit: 0.25 usec
++ * RF_TOS_ENABLE: TX offset calibration enable
++ * ROS_BUSY_EN: RX offset calibration busy enable
++ */
++#define TX_ALC_CFG_1 0x13b4
++#define TX_ALC_CFG_1_TX_TEMP_COMP FIELD32(0x0000003f)
++#define TX_ALC_CFG_1_TX0_GAIN_FINE FIELD32(0x00000f00)
++#define TX_ALC_CFG_1_TX1_GAIN_FINE FIELD32(0x0000f000)
++#define TX_ALC_CFG_1_RF_TOS_DLY FIELD32(0x00070000)
++#define TX_ALC_CFG_1_TX0_RF_GAIN_ATTEN FIELD32(0x00300000)
++#define TX_ALC_CFG_1_TX1_RF_GAIN_ATTEN FIELD32(0x00c00000)
++#define TX_ALC_CFG_1_RF_TOS_TIMEOUT FIELD32(0x3f000000)
++#define TX_ALC_CFG_1_RF_TOS_ENABLE FIELD32(0x40000000)
++#define TX_ALC_CFG_1_ROS_BUSY_EN FIELD32(0x80000000)
++
++/* TXn_BB_GAIN_ATTEN: TXn RF Gain Attenuation Level
++ * Format: 5-bit signed values
++ * Unit: 0.5 dB, Range: -8 dB to 7 dB
++ */
++#define TX0_BB_GAIN_ATTEN 0x13c0
++#define TX0_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f)
++#define TX0_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00)
++#define TX0_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000)
++#define TX0_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000)
++#define TX1_BB_GAIN_ATTEN 0x13c4
++#define TX1_BB_GAIN_ATTEN_LEVEL_0 FIELD32(0x0000001f)
++#define TX1_BB_GAIN_ATTEN_LEVEL_1 FIELD32(0x00001f00)
++#define TX1_BB_GAIN_ATTEN_LEVEL_2 FIELD32(0x001f0000)
++#define TX1_BB_GAIN_ATTEN_LEVEL_3 FIELD32(0x1f000000)
++
++/* TX_ALC_VGA3: TX Automatic Level Correction Variable Gain Amplifier 3 */
++#define TX_ALC_VGA3 0x13c8
++#define TX_ALC_VGA3_TX0_ALC_VGA3 FIELD32(0x0000001f)
++#define TX_ALC_VGA3_TX1_ALC_VGA3 FIELD32(0x00001f00)
++#define TX_ALC_VGA3_TX0_ALC_VGA2 FIELD32(0x001f0000)
++#define TX_ALC_VGA3_TX1_ALC_VGA2 FIELD32(0x1f000000)
++
+ /* TX_PWR_CFG_7 */
+ #define TX_PWR_CFG_7 0x13d4
+ #define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f)
+@@ -1555,6 +1699,10 @@
+ #define TX_PWR_CFG_7_MCS7_CH0 FIELD32(0x000f0000)
+ #define TX_PWR_CFG_7_MCS7_CH1 FIELD32(0x00f00000)
+ #define TX_PWR_CFG_7_MCS7_CH2 FIELD32(0x0f000000)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_7B_54MBS FIELD32(0x000000ff)
++#define TX_PWR_CFG_7B_MCS7 FIELD32(0x00ff0000)
++
+
+ /* TX_PWR_CFG_8 */
+ #define TX_PWR_CFG_8 0x13d8
+@@ -1564,12 +1712,17 @@
+ #define TX_PWR_CFG_8_MCS23_CH0 FIELD32(0x000f0000)
+ #define TX_PWR_CFG_8_MCS23_CH1 FIELD32(0x00f00000)
+ #define TX_PWR_CFG_8_MCS23_CH2 FIELD32(0x0f000000)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_8B_MCS15 FIELD32(0x000000ff)
++
+
+ /* TX_PWR_CFG_9 */
+ #define TX_PWR_CFG_9 0x13dc
+ #define TX_PWR_CFG_9_STBC7_CH0 FIELD32(0x0000000f)
+ #define TX_PWR_CFG_9_STBC7_CH1 FIELD32(0x000000f0)
+ #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00)
++/* bits for new 2T devices */
++#define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff)
+
+ /*
+ * RX_FILTER_CFG: RX configuration register.
+@@ -2137,11 +2290,14 @@ struct mac_iveiv_entry {
+ #define RFCSR1_TX1_PD FIELD8(0x20)
+ #define RFCSR1_RX2_PD FIELD8(0x40)
+ #define RFCSR1_TX2_PD FIELD8(0x80)
++#define RFCSR1_TX2_EN_MT7620 FIELD8(0x02)
+
+ /*
+ * RFCSR 2:
+ */
+ #define RFCSR2_RESCAL_EN FIELD8(0x80)
++#define RFCSR2_RX2_EN_MT7620 FIELD8(0x02)
++#define RFCSR2_TX2_EN_MT7620 FIELD8(0x20)
+
+ /*
+ * RFCSR 3:
+@@ -2160,6 +2316,12 @@ struct mac_iveiv_entry {
+ #define RFCSR3_BIT5 FIELD8(0x20)
+
+ /*
++ * RFCSR 4:
++ * VCOCAL_EN used by MT7620
++ */
++#define RFCSR4_VCOCAL_EN FIELD8(0x80)
++
++/*
+ * FRCSR 5:
+ */
+ #define RFCSR5_R1 FIELD8(0x0c)
+@@ -2214,6 +2376,7 @@ struct mac_iveiv_entry {
+ */
+ #define RFCSR13_TX_POWER FIELD8(0x1f)
+ #define RFCSR13_DR0 FIELD8(0xe0)
++#define RFCSR13_RDIV_MT7620 FIELD8(0x03)
+
+ /*
+ * RFCSR 15:
+@@ -2224,6 +2387,8 @@ struct mac_iveiv_entry {
+ * RFCSR 16:
+ */
+ #define RFCSR16_TXMIXER_GAIN FIELD8(0x07)
++#define RFCSR16_RF_PLL_FREQ_SEL_MT7620 FIELD8(0x0F)
++#define RFCSR16_SDM_MODE_MT7620 FIELD8(0xE0)
+
+ /*
+ * RFCSR 17:
+@@ -2236,6 +2401,8 @@ struct mac_iveiv_entry {
+ /* RFCSR 18 */
+ #define RFCSR18_XO_TUNE_BYPASS FIELD8(0x40)
+
++/* RFCSR 19 */
++#define RFCSR19_K FIELD8(0x03)
+
+ /*
+ * RFCSR 20:
+@@ -2246,11 +2413,14 @@ struct mac_iveiv_entry {
+ * RFCSR 21:
+ */
+ #define RFCSR21_RX_LO2_EN FIELD8(0x08)
++#define RFCSR21_BIT1 FIELD8(0x01)
++#define RFCSR21_BIT8 FIELD8(0x80)
+
+ /*
+ * RFCSR 22:
+ */
+ #define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01)
++#define RFCSR22_FREQPLAN_D_MT7620 FIELD8(0x07)
+
+ /*
+ * RFCSR 23:
+@@ -2273,6 +2443,11 @@ struct mac_iveiv_entry {
+ #define RFCSR27_R4 FIELD8(0x40)
+
+ /*
++ * RFCSR 28:
++ */
++#define RFCSR28_CH11_HT40 FIELD8(0x04)
++
++/*
+ * RFCSR 29:
+ */
+ #define RFCSR29_ADC6_TEST FIELD8(0x01)
+@@ -2333,6 +2508,7 @@ struct mac_iveiv_entry {
+ */
+ #define RFCSR42_BIT1 FIELD8(0x01)
+ #define RFCSR42_BIT4 FIELD8(0x08)
++#define RFCSR42_TX2_EN_MT7620 FIELD8(0x40)
+
+ /*
+ * RFCSR 49:
+@@ -2435,6 +2611,7 @@ enum rt2800_eeprom_word {
+ EEPROM_TSSI_BOUND_BG5,
+ EEPROM_TXPOWER_A1,
+ EEPROM_TXPOWER_A2,
++ EEPROM_TXPOWER_INIT,
+ EEPROM_TSSI_BOUND_A1,
+ EEPROM_TSSI_BOUND_A2,
+ EEPROM_TSSI_BOUND_A3,
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 8d00c599e47a..201b12ed90c6 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -59,6 +59,9 @@
+ rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
+ #define WAIT_FOR_RFCSR(__dev, __reg) \
+ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
++#define WAIT_FOR_RFCSR_MT7620(__dev, __reg) \
++ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY_MT7620, \
++ (__reg))
+ #define WAIT_FOR_RF(__dev, __reg) \
+ rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
+ #define WAIT_FOR_MCU(__dev, __reg) \
+@@ -150,19 +153,56 @@ static void rt2800_rfcsr_write(struct rt2x00_dev *rt2x00dev,
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
+- reg = 0;
+- rt2x00_set_field32(®, RF_CSR_CFG_DATA, value);
+- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
+- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1);
+- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
++ switch (rt2x00dev->chip.rt) {
++ case RT6352:
++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) {
++ reg = 0;
++ rt2x00_set_field32(®, RF_CSR_CFG_DATA_MT7620, value);
++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620,
++ word);
++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 1);
++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1);
++
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ }
++ break;
+
+- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ default:
++ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
++ reg = 0;
++ rt2x00_set_field32(®, RF_CSR_CFG_DATA, value);
++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1);
++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
++
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ }
++ break;
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+ }
+
++static void rt2800_rfcsr_write_bank(struct rt2x00_dev *rt2x00dev, const u8 bank,
++ const unsigned int reg, const u8 value)
++{
++ rt2800_rfcsr_write(rt2x00dev, (reg | (bank << 6)), value);
++}
++
++static void rt2800_rfcsr_write_chanreg(struct rt2x00_dev *rt2x00dev,
++ const unsigned int reg, const u8 value)
++{
++ rt2800_rfcsr_write_bank(rt2x00dev, 4, reg, value);
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, reg, value);
++}
++
++static void rt2800_rfcsr_write_dccal(struct rt2x00_dev *rt2x00dev,
++ const unsigned int reg, const u8 value)
++{
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, reg, value);
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value);
++}
++
+ static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+ {
+@@ -178,22 +218,48 @@ static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+ * doesn't become available in time, reg will be 0xffffffff
+ * which means we return 0xff to the caller.
+ */
+- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
+- reg = 0;
+- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
+- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0);
+- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
++ switch (rt2x00dev->chip.rt) {
++ case RT6352:
++ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) {
++ reg = 0;
++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620,
++ word);
++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 0);
++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1);
+
+- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
+
+- WAIT_FOR_RFCSR(rt2x00dev, ®);
+- }
++ WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®);
++ }
+
+- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA_MT7620);
++ break;
++
++ default:
++ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
++ reg = 0;
++ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
++ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0);
++ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
++
++ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
++
++ WAIT_FOR_RFCSR(rt2x00dev, ®);
++ }
++
++ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
++ break;
++ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+ }
+
++static void rt2800_rfcsr_read_bank(struct rt2x00_dev *rt2x00dev, const u8 bank,
++ const unsigned int reg, u8 *value)
++{
++ rt2800_rfcsr_read(rt2x00dev, (reg | (bank << 6)), value);
++}
++
+ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u32 value)
+ {
+@@ -250,6 +316,7 @@ static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
+ [EEPROM_TSSI_BOUND_BG5] = 0x003b,
+ [EEPROM_TXPOWER_A1] = 0x003c,
+ [EEPROM_TXPOWER_A2] = 0x0053,
++ [EEPROM_TXPOWER_INIT] = 0x0068,
+ [EEPROM_TSSI_BOUND_A1] = 0x006a,
+ [EEPROM_TSSI_BOUND_A2] = 0x006b,
+ [EEPROM_TSSI_BOUND_A3] = 0x006c,
+@@ -524,6 +591,7 @@ void rt2800_get_txwi_rxwi_size(struct rt2x00_dev *rt2x00dev,
+ break;
+
+ case RT5592:
++ case RT6352:
+ *txwi_size = TXWI_DESC_SIZE_5WORDS;
+ *rxwi_size = RXWI_DESC_SIZE_6WORDS;
+ break;
+@@ -2810,7 +2878,8 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
+ rt2800_rfcsr_write(rt2x00dev, 59,
+ r59_nonbt_rev[idx]);
+ } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+- rt2x00_rt(rt2x00dev, RT5392)) {
++ rt2x00_rt(rt2x00dev, RT5392) ||
++ rt2x00_rt(rt2x00dev, RT6352)) {
+ static const char r59_non_bt[] = {0x8f, 0x8f,
+ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
+ 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
+@@ -3104,6 +3173,242 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
+ rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F);
+ }
+
++static void rt2800_config_channel_rf7620(struct rt2x00_dev *rt2x00dev,
++ struct ieee80211_conf *conf,
++ struct rf_channel *rf,
++ struct channel_info *info)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++ u8 rx_agc_fc, tx_agc_fc;
++ u8 rfcsr;
++
++ /* Frequeny plan setting */
++ /* Rdiv setting (set 0x03 if Xtal==20)
++ * R13[1:0]
++ */
++ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR13_RDIV_MT7620,
++ rt2800_clk_is_20mhz(rt2x00dev) ? 3 : 0);
++ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
++
++ /* N setting
++ * R20[7:0] in rf->rf1
++ * R21[0] always 0
++ */
++ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
++ rfcsr = (rf->rf1 & 0x00ff);
++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR21_BIT1, 0);
++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
++
++ /* K setting (always 0)
++ * R16[3:0] (RF PLL freq selection)
++ */
++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR16_RF_PLL_FREQ_SEL_MT7620, 0);
++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
++
++ /* D setting (always 0)
++ * R22[2:0] (D=15, R22[2:0]=<111>)
++ */
++ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR22_FREQPLAN_D_MT7620, 0);
++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
++
++ /* Ksd setting
++ * Ksd: R17<7:0> in rf->rf2
++ * R18<7:0> in rf->rf3
++ * R19<1:0> in rf->rf4
++ */
++ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
++ rfcsr = rf->rf2;
++ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr);
++ rfcsr = rf->rf3;
++ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 19, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4);
++ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr);
++
++ /* Default: XO=20MHz , SDM mode */
++ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1);
++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620,
++ rt2x00dev->default_ant.tx_chain_num != 1);
++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR2_TX2_EN_MT7620,
++ rt2x00dev->default_ant.tx_chain_num != 1);
++ rt2x00_set_field8(&rfcsr, RFCSR2_RX2_EN_MT7620,
++ rt2x00dev->default_ant.rx_chain_num != 1);
++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
++
++ rt2800_rfcsr_read(rt2x00dev, 42, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR42_TX2_EN_MT7620,
++ rt2x00dev->default_ant.tx_chain_num != 1);
++ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr);
++
++ /* RF for DC Cal BW */
++ if (conf_is_ht40(conf)) {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10);
++ } else {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20);
++ }
++
++ if (conf_is_ht40(conf)) {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
++ } else {
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
++ }
++
++ rt2800_rfcsr_read(rt2x00dev, 28, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40,
++ conf_is_ht40(conf) && (rf->channel == 11));
++ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
++
++ if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) {
++ if (conf_is_ht40(conf)) {
++ rx_agc_fc = drv_data->rx_calibration_bw40;
++ tx_agc_fc = drv_data->tx_calibration_bw40;
++ } else {
++ rx_agc_fc = drv_data->rx_calibration_bw20;
++ tx_agc_fc = drv_data->tx_calibration_bw20;
++ }
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= rx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= rx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 6, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= rx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 6, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 7, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= rx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 7, rfcsr);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= tx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= tx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 58, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= tx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 58, rfcsr);
++ rt2800_rfcsr_read_bank(rt2x00dev, 7, 59, &rfcsr);
++ rfcsr &= (~0x3F);
++ rfcsr |= tx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
++ }
++}
++
++static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev,
++ struct ieee80211_channel *chan,
++ int power_level) {
++ u16 eeprom, target_power, max_power;
++ u32 mac_sys_ctrl, mac_status;
++ u32 reg;
++ u8 bbp;
++ int i;
++
++ /* hardware unit is 0.5dBm, limited to 23.5dBm */
++ power_level *= 2;
++ if (power_level > 0x2f)
++ power_level = 0x2f;
++
++ max_power = chan->max_power * 2;
++ if (max_power > 0x2f)
++ max_power = 0x2f;
++
++ rt2800_register_read(rt2x00dev, TX_ALC_CFG_0, ®);
++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, power_level);
++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, power_level);
++ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_0, max_power);
++ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_1, max_power);
++
++ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
++ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) {
++ /* init base power by eeprom target power */
++ rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_INIT,
++ &target_power);
++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, target_power);
++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, target_power);
++ }
++ rt2800_register_write(rt2x00dev, TX_ALC_CFG_0, reg);
++
++ rt2800_register_read(rt2x00dev, TX_ALC_CFG_1, ®);
++ rt2x00_set_field32(®, TX_ALC_CFG_1_TX_TEMP_COMP, 0);
++ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg);
++
++ /* Save MAC SYS CTRL registers */
++ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &mac_sys_ctrl);
++ /* Disable Tx/Rx */
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
++ /* Check MAC Tx/Rx idle */
++ for (i = 0; i < 10000; i++) {
++ rt2800_register_read(rt2x00dev, MAC_STATUS_CFG,
++ &mac_status);
++ if (mac_status & 0x3)
++ usleep_range(50, 200);
++ else
++ break;
++ }
++
++ if (i == 10000)
++ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
++
++ if (chan->center_freq > 2457) {
++ rt2800_bbp_read(rt2x00dev, 30, &bbp);
++ bbp = 0x40;
++ rt2800_bbp_write(rt2x00dev, 30, bbp);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0);
++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
++ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
++ } else {
++ rt2800_bbp_read(rt2x00dev, 30, &bbp);
++ bbp = 0x1f;
++ rt2800_bbp_write(rt2x00dev, 30, bbp);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
++ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
++ }
++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
++}
++
+ static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word,
+ const u8 value)
+@@ -3228,7 +3533,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ struct channel_info *info)
+ {
+ u32 reg;
+- unsigned int tx_pin;
++ u32 tx_pin;
+ u8 bbp, rfcsr;
+
+ info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
+@@ -3273,6 +3578,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ case RF5592:
+ rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info);
+ break;
++ case RF7620:
++ rt2800_config_channel_rf7620(rt2x00dev, conf, rf, info);
++ break;
+ default:
+ rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
+ }
+@@ -3347,7 +3655,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+
+ if (rf->channel <= 14) {
+ if (!rt2x00_rt(rt2x00dev, RT5390) &&
+- !rt2x00_rt(rt2x00dev, RT5392)) {
++ !rt2x00_rt(rt2x00dev, RT5392) &&
++ !rt2x00_rt(rt2x00dev, RT6352)) {
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+ rt2800_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800_bbp_write(rt2x00dev, 75, 0x46);
+@@ -3367,7 +3676,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ rt2800_bbp_write(rt2x00dev, 82, 0x94);
+ else if (rt2x00_rt(rt2x00dev, RT3593))
+ rt2800_bbp_write(rt2x00dev, 82, 0x82);
+- else
++ else if (!rt2x00_rt(rt2x00dev, RT6352))
+ rt2800_bbp_write(rt2x00dev, 82, 0xf2);
+
+ if (rt2x00_rt(rt2x00dev, RT3593))
+@@ -3388,7 +3697,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ if (rt2x00_rt(rt2x00dev, RT3572))
+ rt2800_rfcsr_write(rt2x00dev, 8, 0);
+
+- tx_pin = 0;
++ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
+
+ switch (rt2x00dev->default_ant.tx_chain_num) {
+ case 3:
+@@ -3437,6 +3746,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */
+
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+@@ -3495,7 +3805,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ usleep_range(1000, 1500);
+ }
+
+- if (rt2x00_rt(rt2x00dev, RT5592)) {
++ if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) {
+ rt2800_bbp_write(rt2x00dev, 195, 141);
+ rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
+
+@@ -4182,6 +4492,128 @@ static void rt2800_config_txpower_rt3593(struct rt2x00_dev *rt2x00dev,
+ (unsigned long) regs[i]);
+ }
+
++static void rt2800_config_txpower_rt6352(struct rt2x00_dev *rt2x00dev,
++ struct ieee80211_channel *chan,
++ int power_level)
++{
++ u32 reg, pwreg;
++ u16 eeprom;
++ u32 data, gdata;
++ u8 t, i;
++ enum nl80211_band band = chan->band;
++ int delta;
++
++ /* Warn user if bw_comp is set in EEPROM */
++ delta = rt2800_get_txpower_bw_comp(rt2x00dev, band);
++
++ if (delta)
++ rt2x00_warn(rt2x00dev, "ignoring EEPROM HT40 power delta: %d\n",
++ delta);
++
++ /* populate TX_PWR_CFG_0 up to TX_PWR_CFG_4 from EEPROM for HT20, limit
++ * value to 0x3f and replace 0x20 by 0x21 as this is what the vendor
++ * driver does as well, though it looks kinda wrong.
++ * Maybe some misunderstanding of what a signed 8-bit value is? Maybe
++ * the hardware has a problem handling 0x20, and as the code initially
++ * used a fixed offset between HT20 and HT40 rates they had to work-
++ * around that issue and most likely just forgot about it later on.
++ * Maybe we should use rt2800_get_txpower_bw_comp() here as well,
++ * however, the corresponding EEPROM value is not respected by the
++ * vendor driver, so maybe this is rather being taken care of the
++ * TXALC and the driver doesn't need to handle it...?
++ * Though this is all very awkward, just do as they did, as that's what
++ * board vendors expected when they populated the EEPROM...
++ */
++ for (i = 0; i < 5; i++) {
++ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++ i * 2, &eeprom);
++
++ data = eeprom;
++
++ t = eeprom & 0x3f;
++ if (t == 32)
++ t++;
++
++ gdata = t;
++
++ t = (eeprom & 0x3f00) >> 8;
++ if (t == 32)
++ t++;
++
++ gdata |= (t << 8);
++
++ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
++ (i * 2) + 1, &eeprom);
++
++ t = eeprom & 0x3f;
++ if (t == 32)
++ t++;
++
++ gdata |= (t << 16);
++
++ t = (eeprom & 0x3f00) >> 8;
++ if (t == 32)
++ t++;
++
++ gdata |= (t << 24);
++ data |= (eeprom << 16);
++
++ if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) {
++ /* HT20 */
++ if (data != 0xffffffff)
++ rt2800_register_write(rt2x00dev,
++ TX_PWR_CFG_0 + (i * 4),
++ data);
++ } else {
++ /* HT40 */
++ if (gdata != 0xffffffff)
++ rt2800_register_write(rt2x00dev,
++ TX_PWR_CFG_0 + (i * 4),
++ gdata);
++ }
++ }
++
++ /* Aparently Ralink ran out of space in the BYRATE calibration section
++ * of the EERPOM which is copied to the corresponding TX_PWR_CFG_x
++ * registers. As recent 2T chips use 8-bit instead of 4-bit values for
++ * power-offsets more space would be needed. Ralink decided to keep the
++ * EEPROM layout untouched and rather have some shared values covering
++ * multiple bitrates.
++ * Populate the registers not covered by the EEPROM in the same way the
++ * vendor driver does.
++ */
++
++ /* For OFDM 54MBS use value from OFDM 48MBS */
++ pwreg = 0;
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_1B_48MBS);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_54MBS, t);
++
++ /* For MCS 7 use value from MCS 6 */
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_2B_MCS6_MCS7);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_7B_MCS7, t);
++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_7, pwreg);
++
++ /* For MCS 15 use value from MCS 14 */
++ pwreg = 0;
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_3B_MCS14);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_8B_MCS15, t);
++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_8, pwreg);
++
++ /* For STBC MCS 7 use value from STBC MCS 6 */
++ pwreg = 0;
++ rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®);
++ t = rt2x00_get_field32(reg, TX_PWR_CFG_4B_STBC_MCS6);
++ rt2x00_set_field32(&pwreg, TX_PWR_CFG_9B_STBC_MCS7, t);
++ rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, pwreg);
++
++ rt2800_config_alc(rt2x00dev, chan, power_level);
++
++ /* TODO: temperature compensation code! */
++}
++
+ /*
+ * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and
+ * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values,
+@@ -4378,6 +4810,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
+ {
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
++ else if (rt2x00_rt(rt2x00dev, RT6352))
++ rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level);
+ else
+ rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
+ }
+@@ -4393,6 +4827,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+ {
+ u32 tx_pin;
+ u8 rfcsr;
++ unsigned long min_sleep = 0;
+
+ /*
+ * A voltage-controlled oscillator(VCO) is an electronic oscillator
+@@ -4431,6 +4866,15 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+ rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
++ min_sleep = 1000;
++ break;
++ case RF7620:
++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40);
++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C);
++ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr);
++ rt2x00_set_field8(&rfcsr, RFCSR4_VCOCAL_EN, 1);
++ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr);
++ min_sleep = 2000;
+ break;
+ default:
+ WARN_ONCE(1, "Not supported RF chipet %x for VCO recalibration",
+@@ -4438,7 +4882,8 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+ return;
+ }
+
+- usleep_range(1000, 1500);
++ if (min_sleep > 0)
++ usleep_range(min_sleep, min_sleep * 2);
+
+ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
+ if (rt2x00dev->rf_channel <= 14) {
+@@ -4470,6 +4915,42 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+ }
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
++ if (rt2x00_rt(rt2x00dev, RT6352)) {
++ if (rt2x00dev->default_ant.tx_chain_num == 1) {
++ rt2800_bbp_write(rt2x00dev, 91, 0x07);
++ rt2800_bbp_write(rt2x00dev, 95, 0x1A);
++ rt2800_bbp_write(rt2x00dev, 195, 128);
++ rt2800_bbp_write(rt2x00dev, 196, 0xA0);
++ rt2800_bbp_write(rt2x00dev, 195, 170);
++ rt2800_bbp_write(rt2x00dev, 196, 0x12);
++ rt2800_bbp_write(rt2x00dev, 195, 171);
++ rt2800_bbp_write(rt2x00dev, 196, 0x10);
++ } else {
++ rt2800_bbp_write(rt2x00dev, 91, 0x06);
++ rt2800_bbp_write(rt2x00dev, 95, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 195, 128);
++ rt2800_bbp_write(rt2x00dev, 196, 0xE0);
++ rt2800_bbp_write(rt2x00dev, 195, 170);
++ rt2800_bbp_write(rt2x00dev, 196, 0x30);
++ rt2800_bbp_write(rt2x00dev, 195, 171);
++ rt2800_bbp_write(rt2x00dev, 196, 0x30);
++ }
++
++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
++ rt2800_bbp_write(rt2x00dev, 75, 0x60);
++ rt2800_bbp_write(rt2x00dev, 76, 0x44);
++ rt2800_bbp_write(rt2x00dev, 79, 0x1C);
++ rt2800_bbp_write(rt2x00dev, 80, 0x0C);
++ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
++ }
++
++ /* On 11A, We should delay and wait RF/BBP to be stable
++ * and the appropriate time should be 1000 micro seconds
++ * 2005/06/05 - On 11G, we also need this delay time.
++ * Otherwise it's difficult to pass the WHQL.
++ */
++ usleep_range(1000, 1500);
++ }
+ }
+ EXPORT_SYMBOL_GPL(rt2800_vco_calibration);
+
+@@ -4568,7 +5049,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
+ rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+ rt2x00_rt(rt2x00dev, RT5392) ||
+- rt2x00_rt(rt2x00dev, RT5592))
++ rt2x00_rt(rt2x00dev, RT5592) ||
++ rt2x00_rt(rt2x00dev, RT6352))
+ vgc = 0x1c + (2 * rt2x00dev->lna_gain);
+ else
+ vgc = 0x2e + rt2x00dev->lna_gain;
+@@ -4795,7 +5277,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+ 0x00000000);
+ }
+ } else if (rt2x00_rt(rt2x00dev, RT5390) ||
+- rt2x00_rt(rt2x00dev, RT5392)) {
++ rt2x00_rt(rt2x00dev, RT5392) ||
++ rt2x00_rt(rt2x00dev, RT6352)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+@@ -4805,6 +5288,24 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ } else if (rt2x00_rt(rt2x00dev, RT5350)) {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
++ } else if (rt2x00_rt(rt2x00dev, RT6352)) {
++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
++ rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002);
++ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F);
++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606);
++ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
++ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);
++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C);
++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
++ 0x3630363A);
++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
++ 0x3630363A);
++ rt2800_register_read(rt2x00dev, TX_ALC_CFG_1, ®);
++ rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0);
++ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg);
+ } else {
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+@@ -5786,6 +6287,231 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
+ rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+ }
+
++static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
++ const u8 reg, const u8 value)
++{
++ rt2800_bbp_write(rt2x00dev, 195, reg);
++ rt2800_bbp_write(rt2x00dev, 196, value);
++}
++
++static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
++ const u8 reg, const u8 value)
++{
++ rt2800_bbp_write(rt2x00dev, 158, reg);
++ rt2800_bbp_write(rt2x00dev, 159, value);
++}
++
++static void rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev,
++ const u8 reg, u8 *value)
++{
++ rt2800_bbp_write(rt2x00dev, 158, reg);
++ rt2800_bbp_read(rt2x00dev, 159, value);
++}
++
++static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev)
++{
++ u8 bbp;
++
++ /* Apply Maximum Likelihood Detection (MLD) for 2 stream case */
++ rt2800_bbp_read(rt2x00dev, 105, &bbp);
++ rt2x00_set_field8(&bbp, BBP105_MLD,
++ rt2x00dev->default_ant.rx_chain_num == 2);
++ rt2800_bbp_write(rt2x00dev, 105, bbp);
++
++ /* Avoid data loss and CRC errors */
++ rt2800_bbp4_mac_if_ctrl(rt2x00dev);
++
++ /* Fix I/Q swap issue */
++ rt2800_bbp_read(rt2x00dev, 1, &bbp);
++ bbp |= 0x04;
++ rt2800_bbp_write(rt2x00dev, 1, bbp);
++
++ /* BBP for G band */
++ rt2800_bbp_write(rt2x00dev, 3, 0x08);
++ rt2800_bbp_write(rt2x00dev, 4, 0x00); /* rt2800_bbp4_mac_if_ctrl? */
++ rt2800_bbp_write(rt2x00dev, 6, 0x08);
++ rt2800_bbp_write(rt2x00dev, 14, 0x09);
++ rt2800_bbp_write(rt2x00dev, 15, 0xFF);
++ rt2800_bbp_write(rt2x00dev, 16, 0x01);
++ rt2800_bbp_write(rt2x00dev, 20, 0x06);
++ rt2800_bbp_write(rt2x00dev, 21, 0x00);
++ rt2800_bbp_write(rt2x00dev, 22, 0x00);
++ rt2800_bbp_write(rt2x00dev, 27, 0x00);
++ rt2800_bbp_write(rt2x00dev, 28, 0x00);
++ rt2800_bbp_write(rt2x00dev, 30, 0x00);
++ rt2800_bbp_write(rt2x00dev, 31, 0x48);
++ rt2800_bbp_write(rt2x00dev, 47, 0x40);
++ rt2800_bbp_write(rt2x00dev, 62, 0x00);
++ rt2800_bbp_write(rt2x00dev, 63, 0x00);
++ rt2800_bbp_write(rt2x00dev, 64, 0x00);
++ rt2800_bbp_write(rt2x00dev, 65, 0x2C);
++ rt2800_bbp_write(rt2x00dev, 66, 0x1C);
++ rt2800_bbp_write(rt2x00dev, 67, 0x20);
++ rt2800_bbp_write(rt2x00dev, 68, 0xDD);
++ rt2800_bbp_write(rt2x00dev, 69, 0x10);
++ rt2800_bbp_write(rt2x00dev, 70, 0x05);
++ rt2800_bbp_write(rt2x00dev, 73, 0x18);
++ rt2800_bbp_write(rt2x00dev, 74, 0x0F);
++ rt2800_bbp_write(rt2x00dev, 75, 0x60);
++ rt2800_bbp_write(rt2x00dev, 76, 0x44);
++ rt2800_bbp_write(rt2x00dev, 77, 0x59);
++ rt2800_bbp_write(rt2x00dev, 78, 0x1E);
++ rt2800_bbp_write(rt2x00dev, 79, 0x1C);
++ rt2800_bbp_write(rt2x00dev, 80, 0x0C);
++ rt2800_bbp_write(rt2x00dev, 81, 0x3A);
++ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
++ rt2800_bbp_write(rt2x00dev, 83, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 84, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 86, 0x38);
++ rt2800_bbp_write(rt2x00dev, 88, 0x90);
++ rt2800_bbp_write(rt2x00dev, 91, 0x04);
++ rt2800_bbp_write(rt2x00dev, 92, 0x02);
++ rt2800_bbp_write(rt2x00dev, 95, 0x9A);
++ rt2800_bbp_write(rt2x00dev, 96, 0x00);
++ rt2800_bbp_write(rt2x00dev, 103, 0xC0);
++ rt2800_bbp_write(rt2x00dev, 104, 0x92);
++ /* FIXME BBP105 owerwrite */
++ rt2800_bbp_write(rt2x00dev, 105, 0x3C);
++ rt2800_bbp_write(rt2x00dev, 106, 0x12);
++ rt2800_bbp_write(rt2x00dev, 109, 0x00);
++ rt2800_bbp_write(rt2x00dev, 134, 0x10);
++ rt2800_bbp_write(rt2x00dev, 135, 0xA6);
++ rt2800_bbp_write(rt2x00dev, 137, 0x04);
++ rt2800_bbp_write(rt2x00dev, 142, 0x30);
++ rt2800_bbp_write(rt2x00dev, 143, 0xF7);
++ rt2800_bbp_write(rt2x00dev, 160, 0xEC);
++ rt2800_bbp_write(rt2x00dev, 161, 0xC4);
++ rt2800_bbp_write(rt2x00dev, 162, 0x77);
++ rt2800_bbp_write(rt2x00dev, 163, 0xF9);
++ rt2800_bbp_write(rt2x00dev, 164, 0x00);
++ rt2800_bbp_write(rt2x00dev, 165, 0x00);
++ rt2800_bbp_write(rt2x00dev, 186, 0x00);
++ rt2800_bbp_write(rt2x00dev, 187, 0x00);
++ rt2800_bbp_write(rt2x00dev, 188, 0x00);
++ rt2800_bbp_write(rt2x00dev, 186, 0x00);
++ rt2800_bbp_write(rt2x00dev, 187, 0x01);
++ rt2800_bbp_write(rt2x00dev, 188, 0x00);
++ rt2800_bbp_write(rt2x00dev, 189, 0x00);
++
++ rt2800_bbp_write(rt2x00dev, 91, 0x06);
++ rt2800_bbp_write(rt2x00dev, 92, 0x04);
++ rt2800_bbp_write(rt2x00dev, 93, 0x54);
++ rt2800_bbp_write(rt2x00dev, 99, 0x50);
++ rt2800_bbp_write(rt2x00dev, 148, 0x84);
++ rt2800_bbp_write(rt2x00dev, 167, 0x80);
++ rt2800_bbp_write(rt2x00dev, 178, 0xFF);
++ rt2800_bbp_write(rt2x00dev, 106, 0x13);
++
++ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */
++ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00);
++ rt2800_bbp_glrt_write(rt2x00dev, 1, 0x14);
++ rt2800_bbp_glrt_write(rt2x00dev, 2, 0x20);
++ rt2800_bbp_glrt_write(rt2x00dev, 3, 0x0A);
++ rt2800_bbp_glrt_write(rt2x00dev, 10, 0x16);
++ rt2800_bbp_glrt_write(rt2x00dev, 11, 0x06);
++ rt2800_bbp_glrt_write(rt2x00dev, 12, 0x02);
++ rt2800_bbp_glrt_write(rt2x00dev, 13, 0x07);
++ rt2800_bbp_glrt_write(rt2x00dev, 14, 0x05);
++ rt2800_bbp_glrt_write(rt2x00dev, 15, 0x09);
++ rt2800_bbp_glrt_write(rt2x00dev, 16, 0x20);
++ rt2800_bbp_glrt_write(rt2x00dev, 17, 0x08);
++ rt2800_bbp_glrt_write(rt2x00dev, 18, 0x4A);
++ rt2800_bbp_glrt_write(rt2x00dev, 19, 0x00);
++ rt2800_bbp_glrt_write(rt2x00dev, 20, 0x00);
++ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xE0);
++ rt2800_bbp_glrt_write(rt2x00dev, 129, 0x1F);
++ rt2800_bbp_glrt_write(rt2x00dev, 130, 0x4F);
++ rt2800_bbp_glrt_write(rt2x00dev, 131, 0x32);
++ rt2800_bbp_glrt_write(rt2x00dev, 132, 0x08);
++ rt2800_bbp_glrt_write(rt2x00dev, 133, 0x28);
++ rt2800_bbp_glrt_write(rt2x00dev, 134, 0x19);
++ rt2800_bbp_glrt_write(rt2x00dev, 135, 0x0A);
++ rt2800_bbp_glrt_write(rt2x00dev, 138, 0x16);
++ rt2800_bbp_glrt_write(rt2x00dev, 139, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 140, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1A);
++ rt2800_bbp_glrt_write(rt2x00dev, 142, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 143, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 144, 0x26);
++ rt2800_bbp_glrt_write(rt2x00dev, 145, 0x24);
++ rt2800_bbp_glrt_write(rt2x00dev, 146, 0x42);
++ rt2800_bbp_glrt_write(rt2x00dev, 147, 0x40);
++ rt2800_bbp_glrt_write(rt2x00dev, 148, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 149, 0x29);
++ rt2800_bbp_glrt_write(rt2x00dev, 150, 0x4C);
++ rt2800_bbp_glrt_write(rt2x00dev, 151, 0x46);
++ rt2800_bbp_glrt_write(rt2x00dev, 152, 0x3D);
++ rt2800_bbp_glrt_write(rt2x00dev, 153, 0x40);
++ rt2800_bbp_glrt_write(rt2x00dev, 154, 0x3E);
++ rt2800_bbp_glrt_write(rt2x00dev, 155, 0x38);
++ rt2800_bbp_glrt_write(rt2x00dev, 156, 0x3D);
++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2F);
++ rt2800_bbp_glrt_write(rt2x00dev, 158, 0x3C);
++ rt2800_bbp_glrt_write(rt2x00dev, 159, 0x34);
++ rt2800_bbp_glrt_write(rt2x00dev, 160, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 161, 0x2F);
++ rt2800_bbp_glrt_write(rt2x00dev, 162, 0x3C);
++ rt2800_bbp_glrt_write(rt2x00dev, 163, 0x35);
++ rt2800_bbp_glrt_write(rt2x00dev, 164, 0x2E);
++ rt2800_bbp_glrt_write(rt2x00dev, 165, 0x2F);
++ rt2800_bbp_glrt_write(rt2x00dev, 166, 0x49);
++ rt2800_bbp_glrt_write(rt2x00dev, 167, 0x41);
++ rt2800_bbp_glrt_write(rt2x00dev, 168, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 169, 0x39);
++ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 172, 0x0E);
++ rt2800_bbp_glrt_write(rt2x00dev, 173, 0x0D);
++ rt2800_bbp_glrt_write(rt2x00dev, 174, 0x28);
++ rt2800_bbp_glrt_write(rt2x00dev, 175, 0x21);
++ rt2800_bbp_glrt_write(rt2x00dev, 176, 0x1C);
++ rt2800_bbp_glrt_write(rt2x00dev, 177, 0x16);
++ rt2800_bbp_glrt_write(rt2x00dev, 178, 0x50);
++ rt2800_bbp_glrt_write(rt2x00dev, 179, 0x4A);
++ rt2800_bbp_glrt_write(rt2x00dev, 180, 0x43);
++ rt2800_bbp_glrt_write(rt2x00dev, 181, 0x50);
++ rt2800_bbp_glrt_write(rt2x00dev, 182, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 183, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 184, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 185, 0x10);
++ rt2800_bbp_glrt_write(rt2x00dev, 200, 0x7D);
++ rt2800_bbp_glrt_write(rt2x00dev, 201, 0x14);
++ rt2800_bbp_glrt_write(rt2x00dev, 202, 0x32);
++ rt2800_bbp_glrt_write(rt2x00dev, 203, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 204, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 205, 0x4C);
++ rt2800_bbp_glrt_write(rt2x00dev, 206, 0x43);
++ rt2800_bbp_glrt_write(rt2x00dev, 207, 0x2C);
++ rt2800_bbp_glrt_write(rt2x00dev, 208, 0x2E);
++ rt2800_bbp_glrt_write(rt2x00dev, 209, 0x36);
++ rt2800_bbp_glrt_write(rt2x00dev, 210, 0x30);
++ rt2800_bbp_glrt_write(rt2x00dev, 211, 0x6E);
++
++ /* BBP for G band DCOC function */
++ rt2800_bbp_dcoc_write(rt2x00dev, 140, 0x0C);
++ rt2800_bbp_dcoc_write(rt2x00dev, 141, 0x00);
++ rt2800_bbp_dcoc_write(rt2x00dev, 142, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 143, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 144, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 145, 0x10);
++ rt2800_bbp_dcoc_write(rt2x00dev, 146, 0x08);
++ rt2800_bbp_dcoc_write(rt2x00dev, 147, 0x40);
++ rt2800_bbp_dcoc_write(rt2x00dev, 148, 0x04);
++ rt2800_bbp_dcoc_write(rt2x00dev, 149, 0x04);
++ rt2800_bbp_dcoc_write(rt2x00dev, 150, 0x08);
++ rt2800_bbp_dcoc_write(rt2x00dev, 151, 0x08);
++ rt2800_bbp_dcoc_write(rt2x00dev, 152, 0x03);
++ rt2800_bbp_dcoc_write(rt2x00dev, 153, 0x03);
++ rt2800_bbp_dcoc_write(rt2x00dev, 154, 0x03);
++ rt2800_bbp_dcoc_write(rt2x00dev, 155, 0x02);
++ rt2800_bbp_dcoc_write(rt2x00dev, 156, 0x40);
++ rt2800_bbp_dcoc_write(rt2x00dev, 157, 0x40);
++ rt2800_bbp_dcoc_write(rt2x00dev, 158, 0x64);
++ rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64);
++
++ rt2800_bbp4_mac_if_ctrl(rt2x00dev);
++}
++
+ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+ {
+ unsigned int i;
+@@ -5830,6 +6556,9 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+ case RT5592:
+ rt2800_init_bbp_5592(rt2x00dev);
+ return;
++ case RT6352:
++ rt2800_init_bbp_6352(rt2x00dev);
++ break;
+ }
+
+ for (i = 0; i < EEPROM_BBP_SIZE; i++) {
+@@ -6901,6 +7630,615 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev)
+ rt2800_led_open_drain_enable(rt2x00dev);
+ }
+
++static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
++ bool set_bw, bool is_ht40)
++{
++ u8 bbp_val;
++
++ rt2800_bbp_read(rt2x00dev, 21, &bbp_val);
++ bbp_val |= 0x1;
++ rt2800_bbp_write(rt2x00dev, 21, bbp_val);
++ usleep_range(100, 200);
++
++ if (set_bw) {
++ rt2800_bbp_read(rt2x00dev, 4, &bbp_val);
++ rt2x00_set_field8(&bbp_val, BBP4_BANDWIDTH, 2 * is_ht40);
++ rt2800_bbp_write(rt2x00dev, 4, bbp_val);
++ usleep_range(100, 200);
++ }
++
++ rt2800_bbp_read(rt2x00dev, 21, &bbp_val);
++ bbp_val &= (~0x1);
++ rt2800_bbp_write(rt2x00dev, 21, bbp_val);
++ usleep_range(100, 200);
++}
++
++static int rt2800_rf_lp_config(struct rt2x00_dev *rt2x00dev, bool btxcal)
++{
++ u8 rf_val;
++
++ if (btxcal)
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
++ else
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x02);
++
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x06);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 17, &rf_val);
++ rf_val |= 0x80;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, rf_val);
++
++ if (btxcal) {
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xC1);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x20);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x02);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &rf_val);
++ rf_val &= (~0x3F);
++ rf_val |= 0x3F;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rf_val);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &rf_val);
++ rf_val &= (~0x3F);
++ rf_val |= 0x3F;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rf_val);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 5, 0x31);
++ } else {
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xF1);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0x18);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x02);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &rf_val);
++ rf_val &= (~0x3F);
++ rf_val |= 0x34;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rf_val);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &rf_val);
++ rf_val &= (~0x3F);
++ rf_val |= 0x34;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rf_val);
++ }
++
++ return 0;
++}
++
++static char rt2800_lp_tx_filter_bw_cal(struct rt2x00_dev *rt2x00dev)
++{
++ unsigned int cnt;
++ u8 bbp_val;
++ char cal_val;
++
++ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x82);
++
++ cnt = 0;
++ do {
++ usleep_range(500, 2000);
++ rt2800_bbp_read(rt2x00dev, 159, &bbp_val);
++ if (bbp_val == 0x02 || cnt == 20)
++ break;
++
++ cnt++;
++ } while (cnt < 20);
++
++ rt2800_bbp_dcoc_read(rt2x00dev, 0x39, &bbp_val);
++ cal_val = bbp_val & 0x7F;
++ if (cal_val >= 0x40)
++ cal_val -= 128;
++
++ return cal_val;
++}
++
++static void rt2800_bw_filter_calibration(struct rt2x00_dev *rt2x00dev,
++ bool btxcal)
++{
++ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++ u8 tx_agc_fc = 0, rx_agc_fc = 0, cmm_agc_fc;
++ u8 filter_target;
++ u8 tx_filter_target_20m = 0x09, tx_filter_target_40m = 0x02;
++ u8 rx_filter_target_20m = 0x27, rx_filter_target_40m = 0x31;
++ int loop = 0, is_ht40, cnt;
++ u8 bbp_val, rf_val;
++ char cal_r32_init, cal_r32_val, cal_diff;
++ u8 saverfb5r00, saverfb5r01, saverfb5r03, saverfb5r04, saverfb5r05;
++ u8 saverfb5r06, saverfb5r07;
++ u8 saverfb5r08, saverfb5r17, saverfb5r18, saverfb5r19, saverfb5r20;
++ u8 saverfb5r37, saverfb5r38, saverfb5r39, saverfb5r40, saverfb5r41;
++ u8 saverfb5r42, saverfb5r43, saverfb5r44, saverfb5r45, saverfb5r46;
++ u8 saverfb5r58, saverfb5r59;
++ u8 savebbp159r0, savebbp159r2, savebbpr23;
++ u32 MAC_RF_CONTROL0, MAC_RF_BYPASS0;
++
++ /* Save MAC registers */
++ rt2800_register_read(rt2x00dev, RF_CONTROL0, &MAC_RF_CONTROL0);
++ rt2800_register_read(rt2x00dev, RF_BYPASS0, &MAC_RF_BYPASS0);
++
++ /* save BBP registers */
++ rt2800_bbp_read(rt2x00dev, 23, &savebbpr23);
++
++ rt2800_bbp_dcoc_read(rt2x00dev, 0, &savebbp159r0);
++ rt2800_bbp_dcoc_read(rt2x00dev, 2, &savebbp159r2);
++
++ /* Save RF registers */
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &saverfb5r00);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &saverfb5r01);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 3, &saverfb5r03);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 4, &saverfb5r04);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 5, &saverfb5r05);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &saverfb5r06);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &saverfb5r07);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 8, &saverfb5r08);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 17, &saverfb5r17);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 18, &saverfb5r18);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 19, &saverfb5r19);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 20, &saverfb5r20);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 37, &saverfb5r37);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 38, &saverfb5r38);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 39, &saverfb5r39);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 40, &saverfb5r40);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 41, &saverfb5r41);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 42, &saverfb5r42);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 43, &saverfb5r43);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 44, &saverfb5r44);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 45, &saverfb5r45);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 46, &saverfb5r46);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &saverfb5r58);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &saverfb5r59);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &rf_val);
++ rf_val |= 0x3;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, rf_val);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &rf_val);
++ rf_val |= 0x1;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, rf_val);
++
++ cnt = 0;
++ do {
++ usleep_range(500, 2000);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 1, &rf_val);
++ if (((rf_val & 0x1) == 0x00) || (cnt == 40))
++ break;
++ cnt++;
++ } while (cnt < 40);
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 0, &rf_val);
++ rf_val &= (~0x3);
++ rf_val |= 0x1;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, rf_val);
++
++ /* I-3 */
++ rt2800_bbp_read(rt2x00dev, 23, &bbp_val);
++ bbp_val &= (~0x1F);
++ bbp_val |= 0x10;
++ rt2800_bbp_write(rt2x00dev, 23, bbp_val);
++
++ do {
++ /* I-4,5,6,7,8,9 */
++ if (loop == 0) {
++ is_ht40 = false;
++
++ if (btxcal)
++ filter_target = tx_filter_target_20m;
++ else
++ filter_target = rx_filter_target_20m;
++ } else {
++ is_ht40 = true;
++
++ if (btxcal)
++ filter_target = tx_filter_target_40m;
++ else
++ filter_target = rx_filter_target_40m;
++ }
++
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 8, &rf_val);
++ rf_val &= (~0x04);
++ if (loop == 1)
++ rf_val |= 0x4;
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 8, rf_val);
++
++ rt2800_bbp_core_soft_reset(rt2x00dev, true, is_ht40);
++
++ rt2800_rf_lp_config(rt2x00dev, btxcal);
++ if (btxcal) {
++ tx_agc_fc = 0;
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rf_val);
++ rf_val &= (~0x7F);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rf_val);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rf_val);
++ rf_val &= (~0x7F);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rf_val);
++ } else {
++ rx_agc_fc = 0;
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rf_val);
++ rf_val &= (~0x7F);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rf_val);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rf_val);
++ rf_val &= (~0x7F);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rf_val);
++ }
++
++ usleep_range(1000, 2000);
++
++ rt2800_bbp_dcoc_read(rt2x00dev, 2, &bbp_val);
++ bbp_val &= (~0x6);
++ rt2800_bbp_dcoc_write(rt2x00dev, 2, bbp_val);
++
++ rt2800_bbp_core_soft_reset(rt2x00dev, false, is_ht40);
++
++ cal_r32_init = rt2800_lp_tx_filter_bw_cal(rt2x00dev);
++
++ rt2800_bbp_dcoc_read(rt2x00dev, 2, &bbp_val);
++ bbp_val |= 0x6;
++ rt2800_bbp_dcoc_write(rt2x00dev, 2, bbp_val);
++do_cal:
++ if (btxcal) {
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rf_val);
++ rf_val &= (~0x7F);
++ rf_val |= tx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rf_val);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rf_val);
++ rf_val &= (~0x7F);
++ rf_val |= tx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rf_val);
++ } else {
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rf_val);
++ rf_val &= (~0x7F);
++ rf_val |= rx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rf_val);
++ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rf_val);
++ rf_val &= (~0x7F);
++ rf_val |= rx_agc_fc;
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rf_val);
++ }
++
++ usleep_range(500, 1000);
++
++ rt2800_bbp_core_soft_reset(rt2x00dev, false, is_ht40);
++
++ cal_r32_val = rt2800_lp_tx_filter_bw_cal(rt2x00dev);
++
++ cal_diff = cal_r32_init - cal_r32_val;
++
++ if (btxcal)
++ cmm_agc_fc = tx_agc_fc;
++ else
++ cmm_agc_fc = rx_agc_fc;
++
++ if (((cal_diff > filter_target) && (cmm_agc_fc == 0)) ||
++ ((cal_diff < filter_target) && (cmm_agc_fc == 0x3f))) {
++ if (btxcal)
++ tx_agc_fc = 0;
++ else
++ rx_agc_fc = 0;
++ } else if ((cal_diff <= filter_target) && (cmm_agc_fc < 0x3f)) {
++ if (btxcal)
++ tx_agc_fc++;
++ else
++ rx_agc_fc++;
++ goto do_cal;
++ }
++
++ if (btxcal) {
++ if (loop == 0)
++ drv_data->tx_calibration_bw20 = tx_agc_fc;
++ else
++ drv_data->tx_calibration_bw40 = tx_agc_fc;
++ } else {
++ if (loop == 0)
++ drv_data->rx_calibration_bw20 = rx_agc_fc;
++ else
++ drv_data->rx_calibration_bw40 = rx_agc_fc;
++ }
++
++ loop++;
++ } while (loop <= 1);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 0, saverfb5r00);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, saverfb5r01);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, saverfb5r03);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r04);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 5, saverfb5r05);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, saverfb5r06);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, saverfb5r07);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 8, saverfb5r08);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, saverfb5r17);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, saverfb5r18);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, saverfb5r19);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, saverfb5r20);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 37, saverfb5r37);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 38, saverfb5r38);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 39, saverfb5r39);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 40, saverfb5r40);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 41, saverfb5r41);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 42, saverfb5r42);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 43, saverfb5r43);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 44, saverfb5r44);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 45, saverfb5r45);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 46, saverfb5r46);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, saverfb5r58);
++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, saverfb5r59);
++
++ rt2800_bbp_write(rt2x00dev, 23, savebbpr23);
++
++ rt2800_bbp_dcoc_write(rt2x00dev, 0, savebbp159r0);
++ rt2800_bbp_dcoc_write(rt2x00dev, 2, savebbp159r2);
++
++ rt2800_bbp_read(rt2x00dev, 4, &bbp_val);
++ rt2x00_set_field8(&bbp_val, BBP4_BANDWIDTH,
++ 2 * test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags));
++ rt2800_bbp_write(rt2x00dev, 4, bbp_val);
++
++ rt2800_register_write(rt2x00dev, RF_CONTROL0, MAC_RF_CONTROL0);
++ rt2800_register_write(rt2x00dev, RF_BYPASS0, MAC_RF_BYPASS0);
++}
++
++static void rt2800_init_rfcsr_6352(struct rt2x00_dev *rt2x00dev)
++{
++ /* Initialize RF central register to default value */
++ rt2800_rfcsr_write(rt2x00dev, 0, 0x02);
++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
++ rt2800_rfcsr_write(rt2x00dev, 2, 0x33);
++ rt2800_rfcsr_write(rt2x00dev, 3, 0xFF);
++ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C);
++ rt2800_rfcsr_write(rt2x00dev, 5, 0x40);
++ rt2800_rfcsr_write(rt2x00dev, 6, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 8, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 9, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 10, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 12, rt2x00dev->freq_offset);
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 14, 0x40);
++ rt2800_rfcsr_write(rt2x00dev, 15, 0x22);
++ rt2800_rfcsr_write(rt2x00dev, 16, 0x4C);
++ rt2800_rfcsr_write(rt2x00dev, 17, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 18, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 20, 0xA0);
++ rt2800_rfcsr_write(rt2x00dev, 21, 0x12);
++ rt2800_rfcsr_write(rt2x00dev, 22, 0x07);
++ rt2800_rfcsr_write(rt2x00dev, 23, 0x13);
++ rt2800_rfcsr_write(rt2x00dev, 24, 0xFE);
++ rt2800_rfcsr_write(rt2x00dev, 25, 0x24);
++ rt2800_rfcsr_write(rt2x00dev, 26, 0x7A);
++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0x05);
++ rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 32, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 34, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 38, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 41, 0xD0);
++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
++
++ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
++ if (rt2800_clk_is_20mhz(rt2x00dev))
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
++ else
++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
++ rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
++ rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
++ rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
++ rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
++ rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
++ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
++ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
++ rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
++
++ rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
++ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
++
++ /* Initialize RF channel register to default value */
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 1, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 2, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 3, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 4, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 5, 0x08);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 6, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 7, 0x51);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x16);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x61);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 12, 0x22);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 13, 0x3D);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 15, 0x13);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 16, 0x22);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x01);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x52);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 22, 0x80);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 23, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 24, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 25, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 26, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 27, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x5C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0x6B);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 30, 0x6B);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 31, 0x31);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x5D);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 33, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xE6);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 35, 0x55);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 37, 0xBB);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 39, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 40, 0x03);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 41, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 42, 0x00);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xD3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x07);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x68);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xEF);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x07);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xA8);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x85);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x10);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x07);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6A);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x85);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x10);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 62, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 63, 0x00);
++
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5);
++
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
++
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
++
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
++
++ /* Initialize RF channel register for DRQFN */
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
++
++ /* Initialize RF DC calibration register to default value */
++ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 1, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 2, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 9, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 10, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 11, 0x01);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 12, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 13, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 14, 0x07);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 15, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 16, 0x22);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 21, 0xF1);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 22, 0x11);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 23, 0x02);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 24, 0x41);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 25, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 26, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 27, 0xD7);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 28, 0xA2);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 29, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 30, 0x49);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 31, 0x20);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 32, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 33, 0xF1);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 34, 0xA1);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 35, 0x01);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 41, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 42, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 43, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 44, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 45, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 46, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 47, 0x3E);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 48, 0x3D);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 49, 0x3E);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 50, 0x3D);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 51, 0x3E);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 52, 0x3D);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 53, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 54, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 55, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 56, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 57, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 60, 0x0A);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 61, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00);
++
++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
++
++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
++
++ rt2800_bw_filter_calibration(rt2x00dev, true);
++ rt2800_bw_filter_calibration(rt2x00dev, false);
++}
++
+ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+ {
+ if (rt2800_is_305x_soc(rt2x00dev)) {
+@@ -6941,6 +8279,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+ case RT5592:
+ rt2800_init_rfcsr_5592(rt2x00dev);
+ break;
++ case RT6352:
++ rt2800_init_rfcsr_6352(rt2x00dev);
++ break;
+ }
+ }
+
+@@ -7307,7 +8648,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
+ */
+ if (rt2x00_rt(rt2x00dev, RT3290) ||
+ rt2x00_rt(rt2x00dev, RT5390) ||
+- rt2x00_rt(rt2x00dev, RT5392))
++ rt2x00_rt(rt2x00dev, RT5392) ||
++ rt2x00_rt(rt2x00dev, RT6352))
+ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+ else if (rt2x00_rt(rt2x00dev, RT3352))
+ rf = RF3322;
+@@ -7339,6 +8681,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
+ case RF5390:
+ case RF5392:
+ case RF5592:
++ case RF7620:
+ break;
+ default:
+ rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n",
+@@ -7746,6 +9089,23 @@ static const struct rf_channel rf_vals_5592_xtal40[] = {
+ {196, 83, 0, 12, 1},
+ };
+
++static const struct rf_channel rf_vals_7620[] = {
++ {1, 0x50, 0x99, 0x99, 1},
++ {2, 0x50, 0x44, 0x44, 2},
++ {3, 0x50, 0xEE, 0xEE, 2},
++ {4, 0x50, 0x99, 0x99, 3},
++ {5, 0x51, 0x44, 0x44, 0},
++ {6, 0x51, 0xEE, 0xEE, 0},
++ {7, 0x51, 0x99, 0x99, 1},
++ {8, 0x51, 0x44, 0x44, 2},
++ {9, 0x51, 0xEE, 0xEE, 2},
++ {10, 0x51, 0x99, 0x99, 3},
++ {11, 0x52, 0x44, 0x44, 0},
++ {12, 0x52, 0xEE, 0xEE, 0},
++ {13, 0x52, 0x99, 0x99, 1},
++ {14, 0x52, 0x33, 0x33, 3},
++};
++
+ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ {
+ struct hw_mode_spec *spec = &rt2x00dev->spec;
+@@ -7849,6 +9209,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ spec->channels = rf_vals_3x;
+ break;
+
++ case RF7620:
++ spec->num_channels = ARRAY_SIZE(rf_vals_7620);
++ spec->channels = rf_vals_7620;
++ break;
++
+ case RF3052:
+ case RF3053:
+ spec->num_channels = ARRAY_SIZE(rf_vals_3x);
+@@ -7980,6 +9345,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+ case RF5390:
+ case RF5392:
+ case RF5592:
++ case RF7620:
+ __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags);
+ break;
+ }
+@@ -8024,6 +9390,9 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
+ return -ENODEV;
+ }
+
++ if (rt == RT5390 && rt2x00_is_soc(rt2x00dev))
++ rt = RT6352;
++
+ rt2x00_set_rt(rt2x00dev, rt, rev);
+
+ return 0;
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+index d9ef260d542a..f357531d9488 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+@@ -33,6 +33,10 @@
+ struct rt2800_drv_data {
+ u8 calibration_bw20;
+ u8 calibration_bw40;
++ char rx_calibration_bw20;
++ char rx_calibration_bw40;
++ char tx_calibration_bw20;
++ char tx_calibration_bw40;
+ u8 bbp25;
+ u8 bbp26;
+ u8 txmixer_gain_24g;
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+index ce340bfd71a0..8fdd2f9726ee 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -174,6 +174,7 @@ struct rt2x00_chip {
+ #define RT5390 0x5390 /* 2.4GHz */
+ #define RT5392 0x5392 /* 2.4GHz */
+ #define RT5592 0x5592
++#define RT6352 0x6352 /* WSOC 2.4GHz */
+
+ u16 rf;
+ u16 rev;
+--
+2.12.1
+
--- /dev/null
+From 0109238d62a99ea779a7e28e21868118e7b8d69d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 10 Apr 2017 14:28:14 +0200
+Subject: [PATCH 1/2] rt2800: fix LNA gain assignment for MT7620
+To: Stanislaw Gruszka <sgruszka@redhat.com>
+Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
+ linux-wireless@vger.kernel.org,
+ Kalle Valo <kvalo@codeaurora.org>
+
+The base value used for MT7620 differs from Rt5392 which resulted in
+quite bad RX signal quality. Fix this by using the correct base value as
+well as the LNA calibration values for HT20.
+
+Reported-by: Tom Psyborg <pozega.tomislav@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index ba06ac2d876d..7135519a638c 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3806,11 +3806,25 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ }
+
+ if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) {
++ reg = 0x10;
++ if (!conf_is_ht40(conf)) {
++ if (rt2x00_rt(rt2x00dev, RT6352) &&
++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
++ reg |= 0x5;
++ } else {
++ reg |= 0xa;
++ }
++ }
+ rt2800_bbp_write(rt2x00dev, 195, 141);
+- rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
++ rt2800_bbp_write(rt2x00dev, 196, reg);
+
+ /* AGC init */
+- reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2 * rt2x00dev->lna_gain;
++ if (rt2x00_rt(rt2x00dev, RT6352))
++ reg = 0x04;
++ else
++ reg = rf->channel <= 14 ? 0x1c : 0x24;
++
++ reg += 2 * rt2x00dev->lna_gain;
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
+ rt2800_iq_calibrate(rt2x00dev, rf->channel);
+--
+2.12.2
+
--- /dev/null
+From feb608c7986c14bab153f31f8e96f251072e6578 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 10 Apr 2017 15:33:20 +0200
+Subject: [PATCH 2/2] rt2800: do VCO calibration after programming ALC
+To: Stanislaw Gruszka <sgruszka@redhat.com>
+Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
+ linux-wireless@vger.kernel.org,
+ Kalle Valo <kvalo@codeaurora.org>
+
+Scanning fails if we don't do VCO calibration every time.
+The vendor driver duplicates the VCO calibration function into the
+channel switching logic, we can do the same with less duplication.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 7135519a638c..870bf315f98b 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -3407,6 +3407,8 @@ static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev,
+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
+ }
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
++
++ rt2800_vco_calibration(rt2x00dev);
+ }
+
+ static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev,
+--
+2.12.2
+
--- /dev/null
+From 02c452f317b4a4d06c433c294e66896a389731c1 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 18 Apr 2017 11:09:53 +0200
+Subject: [PATCH] rt2800: fix mt7620 vco calibration registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+To: Stanislaw Gruszka <sgruszka@redhat.com>
+Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
+ linux-wireless@vger.kernel.org,
+ Kalle Valo <kvalo@codeaurora.org>,
+ Tom Psyborg <pozega.tomislav@gmail.com>
+
+Use register values from init LNA function instead of the ones from
+restore LNA function. Apply register values based on rx path
+configuration.
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 870bf315f98b..86cffee6876a 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -4932,7 +4932,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+ if (rt2x00_rt(rt2x00dev, RT6352)) {
+- if (rt2x00dev->default_ant.tx_chain_num == 1) {
++ if (rt2x00dev->default_ant.rx_chain_num == 1) {
+ rt2800_bbp_write(rt2x00dev, 91, 0x07);
+ rt2800_bbp_write(rt2x00dev, 95, 0x1A);
+ rt2800_bbp_write(rt2x00dev, 195, 128);
+@@ -4953,8 +4953,8 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
+ }
+
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+- rt2800_bbp_write(rt2x00dev, 75, 0x60);
+- rt2800_bbp_write(rt2x00dev, 76, 0x44);
++ rt2800_bbp_write(rt2x00dev, 75, 0x68);
++ rt2800_bbp_write(rt2x00dev, 76, 0x4C);
+ rt2800_bbp_write(rt2x00dev, 79, 0x1C);
+ rt2800_bbp_write(rt2x00dev, 80, 0x0C);
+ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
+--
+2.12.2
+
--- /dev/null
+From c426cb0ed15ee12dfdc8c53ddd1449ac617023cf Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 18 Apr 2017 11:45:37 +0200
+Subject: [PATCH] rt2800: fix mt7620 E2 channel registers
+To: Stanislaw Gruszka <sgruszka@redhat.com>
+Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
+ linux-wireless@vger.kernel.org,
+ Kalle Valo <kvalo@codeaurora.org>,
+ Tom Psyborg <pozega.tomislav@gmail.com>
+
+From: Tomislav Požega <pozega.tomislav@gmail.com>
+
+update RF register 47 and 54 values according to vendor driver
+
+Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 86cffee6876a..8585cdc3de53 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -8145,9 +8145,11 @@ static void rt2800_init_rfcsr_6352(struct rt2x00_dev *rt2x00dev)
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
+- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69);
++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67);
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
+- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20);
++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27);
++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
+--
+2.12.2
+
config RT2X00_LIB_SOC
- tristate
+ tristate "RT2x00 SoC support"
-+ depends on SOC_RT288X || SOC_RT305X
++ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
depends on m
select RT2X00_LIB
+++ /dev/null
---- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
-+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
-@@ -1,5 +1,5 @@
- config BRCMUTIL
-- tristate
-+ tristate "Broadcom 802.11 driver utility functions"
- depends on m
-
- config BRCMSMAC
+++ /dev/null
-From: Stanislaw Gruszka <sgruszka@redhat.com>
-Date: Thu, 2 Feb 2017 10:57:40 +0100
-Subject: [PATCH] rt2x00: avoid introducing a USB dependency in the
- rt2x00lib module
-
-As reported by Felix:
-
-Though protected by an ifdef, introducing an usb symbol dependency in
-the rt2x00lib module is a major inconvenience for distributions that
-package kernel modules split into individual packages.
-
-Get rid of this unnecessary dependency by calling the usb related
-function from a more suitable place.
-
-Cc: Vishal Thanki <vishalthanki@gmail.com>
-Reported-by: Felix Fietkau <nbd@nbd.name>
-Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
-Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
----
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1436,21 +1436,6 @@ void rt2x00lib_remove_dev(struct rt2x00_
- cancel_work_sync(&rt2x00dev->intf_work);
- cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
- cancel_work_sync(&rt2x00dev->sleep_work);
--#if IS_ENABLED(CPTCFG_RT2X00_LIB_USB)
-- if (rt2x00_is_usb(rt2x00dev)) {
-- usb_kill_anchored_urbs(rt2x00dev->anchor);
-- hrtimer_cancel(&rt2x00dev->txstatus_timer);
-- cancel_work_sync(&rt2x00dev->rxdone_work);
-- cancel_work_sync(&rt2x00dev->txdone_work);
-- }
--#endif
-- if (rt2x00dev->workqueue)
-- destroy_workqueue(rt2x00dev->workqueue);
--
-- /*
-- * Free the tx status fifo.
-- */
-- kfifo_free(&rt2x00dev->txstatus_fifo);
-
- /*
- * Kill the tx status tasklet.
-@@ -1466,6 +1451,14 @@ void rt2x00lib_remove_dev(struct rt2x00_
- */
- rt2x00lib_uninitialize(rt2x00dev);
-
-+ if (rt2x00dev->workqueue)
-+ destroy_workqueue(rt2x00dev->workqueue);
-+
-+ /*
-+ * Free the tx status fifo.
-+ */
-+ kfifo_free(&rt2x00dev->txstatus_fifo);
-+
- /*
- * Free extra components
- */
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
-@@ -744,6 +744,11 @@ void rt2x00usb_uninitialize(struct rt2x0
- {
- struct data_queue *queue;
-
-+ usb_kill_anchored_urbs(rt2x00dev->anchor);
-+ hrtimer_cancel(&rt2x00dev->txstatus_timer);
-+ cancel_work_sync(&rt2x00dev->rxdone_work);
-+ cancel_work_sync(&rt2x00dev->txdone_work);
-+
- queue_for_each(rt2x00dev, queue)
- rt2x00usb_free_entries(queue);
- }
+++ /dev/null
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 30 Jan 2017 16:09:51 +0100
-Subject: [PATCH] brcmfmac: check brcmf_bus_get_memdump result for error
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This method may be unsupported (see: USB bus) or may just fail (see:
-SDIO bus).
-While at it rework logic in brcmf_sdio_bus_get_memdump function to avoid
-too many conditional code nesting levels.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
-@@ -32,16 +32,25 @@ static int brcmf_debug_create_memdump(st
- {
- void *dump;
- size_t ramsize;
-+ int err;
-
- ramsize = brcmf_bus_get_ramsize(bus);
-- if (ramsize) {
-- dump = vzalloc(len + ramsize);
-- if (!dump)
-- return -ENOMEM;
-- memcpy(dump, data, len);
-- brcmf_bus_get_memdump(bus, dump + len, ramsize);
-- dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
-+ if (!ramsize)
-+ return -ENOTSUPP;
-+
-+ dump = vzalloc(len + ramsize);
-+ if (!dump)
-+ return -ENOMEM;
-+
-+ memcpy(dump, data, len);
-+ err = brcmf_bus_get_memdump(bus, dump + len, ramsize);
-+ if (err) {
-+ vfree(dump);
-+ return err;
- }
-+
-+ dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
-+
- return 0;
- }
-
+++ /dev/null
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 30 Jan 2017 16:09:52 +0100
-Subject: [PATCH] brcmfmac: be more verbose when PSM's watchdog fires
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's important to inform user so he knows things went wrong. He may also
-want to get memory dump for further debugging purposes.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
-@@ -58,10 +58,18 @@ static int brcmf_debug_psm_watchdog_noti
- const struct brcmf_event_msg *evtmsg,
- void *data)
- {
-+ int err;
-+
- brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
-
-- return brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
-- evtmsg->datalen);
-+ brcmf_err("PSM's watchdog has fired!\n");
-+
-+ err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
-+ evtmsg->datalen);
-+ if (err)
-+ brcmf_err("Failed to get memory dump, %d\n", err);
-+
-+ return err;
- }
-
- void brcmf_debugfs_init(void)
+++ /dev/null
-From 0f83ff69735651cc7a3d150466a5257ff829b62b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 17 Jan 2017 23:35:50 +0100
-Subject: [PATCH] brcmfmac: use wiphy_read_of_freq_limits to respect limits
- from DT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This new helper reads extra frequency limits specified in DT and
-disables unavailable chanels. This is useful for devices (like home
-routers) with chipsets limited e.g. by board design.
-
-In order to respect info read from DT we simply need to check for
-IEEE80211_CHAN_DISABLED bit when constructing channel info.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -5908,6 +5908,9 @@ static int brcmf_construct_chaninfo(stru
- continue;
- }
-
-+ if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
-+ continue;
-+
- /* assuming the chanspecs order is HT20,
- * HT40 upper, HT40 lower, and VHT80.
- */
-@@ -6509,6 +6512,9 @@ static int brcmf_setup_wiphy(struct wiph
- wiphy->bands[NL80211_BAND_5GHZ] = band;
- }
- }
-+
-+ wiphy_read_of_freq_limits(wiphy);
-+
- return 0;
- }
-
+++ /dev/null
-From 9587a01a7ead9efc5032c16e0d9668de58be1186 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 2 Feb 2017 22:33:13 +0100
-Subject: [PATCH] brcmfmac: merge two brcmf_err macros into one
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows simplifying the code by adding a simple IS_ENABLED check for
-CONFIG_BRCMDB symbol.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 8 ++------
- 1 file changed, 2 insertions(+), 6 deletions(-)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
-@@ -45,20 +45,16 @@
- #undef pr_fmt
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-+#ifndef CPTCFG_BRCM_TRACING
- /* Macro for error messages. net_ratelimit() is used when driver
- * debugging is not selected. When debugging the driver error
- * messages are as important as other tracing or even more so.
- */
--#ifndef CPTCFG_BRCM_TRACING
--#ifdef CPTCFG_BRCMDBG
--#define brcmf_err(fmt, ...) pr_err("%s: " fmt, __func__, ##__VA_ARGS__)
--#else
- #define brcmf_err(fmt, ...) \
- do { \
-- if (net_ratelimit()) \
-+ if (IS_ENABLED(CPTCFG_BRCMDBG) || net_ratelimit()) \
- pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \
- } while (0)
--#endif
- #else
- __printf(2, 3)
- void __brcmf_err(const char *func, const char *fmt, ...);
+++ /dev/null
-From 087fa712a00685dac4bcc64b7c3dc8ae6bee8026 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 2 Feb 2017 22:33:14 +0100
-Subject: [PATCH] brcmfmac: switch to C function (__brcmf_err) for printing
- errors
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This will allow extending code and using more detailed messages e.g.
-with the help of dev_err.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- .../net/wireless/broadcom/brcm80211/brcmfmac/common.c | 16 ++++++++++++++++
- drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 6 +++---
- 2 files changed, 19 insertions(+), 3 deletions(-)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
-@@ -218,6 +218,22 @@ done:
- return err;
- }
-
-+#ifndef CPTCFG_BRCM_TRACING
-+void __brcmf_err(const char *func, const char *fmt, ...)
-+{
-+ struct va_format vaf;
-+ va_list args;
-+
-+ va_start(args, fmt);
-+
-+ vaf.fmt = fmt;
-+ vaf.va = &args;
-+ pr_err("%s: %pV", func, &vaf);
-+
-+ va_end(args);
-+}
-+#endif
-+
- #if defined(CPTCFG_BRCM_TRACING) || defined(CPTCFG_BRCMDBG)
- void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
- {
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
-@@ -45,6 +45,8 @@
- #undef pr_fmt
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-+__printf(2, 3)
-+void __brcmf_err(const char *func, const char *fmt, ...);
- #ifndef CPTCFG_BRCM_TRACING
- /* Macro for error messages. net_ratelimit() is used when driver
- * debugging is not selected. When debugging the driver error
-@@ -53,11 +55,9 @@
- #define brcmf_err(fmt, ...) \
- do { \
- if (IS_ENABLED(CPTCFG_BRCMDBG) || net_ratelimit()) \
-- pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \
-+ __brcmf_err(__func__, fmt, ##__VA_ARGS__); \
- } while (0)
- #else
--__printf(2, 3)
--void __brcmf_err(const char *func, const char *fmt, ...);
- #define brcmf_err(fmt, ...) \
- __brcmf_err(__func__, fmt, ##__VA_ARGS__)
- #endif
+++ /dev/null
-From d0630555650a394cf5743268820511f527a561a5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 2 Feb 2017 22:33:15 +0100
-Subject: [PATCH] brcmfmac: merge two remaining brcmf_err macros
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Now we always have __brcmf_err function we can do perfectly fine with
-just one macro.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 14 +++++---------
- 1 file changed, 5 insertions(+), 9 deletions(-)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
-@@ -47,20 +47,16 @@
-
- __printf(2, 3)
- void __brcmf_err(const char *func, const char *fmt, ...);
--#ifndef CPTCFG_BRCM_TRACING
--/* Macro for error messages. net_ratelimit() is used when driver
-- * debugging is not selected. When debugging the driver error
-- * messages are as important as other tracing or even more so.
-+/* Macro for error messages. When debugging / tracing the driver all error
-+ * messages are important to us.
- */
- #define brcmf_err(fmt, ...) \
- do { \
-- if (IS_ENABLED(CPTCFG_BRCMDBG) || net_ratelimit()) \
-+ if (IS_ENABLED(CPTCFG_BRCMDBG) || \
-+ IS_ENABLED(CPTCFG_BRCM_TRACING) || \
-+ net_ratelimit()) \
- __brcmf_err(__func__, fmt, ##__VA_ARGS__); \
- } while (0)
--#else
--#define brcmf_err(fmt, ...) \
-- __brcmf_err(__func__, fmt, ##__VA_ARGS__)
--#endif
-
- #if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING)
- __printf(3, 4)
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 22 Mar 2017 20:37:04 +0100
+Subject: [PATCH] ath9k_hw: fix channel maximum power level test
+
+The tx power applied by set_txpower is limited by the CTL (conformance
+test limit) entries in the EEPROM. These can change based on the user
+configured regulatory domain.
+Depending on the EEPROM data this can cause the tx power to become too
+limited, if the original regdomain CTLs impose lowr limits than the CTLs
+of the user configured regdomain.
+
+To fix this issue, set the initial channel limits without any CTL
+restrictions and only apply the CTL at run time when setting the channel
+and the real tx power.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2937,10 +2937,14 @@ void ath9k_hw_apply_txpower(struct ath_h
+ struct ieee80211_channel *channel;
+ int chan_pwr, new_pwr, max_gain;
+ int ant_gain, ant_reduction = 0;
++ u16 ctl = NO_CTL;
+
+ if (!chan)
+ return;
+
++ if (!test)
++ ctl = ath9k_regd_get_ctl(reg, chan);
++
+ channel = chan->chan;
+ chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
+ new_pwr = min_t(int, chan_pwr, reg->power_limit);
+@@ -2950,9 +2954,7 @@ void ath9k_hw_apply_txpower(struct ath_h
+ if (ant_gain > max_gain)
+ ant_reduction = ant_gain - max_gain;
+
+- ah->eep_ops->set_txpower(ah, chan,
+- ath9k_regd_get_ctl(reg, chan),
+- ant_reduction, new_pwr, test);
++ ah->eep_ops->set_txpower(ah, chan, ctl, ant_reduction, new_pwr, test);
+ }
+
+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
--- /dev/null
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 29 Mar 2017 14:15:24 +0200
+Subject: [PATCH] mac80211: unconditionally start new netdev queues with iTXQ
+ support
+
+When internal mac80211 TXQs aren't supported, netdev queues must
+always started out started even when driver queues are stopped
+while the interface is added. This is necessary because with the
+internal TXQ support netdev queues are never stopped and packet
+scheduling/dropping is done in mac80211.
+
+Cc: stable@vger.kernel.org # 4.9+
+Fixes: 80a83cfc434b1 ("mac80211: skip netdev queue control with software queuing")
+Reported-and-tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -727,7 +727,8 @@ int ieee80211_do_open(struct wireless_de
+ ieee80211_recalc_ps(local);
+
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+- sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
++ local->ops->wake_tx_queue) {
+ /* XXX: for AP_VLAN, actually track AP queues */
+ netif_tx_start_all_queues(dev);
+ } else if (dev) {
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
-@@ -116,6 +116,9 @@ static const struct ieee80211_regdomain
+@@ -24,6 +24,7 @@
+ #include "regd_common.h"
+
+ static int __ath_regd_init(struct ath_regulatory *reg);
++static struct reg_dmn_pair_mapping *ath_get_regpair(int regdmn);
+
+ /*
+ * This is a set of common rules used by our world regulatory domains.
+@@ -116,6 +117,9 @@ static const struct ieee80211_regdomain
static bool dynamic_country_user_possible(struct ath_regulatory *reg)
{
if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
return true;
-@@ -188,6 +191,8 @@ static bool dynamic_country_user_possibl
+@@ -188,6 +192,8 @@ static bool dynamic_country_user_possibl
static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
{
if (!IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_REG_HINTS))
return false;
if (!dynamic_country_user_possible(reg))
-@@ -341,6 +346,9 @@ ath_reg_apply_beaconing_flags(struct wip
+@@ -341,6 +347,9 @@ ath_reg_apply_beaconing_flags(struct wip
struct ieee80211_channel *ch;
unsigned int i;
for (band = 0; band < NUM_NL80211_BANDS; band++) {
if (!wiphy->bands[band])
continue;
-@@ -374,6 +382,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip
+@@ -374,6 +383,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip
{
struct ieee80211_supported_band *sband;
sband = wiphy->bands[NL80211_BAND_2GHZ];
if (!sband)
return;
-@@ -402,6 +413,9 @@ static void ath_reg_apply_radar_flags(st
+@@ -402,6 +414,9 @@ static void ath_reg_apply_radar_flags(st
struct ieee80211_channel *ch;
unsigned int i;
if (!wiphy->bands[NL80211_BAND_5GHZ])
return;
-@@ -634,6 +648,10 @@ ath_regd_init_wiphy(struct ath_regulator
+@@ -539,6 +554,11 @@ void ath_reg_notifier_apply(struct wiphy
+ ath_reg_dyn_country(wiphy, reg, request);
+ break;
+ }
++
++ /* Prevent broken CTLs from being applied */
++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD) &&
++ reg->regpair != common->reg_world_copy.regpair)
++ reg->regpair = ath_get_regpair(WOR0_WORLD);
+ }
+ EXPORT_SYMBOL(ath_reg_notifier_apply);
+
+@@ -634,6 +654,10 @@ ath_regd_init_wiphy(struct ath_regulator
const struct ieee80211_regdomain *regd;
wiphy->reg_notifier = reg_notifier;
wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
REGULATORY_CUSTOM_REG;
+@@ -762,10 +786,7 @@ ath_regd_init(struct ath_regulatory *reg
+ if (r)
+ return r;
+
+- if (ath_is_world_regd(reg))
+- memcpy(&common->reg_world_copy, reg,
+- sizeof(struct ath_regulatory));
+-
++ memcpy(&common->reg_world_copy, reg, sizeof(struct ath_regulatory));
+ ath_regd_init_wiphy(reg, wiphy, reg_notifier);
+
+ return 0;
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -23,6 +23,9 @@ config WLAN_VENDOR_ATH
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
-@@ -43,7 +43,8 @@ static int __ath_regd_init(struct ath_re
+@@ -44,7 +44,8 @@ static struct reg_dmn_pair_mapping *ath_
NL80211_RRF_NO_OFDM)
/* We allow IBSS on these on a case by case basis by regulatory domain */
NL80211_RRF_NO_IR)
#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
NL80211_RRF_NO_IR)
-@@ -61,57 +62,56 @@ static int __ath_regd_init(struct ath_re
+@@ -62,57 +63,56 @@ static struct reg_dmn_pair_mapping *ath_
#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
ATH9K_5GHZ_5725_5850
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
-@@ -114,6 +114,16 @@ static const struct ieee80211_regdomain
+@@ -115,6 +115,16 @@ static const struct ieee80211_regdomain
)
};
static bool dynamic_country_user_possible(struct ath_regulatory *reg)
{
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
-@@ -122,6 +132,9 @@ static bool dynamic_country_user_possibl
+@@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl
if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
return true;
switch (reg->country_code) {
case CTRY_UNITED_STATES:
case CTRY_JAPAN1:
-@@ -207,11 +220,6 @@ static inline bool is_wwr_sku(u16 regd)
+@@ -208,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd)
(regd == WORLD));
}
bool ath_is_world_regd(struct ath_regulatory *reg)
{
return is_wwr_sku(ath_regd_get_eepromRD(reg));
-@@ -652,6 +660,9 @@ ath_regd_init_wiphy(struct ath_regulator
+@@ -658,6 +666,9 @@ ath_regd_init_wiphy(struct ath_regulator
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
return 0;
config RT2800SOC
tristate "Ralink WiSoC support"
depends on m
-- depends on SOC_RT288X || SOC_RT305X
-+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
+- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
select RT2X00_LIB_SOC
select RT2X00_LIB_MMIO
select RT2X00_LIB_CRYPTO
config RT2X00_LIB_SOC
tristate "RT2x00 SoC support"
-- depends on SOC_RT288X || SOC_RT305X
-+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
+- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
depends on m
select RT2X00_LIB
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7956,6 +7956,7 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -9379,6 +9379,7 @@ static int rt2800_probe_rt(struct rt2x00
case RT3390:
case RT3572:
case RT3593:
#define RF5362 0x5362
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7557,6 +7557,66 @@ static const struct rf_channel rf_vals_3
+@@ -8957,6 +8957,66 @@ static const struct rf_channel rf_vals_3
{14, 0xF0, 2, 0x18},
};
static const struct rf_channel rf_vals_5592_xtal20[] = {
/* Channel, N, K, mod, R */
{1, 482, 4, 10, 3},
-@@ -7798,6 +7858,11 @@ static int rt2800_probe_hw_mode(struct r
+@@ -9220,6 +9280,11 @@ static int rt2800_probe_hw_mode(struct r
spec->channels = rf_vals_3x;
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4363,6 +4363,7 @@ void rt2800_vco_calibration(struct rt2x0
+@@ -4855,6 +4855,7 @@ void rt2800_vco_calibration(struct rt2x0
case RF3053:
case RF3070:
case RF3290:
case RF5350:
case RF5360:
case RF5362:
-@@ -7980,6 +7981,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -9402,6 +9403,7 @@ static int rt2800_probe_hw_mode(struct r
case RF3053:
case RF3070:
case RF3290:
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -2584,6 +2584,211 @@ static void rt2800_config_channel_rf3053
+@@ -2709,6 +2709,211 @@ static void rt2800_config_channel_rf3053
}
}
#define POWER_BOUND 0x27
#define POWER_BOUND_5G 0x2b
-@@ -3203,6 +3408,9 @@ static void rt2800_config_channel(struct
+@@ -3565,6 +3770,9 @@ static void rt2800_config_channel(struct
case RF3322:
rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7483,6 +7483,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -8882,6 +8882,7 @@ static int rt2800_init_eeprom(struct rt2
case RF3290:
case RF3320:
case RF3322:
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
-@@ -1574,6 +1574,20 @@
- #define TX_PWR_CFG_9_STBC7_CH2 FIELD32(0x00000f00)
+@@ -1727,6 +1727,20 @@
+ #define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff)
/*
+ * TX_TXBF_CFG:
#define RX_FILTER_CFG 0x1400
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4946,6 +4946,12 @@ static int rt2800_init_registers(struct
+@@ -5485,6 +5485,12 @@ static int rt2800_init_registers(struct
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
0x00000000);
}
+ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
+ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
} else if (rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392)) {
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
-@@ -5140,6 +5146,11 @@ static int rt2800_init_registers(struct
+ rt2x00_rt(rt2x00dev, RT5392) ||
+ rt2x00_rt(rt2x00dev, RT6352)) {
+@@ -5698,6 +5704,11 @@ static int rt2800_init_registers(struct
reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -5767,6 +5767,47 @@ static void rt2800_init_bbp_3593(struct
+@@ -6325,6 +6325,47 @@ static void rt2800_init_bbp_3593(struct
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
}
static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
{
int ant, div_mode;
-@@ -5986,6 +6027,9 @@ static void rt2800_init_bbp(struct rt2x0
+@@ -6769,6 +6810,9 @@ static void rt2800_init_bbp(struct rt2x0
case RT3593:
rt2800_init_bbp_3593(rt2x00dev);
return;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
-@@ -2155,6 +2155,7 @@ struct mac_iveiv_entry {
+@@ -2311,6 +2311,7 @@ struct mac_iveiv_entry {
/*
* RFCSR 2:
*/
+#define RFCSR2_RESCAL_BP FIELD8(0x40)
#define RFCSR2_RESCAL_EN FIELD8(0x80)
-
- /*
+ #define RFCSR2_RX2_EN_MT7620 FIELD8(0x02)
+ #define RFCSR2_TX2_EN_MT7620 FIELD8(0x20)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -6899,6 +6899,144 @@ static void rt2800_init_rfcsr_5350(struc
+@@ -7685,6 +7685,144 @@ static void rt2800_init_rfcsr_5350(struc
rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
}
static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
{
rt2800_rf_init_calibration(rt2x00dev, 2);
-@@ -7130,6 +7268,9 @@ static void rt2800_init_rfcsr(struct rt2
+@@ -8525,6 +8663,9 @@ static void rt2800_init_rfcsr(struct rt2
case RT3390:
rt2800_init_rfcsr_3390(rt2x00dev);
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -309,7 +309,8 @@ static unsigned int rt2800_eeprom_word_i
+@@ -376,7 +376,8 @@ static unsigned int rt2800_eeprom_word_i
wiphy_name(rt2x00dev->hw->wiphy), word))
return 0;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7660,6 +7660,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9059,6 +9059,8 @@ static int rt2800_init_eeprom(struct rt2
rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
else if (rt2x00_rt(rt2x00dev, RT3352))
rf = RF3322;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -3371,6 +3371,36 @@ static char rt2800_txpower_to_dev(struct
+@@ -3733,6 +3733,36 @@ static char rt2800_txpower_to_dev(struct
return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
}
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,
-@@ -3389,6 +3419,12 @@ static void rt2800_config_channel(struct
+@@ -3751,6 +3781,12 @@ static void rt2800_config_channel(struct
rt2800_txpower_to_dev(rt2x00dev, rf->channel,
info->default_power3);
switch (rt2x00dev->chip.rf) {
case RF2020:
case RF3020:
-@@ -3490,6 +3526,15 @@ static void rt2800_config_channel(struct
+@@ -3855,6 +3891,15 @@ static void rt2800_config_channel(struct
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 77, 0x98);
} else {
rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
-@@ -3502,6 +3547,7 @@ static void rt2800_config_channel(struct
- !rt2x00_rt(rt2x00dev, RT5392)) {
+@@ -3868,6 +3913,7 @@ static void rt2800_config_channel(struct
+ !rt2x00_rt(rt2x00dev, RT6352)) {
if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
rt2800_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800_bbp_write(rt2x00dev, 82, 0x62);
rt2800_bbp_write(rt2x00dev, 75, 0x46);
} else {
if (rt2x00_rt(rt2x00dev, RT3593))
-@@ -3510,19 +3556,22 @@ static void rt2800_config_channel(struct
+@@ -3876,19 +3922,22 @@ static void rt2800_config_channel(struct
rt2800_bbp_write(rt2x00dev, 82, 0x84);
rt2800_bbp_write(rt2x00dev, 75, 0x50);
}
+ else if (rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT3883))
rt2800_bbp_write(rt2x00dev, 82, 0x82);
- else
+ else if (!rt2x00_rt(rt2x00dev, RT6352))
rt2800_bbp_write(rt2x00dev, 82, 0xf2);
- if (rt2x00_rt(rt2x00dev, RT3593))
rt2800_bbp_write(rt2x00dev, 83, 0x9a);
if (rt2x00_has_cap_external_lna_a(rt2x00dev))
-@@ -3644,6 +3693,23 @@ static void rt2800_config_channel(struct
+@@ -4011,6 +4060,23 @@ static void rt2800_config_channel(struct
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -3358,13 +3358,15 @@ static char rt2800_txpower_to_dev(struct
+@@ -3720,13 +3720,15 @@ static char rt2800_txpower_to_dev(struct
unsigned int channel,
char txpower)
{
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4596,7 +4596,8 @@ static void rt2800_config_txpower(struct
+@@ -5085,7 +5085,8 @@ static void rt2800_config_txpower(struct
struct ieee80211_channel *chan,
int power_level)
{
+ if (rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT3883))
rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
- else
- rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
+ else if (rt2x00_rt(rt2x00dev, RT6352))
+ rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7543,7 +7543,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
+@@ -8941,7 +8941,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
{
u16 word;
return 0;
rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
-@@ -7557,7 +7558,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
+@@ -8955,7 +8956,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
{
u16 word;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -520,6 +520,7 @@ void rt2800_get_txwi_rxwi_size(struct rt
+@@ -587,6 +587,7 @@ void rt2800_get_txwi_rxwi_size(struct rt
{
switch (rt2x00dev->chip.rt) {
case RT3593:
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -1888,7 +1888,8 @@ void rt2800_config_ant(struct rt2x00_dev
+@@ -2013,7 +2013,8 @@ void rt2800_config_ant(struct rt2x00_dev
rt2800_bbp_write(rt2x00dev, 3, r3);
rt2800_bbp_write(rt2x00dev, 1, r1);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -1911,7 +1911,8 @@ static void rt2800_config_lna_gain(struc
+@@ -2036,7 +2036,8 @@ static void rt2800_config_lna_gain(struc
rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
} else if (libconf->rf.channel <= 128) {
rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
lna_gain = rt2x00_get_field16(eeprom,
EEPROM_EXT_LNA2_A1);
-@@ -1921,7 +1922,8 @@ static void rt2800_config_lna_gain(struc
+@@ -2046,7 +2047,8 @@ static void rt2800_config_lna_gain(struc
EEPROM_RSSI_BG2_LNA_A1);
}
} else {
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -4799,7 +4799,8 @@ static u8 rt2800_get_default_vgc(struct
+@@ -5338,7 +5338,8 @@ static u8 rt2800_get_default_vgc(struct
else
vgc = 0x2e + rt2x00dev->lna_gain;
} else { /* 5GHZ band */
vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
else if (rt2x00_rt(rt2x00dev, RT5592))
vgc = 0x24 + (2 * rt2x00dev->lna_gain);
-@@ -4819,7 +4820,8 @@ static inline void rt2800_set_vgc(struct
+@@ -5358,7 +5359,8 @@ static inline void rt2800_set_vgc(struct
{
if (qual->vgc_level != vgc_level) {
if (rt2x00_rt(rt2x00dev, RT3572) ||
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
vgc_level);
} else if (rt2x00_rt(rt2x00dev, RT5592)) {
-@@ -4866,6 +4868,11 @@ void rt2800_link_tuner(struct rt2x00_dev
+@@ -5405,6 +5407,11 @@ void rt2800_link_tuner(struct rt2x00_dev
}
break;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7676,7 +7676,8 @@ static int rt2800_validate_eeprom(struct
+@@ -9074,7 +9074,8 @@ static int rt2800_validate_eeprom(struct
rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
-@@ -7696,7 +7697,8 @@ static int rt2800_validate_eeprom(struct
+@@ -9094,7 +9095,8 @@ static int rt2800_validate_eeprom(struct
rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
-@@ -7704,7 +7706,8 @@ static int rt2800_validate_eeprom(struct
+@@ -9102,7 +9104,8 @@ static int rt2800_validate_eeprom(struct
}
rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -3965,6 +3965,9 @@ static u8 rt2800_compensate_txpower(stru
+@@ -4332,6 +4332,9 @@ static u8 rt2800_compensate_txpower(stru
if (rt2x00_rt(rt2x00dev, RT3593))
return min_t(u8, txpower, 0xc);
*/
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -999,6 +999,11 @@ struct rt2x00_dev {
+@@ -1000,6 +1000,11 @@ struct rt2x00_dev {
int rf_channel;
/*
obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -20,6 +20,8 @@
- #ifndef RT2800LIB_H
- #define RT2800LIB_H
+@@ -48,6 +48,8 @@ struct rt2800_drv_data {
+ struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE];
+ };
+#include "rt2800.h"
+
struct rt2800_ops {
void (*register_read)(struct rt2x00_dev *rt2x00dev,
const unsigned int offset, u32 *value);
-@@ -119,6 +121,15 @@ static inline int rt2800_read_eeprom(str
+@@ -147,6 +149,15 @@ static inline int rt2800_read_eeprom(str
{
const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
.drv_init_registers = rt2800mmio_init_registers,
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -701,6 +701,7 @@ enum rt2x00_capability_flags {
+@@ -702,6 +702,7 @@ enum rt2x00_capability_flags {
REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE,
REQUIRE_DELAYED_RFKILL,
/*
* Capabilities
-@@ -976,6 +977,11 @@ struct rt2x00_dev {
+@@ -977,6 +978,11 @@ struct rt2x00_dev {
const struct firmware *fw;
/*
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1346,6 +1346,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1418,6 +1418,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
/*
* Let the driver probe the device to detect the capabilities.
*/
-@@ -1484,6 +1488,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1556,6 +1560,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
* Free the driver data.
*/
kfree(rt2x00dev->drv_data);
#endif /* _RT2X00_PLATFORM_H */
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -951,6 +951,22 @@ static int rt2x00lib_probe_hw_modes(stru
+@@ -1023,6 +1023,22 @@ static int rt2x00lib_probe_hw_modes(stru
unsigned int num_rates;
unsigned int i;
num_rates += 4;
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -408,6 +408,7 @@ struct hw_mode_spec {
+@@ -409,6 +409,7 @@ struct hw_mode_spec {
unsigned int supported_bands;
#define SUPPORT_BAND_2GHZ 0x00000001
#define SUPPORT_BAND_5GHZ 0x00000002
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -929,8 +929,13 @@ static void rt2x00lib_rate(struct ieee80
+@@ -1001,8 +1001,13 @@ static void rt2x00lib_rate(struct ieee80
void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
{
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -955,6 +955,16 @@ static int rt2x00lib_probe_hw_modes(stru
+@@ -1027,6 +1027,16 @@ static int rt2x00lib_probe_hw_modes(stru
struct ieee80211_rate *rates;
unsigned int num_rates;
unsigned int i;
#include "rt2x00.h"
#include "rt2800lib.h"
-@@ -7861,6 +7862,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -9261,6 +9262,17 @@ static int rt2800_init_eeprom(struct rt2
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1286,7 +1286,7 @@ static inline void rt2x00lib_set_if_comb
+@@ -1358,7 +1358,7 @@ static inline void rt2x00lib_set_if_comb
*/
if_limit = &rt2x00dev->if_limits_ap;
if_limit->max = rt2x00dev->ops->max_ap_intf;
+++ /dev/null
---- a/drivers/net/wireless/ralink/rt2x00/Kconfig
-+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
-@@ -211,7 +211,7 @@ endif
- config RT2800SOC
- tristate "Ralink WiSoC support"
- depends on m
-- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
-+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
- select RT2X00_LIB_SOC
- select RT2X00_LIB_MMIO
- select RT2X00_LIB_CRYPTO
-@@ -248,7 +248,7 @@ config RT2X00_LIB_PCI
-
- config RT2X00_LIB_SOC
- tristate "RT2x00 SoC support"
-- depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
-+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
- depends on m
- select RT2X00_LIB
-
+++ /dev/null
-From: Roman Yeryomin <roman@advem.lv>
-Date: Tue, 1 Jul 2014 10:26:18 +0000
-Subject: [PATCH] mac80211: rt2x00: add support for mt7620
-
-Support for MT7620 was added to OpenWrt in r41441 and heavily reworked
-since in order to match the Kernel's code quality standards.
-
-Signed-off-by: Roman Yeryomin <roman@advem.lv>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
-@@ -81,6 +81,7 @@
- #define RF5372 0x5372
- #define RF5390 0x5390
- #define RF5392 0x5392
-+#define RF7620 0x7620
-
- /*
- * Chipset revisions.
-@@ -641,6 +642,14 @@
- #define RF_CSR_CFG_BUSY FIELD32(0x00020000)
-
- /*
-+ * mt7620 RF registers (reversed order)
-+ */
-+#define RF_CSR_CFG_DATA_MT7620 FIELD32(0x0000ff00)
-+#define RF_CSR_CFG_REGNUM_MT7620 FIELD32(0x03ff0000)
-+#define RF_CSR_CFG_WRITE_MT7620 FIELD32(0x00000010)
-+#define RF_CSR_CFG_BUSY_MT7620 FIELD32(0x00000001)
-+
-+/*
- * EFUSE_CSR: RT30x0 EEPROM
- */
- #define EFUSE_CTRL 0x0580
-@@ -1024,6 +1033,11 @@
- #define AUTOWAKEUP_CFG_AUTOWAKE FIELD32(0x00008000)
-
- /*
-+ * mt7620
-+ */
-+#define MIMO_PS_CFG 0x1210
-+
-+/*
- * EDCA_AC0_CFG:
- */
- #define EDCA_AC0_CFG 0x1300
-@@ -1203,6 +1217,8 @@
- #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000)
- #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000)
- #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000)
-+#define TX_PIN_CFG_RFRX_EN FIELD32(0x00100000) /* mt7620 */
-+#define TX_PIN_CFG_RFRX_POL FIELD32(0x00200000) /* mt7620 */
- #define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000)
- #define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000)
- #define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000)
-@@ -1549,6 +1565,17 @@
- #define TX_PWR_CFG_4_EXT_STBC4_CH2 FIELD32(0x0000000f)
- #define TX_PWR_CFG_4_EXT_STBC6_CH2 FIELD32(0x00000f00)
-
-+/* mt7620 */
-+#define TX0_RF_GAIN_CORRECT 0x13a0
-+#define TX1_RF_GAIN_CORRECT 0x13a4
-+#define TX0_RF_GAIN_ATTEN 0x13a8
-+#define TX1_RF_GAIN_ATTEN 0x13ac
-+#define TX_ALG_CFG_0 0x13b0
-+#define TX_ALG_CFG_1 0x13b4
-+#define TX0_BB_GAIN_ATTEN 0x13c0
-+#define TX1_BB_GAIN_ATTEN 0x13c4
-+#define TX_ALC_VGA3 0x13c8
-+
- /* TX_PWR_CFG_7 */
- #define TX_PWR_CFG_7 0x13d4
- #define TX_PWR_CFG_7_OFDM54_CH0 FIELD32(0x0000000f)
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -60,6 +60,9 @@
- rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
- #define WAIT_FOR_RFCSR(__dev, __reg) \
- rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
-+#define WAIT_FOR_RFCSR_MT7620(__dev, __reg) \
-+ rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY_MT7620, \
-+ (__reg))
- #define WAIT_FOR_RF(__dev, __reg) \
- rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
- #define WAIT_FOR_MCU(__dev, __reg) \
-@@ -151,19 +154,56 @@ static void rt2800_rfcsr_write(struct rt
- * Wait until the RFCSR becomes available, afterwards we
- * can safely write the new data into the register.
- */
-- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
-- reg = 0;
-- rt2x00_set_field32(®, RF_CSR_CFG_DATA, value);
-- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
-- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1);
-- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
-+ switch (rt2x00dev->chip.rf) {
-+ case RF7620:
-+ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) {
-+ reg = 0;
-+ rt2x00_set_field32(®, RF_CSR_CFG_DATA_MT7620, value);
-+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620,
-+ word);
-+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 1);
-+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1);
-+
-+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
-+ }
-+ break;
-+
-+ default:
-+ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
-+ reg = 0;
-+ rt2x00_set_field32(®, RF_CSR_CFG_DATA, value);
-+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
-+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1);
-+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
-
-- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
-+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
-+ }
-+ break;
- }
-
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
-
-+static void rt2800_rfcsr_write_bank(struct rt2x00_dev *rt2x00dev, const u8 bank,
-+ const unsigned int reg, const u8 value)
-+{
-+ rt2800_rfcsr_write(rt2x00dev, (reg | (bank << 6)), value);
-+}
-+
-+static void rt2800_rfcsr_write_chanreg(struct rt2x00_dev *rt2x00dev,
-+ const unsigned int reg, const u8 value)
-+{
-+ rt2800_rfcsr_write_bank(rt2x00dev, 4, reg, value);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 6, reg, value);
-+}
-+
-+static void rt2800_rfcsr_write_dccal(struct rt2x00_dev *rt2x00dev,
-+ const unsigned int reg, const u8 value)
-+{
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, reg, value);
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value);
-+}
-+
- static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev,
- const unsigned int word, u8 *value)
- {
-@@ -179,22 +219,48 @@ static void rt2800_rfcsr_read(struct rt2
- * doesn't become available in time, reg will be 0xffffffff
- * which means we return 0xff to the caller.
- */
-- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
-- reg = 0;
-- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
-- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0);
-- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
-+ switch (rt2x00dev->chip.rf) {
-+ case RF7620:
-+ if (WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®)) {
-+ reg = 0;
-+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM_MT7620,
-+ word);
-+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE_MT7620, 0);
-+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY_MT7620, 1);
-
-- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
-+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
-
-- WAIT_FOR_RFCSR(rt2x00dev, ®);
-- }
-+ WAIT_FOR_RFCSR_MT7620(rt2x00dev, ®);
-+ }
-+
-+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA_MT7620);
-+ break;
-+
-+ default:
-+ if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
-+ reg = 0;
-+ rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
-+ rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0);
-+ rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
-
-- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
-+ rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
-+
-+ WAIT_FOR_RFCSR(rt2x00dev, ®);
-+ }
-+
-+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
-+ break;
-+ }
-
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
-
-+static void rt2800_rfcsr_read_bank(struct rt2x00_dev *rt2x00dev, const u8 bank,
-+ const unsigned int reg, u8 *value)
-+{
-+ rt2800_rfcsr_read(rt2x00dev, (reg | (bank << 6)), value);
-+}
-+
- static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
- const unsigned int word, const u32 value)
- {
-@@ -526,6 +592,16 @@ void rt2800_get_txwi_rxwi_size(struct rt
- *rxwi_size = RXWI_DESC_SIZE_5WORDS;
- break;
-
-+ case RT5390:
-+ if (rt2x00dev->chip.rf == RF7620) {
-+ *txwi_size = TXWI_DESC_SIZE_5WORDS;
-+ *rxwi_size = RXWI_DESC_SIZE_6WORDS;
-+ } else {
-+ *txwi_size = TXWI_DESC_SIZE_4WORDS;
-+ *rxwi_size = RXWI_DESC_SIZE_4WORDS;
-+ }
-+ break;
-+
- case RT5592:
- *txwi_size = TXWI_DESC_SIZE_5WORDS;
- *rxwi_size = RXWI_DESC_SIZE_6WORDS;
-@@ -3258,6 +3334,296 @@ static void rt2800_config_channel_rf55xx
- rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F);
- }
-
-+static void rt2800_config_channel_rf7620(struct rt2x00_dev *rt2x00dev,
-+ struct ieee80211_conf *conf,
-+ struct rf_channel *rf,
-+ struct channel_info *info)
-+{
-+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
-+ u32 mac_sys_ctrl, mac_status;
-+ u16 eeprom, target_power;
-+ u32 tx_pin = 0x00150F0F;
-+ u8 txrx_agc_fc;
-+ u8 rfcsr;
-+ u32 reg;
-+ u8 bbp;
-+ int i;
-+
-+ /* Frequeny plan setting */
-+ /* Rdiv setting (stored in rf->rf1)
-+ * R13[1:0]
-+ */
-+ rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
-+ rfcsr = rfcsr & (~0x03);
-+ if (rt2800_clk_is_20mhz(rt2x00dev))
-+ rfcsr |= (rf->rf1 & 0x03);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
-+
-+ /* N setting (stored in rf->rf2)
-+ * R21[0], R20[7:0]
-+ */
-+ rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
-+ rfcsr = (rf->rf2 & 0x00ff);
-+ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
-+ rfcsr = rfcsr & (~0x01);
-+ rfcsr |= ((rf->rf2 & 0x0100) >> 8);
-+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
-+
-+ /* K setting (stored in rf->rf3[0:7])
-+ * R16[3:0] (RF PLL freq selection)
-+ */
-+ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr);
-+ rfcsr = rfcsr & (~0x0f);
-+ rfcsr |= (rf->rf3 & 0x0f);
-+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
-+
-+ /* D setting (stored in rf->rf3[8:15])
-+ * R22[2:0] (D=15, R22[2:0]=<111>)
-+ */
-+ rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
-+ rfcsr = rfcsr & (~0x07);
-+ rfcsr |= ((rf->rf3 >> 8) & 0x07);
-+ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
-+
-+ /* Ksd setting (stored in rf->rf4)
-+ * Ksd: R19<1:0>,R18<7:0>,R17<7:0>
-+ */
-+ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
-+ rfcsr = (rf->rf4 & 0x000000ff);
-+ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 18, &rfcsr);
-+ rfcsr = ((rf->rf4 & 0x0000ff00) >> 8);
-+ rt2800_rfcsr_write(rt2x00dev, 18, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 19, &rfcsr);
-+ rfcsr = rfcsr & (~0x03);
-+ rfcsr |= ((rf->rf4 & 0x00030000) >> 16);
-+ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr);
-+
-+ /* Default: XO=20MHz , SDM mode */
-+ rt2800_rfcsr_read(rt2x00dev, 16, &rfcsr);
-+ rfcsr = rfcsr & (~0xE0);
-+ rfcsr |= 0x80;
-+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
-+ rfcsr |= 0x80;
-+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
-+ if (rt2x00dev->default_ant.tx_chain_num == 1)
-+ rfcsr &= (~0x2);
-+ else
-+ rfcsr |= 0x2;
-+ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
-+ if (rt2x00dev->default_ant.tx_chain_num == 1)
-+ rfcsr &= (~0x20);
-+ else
-+ rfcsr |= 0x20;
-+ if (rt2x00dev->default_ant.rx_chain_num == 1)
-+ rfcsr &= (~0x02);
-+ else
-+ rfcsr |= 0x02;
-+ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
-+
-+ rt2800_rfcsr_read(rt2x00dev, 42, &rfcsr);
-+ if (rt2x00dev->default_ant.tx_chain_num == 1)
-+ rfcsr &= (~0x40);
-+ else
-+ rfcsr |= 0x40;
-+ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr);
-+
-+ /* RF for DC Cal BW */
-+ if (conf_is_ht40(conf)) {
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10);
-+ } else {
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x20);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x20);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x20);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20);
-+ }
-+
-+ if (conf_is_ht40(conf)) {
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
-+ } else {
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
-+ }
-+
-+ rt2800_rfcsr_read(rt2x00dev, 28, &rfcsr);
-+ if (conf_is_ht40(conf) && (rf->channel == 11))
-+ rfcsr |= 0x4;
-+ else
-+ rfcsr &= (~0x4);
-+ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
-+
-+ /*if (bScan == FALSE)*/
-+ if (conf_is_ht40(conf)) {
-+ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw40,
-+ RFCSR24_TX_AGC_FC);
-+ } else {
-+ txrx_agc_fc = rt2x00_get_field8(drv_data->calibration_bw20,
-+ RFCSR24_TX_AGC_FC);
-+ }
-+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 6, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 6, rfcsr);
-+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 7, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 7, rfcsr);
-+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 6, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 6, rfcsr);
-+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 7, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 7, rfcsr);
-+
-+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 58, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 58, rfcsr);
-+ rt2800_rfcsr_read_bank(rt2x00dev, 5, 59, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 59, rfcsr);
-+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 58, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 58, rfcsr);
-+ rt2800_rfcsr_read_bank(rt2x00dev, 7, 59, &rfcsr);
-+ rfcsr &= (~0x3F);
-+ rfcsr |= txrx_agc_fc;
-+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
-+
-+ rt2800_register_read(rt2x00dev, TX_ALG_CFG_0, ®);
-+ reg = reg & (~0x3F3F);
-+ reg |= info->default_power1;
-+ reg |= (info->default_power2 << 8);
-+ reg |= (0x2F << 16);
-+ reg |= (0x2F << 24);
-+
-+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) {
-+ /* init base power by e2p target power */
-+ rt2800_eeprom_read(rt2x00dev, 0xD0, &target_power);
-+ target_power &= 0x3F;
-+ reg = reg & (~0x3F3F);
-+ reg |= target_power;
-+ reg |= (target_power << 8);
-+ }
-+ rt2800_register_write(rt2x00dev, TX_ALG_CFG_0, reg);
-+
-+ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, ®);
-+ reg = reg & (~0x3F);
-+ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg);
-+
-+ /*if (bScan == FALSE)*/
-+ /* Save MAC SYS CTRL registers */
-+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &mac_sys_ctrl);
-+ /* Disable Tx/Rx */
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
-+ /* Check MAC Tx/Rx idle */
-+ for (i = 0; i < 10000; i++) {
-+ rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, &mac_status);
-+ if (mac_status & 0x3)
-+ usleep_range(50, 200);
-+ else
-+ break;
-+ }
-+
-+ if (i == 10000)
-+ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
-+
-+ if (rf->channel > 10) {
-+ rt2800_bbp_read(rt2x00dev, 30, &bbp);
-+ bbp = 0x40;
-+ rt2800_bbp_write(rt2x00dev, 30, bbp);
-+ rt2800_rfcsr_write(rt2x00dev, 39, 0);
-+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
-+ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
-+ else
-+ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
-+ } else {
-+ rt2800_bbp_read(rt2x00dev, 30, &bbp);
-+ bbp = 0x1f;
-+ rt2800_bbp_write(rt2x00dev, 30, bbp);
-+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
-+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
-+ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
-+ else
-+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
-+ }
-+
-+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 5, 0x40);
-+ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C);
-+
-+ /* vcocal_en (initiate VCO calibration (reset after completion)) */
-+ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr);
-+ rfcsr = ((rfcsr & ~0x80) | 0x80);
-+ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr);
-+ usleep_range(2000, 3000);
-+
-+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
-+
-+ if (rt2x00dev->default_ant.tx_chain_num == 1) {
-+ rt2800_bbp_write(rt2x00dev, 91, 0x07);
-+ rt2800_bbp_write(rt2x00dev, 95, 0x1A);
-+ rt2800_bbp_write(rt2x00dev, 195, 128);
-+ rt2800_bbp_write(rt2x00dev, 196, 0xA0);
-+ rt2800_bbp_write(rt2x00dev, 195, 170);
-+ rt2800_bbp_write(rt2x00dev, 196, 0x12);
-+ rt2800_bbp_write(rt2x00dev, 195, 171);
-+ rt2800_bbp_write(rt2x00dev, 196, 0x10);
-+ } else {
-+ rt2800_bbp_write(rt2x00dev, 91, 0x06);
-+ rt2800_bbp_write(rt2x00dev, 95, 0x9A);
-+ rt2800_bbp_write(rt2x00dev, 195, 128);
-+ rt2800_bbp_write(rt2x00dev, 196, 0xE0);
-+ rt2800_bbp_write(rt2x00dev, 195, 170);
-+ rt2800_bbp_write(rt2x00dev, 196, 0x30);
-+ rt2800_bbp_write(rt2x00dev, 195, 171);
-+ rt2800_bbp_write(rt2x00dev, 196, 0x30);
-+ }
-+
-+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
-+ rt2800_bbp_write(rt2x00dev, 75, 0x60);
-+ rt2800_bbp_write(rt2x00dev, 76, 0x44);
-+ rt2800_bbp_write(rt2x00dev, 79, 0x1C);
-+ rt2800_bbp_write(rt2x00dev, 80, 0x0C);
-+ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
-+
-+ if (!conf_is_ht40(conf)) {
-+ rt2800_bbp_write(rt2x00dev, 195, 141);
-+ rt2800_bbp_write(rt2x00dev, 196, 0x1A);
-+ }
-+ }
-+
-+ /* On 11A, We should delay and wait RF/BBP to be stable
-+ * and the appropriate time should be 1000 micro seconds
-+ * 2005/06/05 - On 11G, we also need this delay time.
-+ * Otherwise it's difficult to pass the WHQL.
-+ */
-+ usleep_range(1000, 1500);
-+}
-+
- static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev,
- const unsigned int word,
- const u8 value)
-@@ -3414,7 +3780,7 @@ static void rt2800_config_channel(struct
- struct channel_info *info)
- {
- u32 reg;
-- unsigned int tx_pin;
-+ u32 tx_pin;
- u8 bbp, rfcsr;
-
- info->default_power1 = rt2800_txpower_to_dev(rt2x00dev, rf->channel,
-@@ -3468,6 +3834,9 @@ static void rt2800_config_channel(struct
- case RF5592:
- rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info);
- break;
-+ case RF7620:
-+ rt2800_config_channel_rf7620(rt2x00dev, conf, rf, info);
-+ break;
- default:
- rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
- }
-@@ -3574,7 +3943,7 @@ static void rt2800_config_channel(struct
- else if (rt2x00_rt(rt2x00dev, RT3593) ||
- rt2x00_rt(rt2x00dev, RT3883))
- rt2800_bbp_write(rt2x00dev, 82, 0x82);
-- else
-+ else if (rt2x00dev->chip.rf != RF7620)
- rt2800_bbp_write(rt2x00dev, 82, 0xf2);
-
- if (rt2x00_rt(rt2x00dev, RT3593) ||
-@@ -3596,7 +3965,7 @@ static void rt2800_config_channel(struct
- if (rt2x00_rt(rt2x00dev, RT3572))
- rt2800_rfcsr_write(rt2x00dev, 8, 0);
-
-- tx_pin = 0;
-+ rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin);
-
- switch (rt2x00dev->default_ant.tx_chain_num) {
- case 3:
-@@ -3645,6 +4014,7 @@ static void rt2800_config_channel(struct
-
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
-+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */
-
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
-
-@@ -3720,7 +4090,8 @@ static void rt2800_config_channel(struct
- usleep_range(1000, 1500);
- }
-
-- if (rt2x00_rt(rt2x00dev, RT5592)) {
-+ if (rt2x00_rt(rt2x00dev, RT5592) ||
-+ (rt2x00_rt(rt2x00dev, RT5390) && rt2x00_rf(rt2x00dev, RF7620))) {
- rt2800_bbp_write(rt2x00dev, 195, 141);
- rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
-
-@@ -4662,6 +5033,15 @@ void rt2800_vco_calibration(struct rt2x0
- rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
- rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
- break;
-+ case RF7620:
-+ rt2800_rfcsr_read(rt2x00dev, 4, &rfcsr);
-+ /* vcocal_en (initiate VCO calibration (reset after completion))
-+ * It should be at the end of RF configuration.
-+ */
-+ rfcsr = ((rfcsr & ~0x80) | 0x80);
-+ rt2800_rfcsr_write(rt2x00dev, 4, rfcsr);
-+ usleep_range(2000, 3000);
-+ break;
- default:
- WARN_ONCE(1, "Not supported RF chipet %x for VCO recalibration",
- rt2x00dev->chip.rf);
-@@ -5037,6 +5417,24 @@ static int rt2800_init_registers(struct
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000);
- rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
- rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
-+ } else if (rt2x00_rf(rt2x00dev, RF7620)) {
-+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
-+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
-+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
-+ rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002);
-+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F);
-+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606);
-+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
-+ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);
-+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C);
-+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
-+ 0x3630363A);
-+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
-+ 0x3630363A);
-+ rt2800_register_read(rt2x00dev, TX_ALG_CFG_1, ®);
-+ reg = reg & (~0x80000000);
-+ rt2800_register_write(rt2x00dev, TX_ALG_CFG_1, reg);
- } else if (rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392)) {
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
-@@ -6075,6 +6473,225 @@ static void rt2800_init_bbp_5592(struct
- rt2800_bbp_write(rt2x00dev, 103, 0xc0);
- }
-
-+static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
-+ const u8 reg, const u8 value)
-+{
-+ rt2800_bbp_write(rt2x00dev, 195, reg);
-+ rt2800_bbp_write(rt2x00dev, 196, value);
-+}
-+
-+static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
-+ const u8 reg, const u8 value)
-+{
-+ rt2800_bbp_write(rt2x00dev, 158, reg);
-+ rt2800_bbp_write(rt2x00dev, 159, value);
-+}
-+
-+static void rt2800_init_bbp_7620(struct rt2x00_dev *rt2x00dev)
-+{
-+ u8 bbp;
-+
-+ /* Apply Maximum Likelihood Detection (MLD) for 2 stream case */
-+ rt2800_bbp_read(rt2x00dev, 105, &bbp);
-+ rt2x00_set_field8(&bbp, BBP105_MLD,
-+ rt2x00dev->default_ant.rx_chain_num == 2);
-+ rt2800_bbp_write(rt2x00dev, 105, bbp);
-+
-+ /* Avoid data loss and CRC errors */
-+ /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */
-+ rt2800_bbp4_mac_if_ctrl(rt2x00dev);
-+
-+ /* Fix I/Q swap issue */
-+ rt2800_bbp_read(rt2x00dev, 1, &bbp);
-+ bbp |= 0x04;
-+ rt2800_bbp_write(rt2x00dev, 1, bbp);
-+
-+ /* BBP for G band */
-+ rt2800_bbp_write(rt2x00dev, 3, 0x08);
-+ rt2800_bbp_write(rt2x00dev, 4, 0x00); /* rt2800_bbp4_mac_if_ctrl? */
-+ rt2800_bbp_write(rt2x00dev, 6, 0x08);
-+ rt2800_bbp_write(rt2x00dev, 14, 0x09);
-+ rt2800_bbp_write(rt2x00dev, 15, 0xFF);
-+ rt2800_bbp_write(rt2x00dev, 16, 0x01);
-+ rt2800_bbp_write(rt2x00dev, 20, 0x06);
-+ rt2800_bbp_write(rt2x00dev, 21, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 22, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 27, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 28, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 30, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 31, 0x48);
-+ rt2800_bbp_write(rt2x00dev, 47, 0x40);
-+ rt2800_bbp_write(rt2x00dev, 62, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 63, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 64, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 65, 0x2C);
-+ rt2800_bbp_write(rt2x00dev, 66, 0x1C);
-+ rt2800_bbp_write(rt2x00dev, 67, 0x20);
-+ rt2800_bbp_write(rt2x00dev, 68, 0xDD);
-+ rt2800_bbp_write(rt2x00dev, 69, 0x10);
-+ rt2800_bbp_write(rt2x00dev, 70, 0x05);
-+ rt2800_bbp_write(rt2x00dev, 73, 0x18);
-+ rt2800_bbp_write(rt2x00dev, 74, 0x0F);
-+ rt2800_bbp_write(rt2x00dev, 75, 0x60);
-+ rt2800_bbp_write(rt2x00dev, 76, 0x44);
-+ rt2800_bbp_write(rt2x00dev, 77, 0x59);
-+ rt2800_bbp_write(rt2x00dev, 78, 0x1E);
-+ rt2800_bbp_write(rt2x00dev, 79, 0x1C);
-+ rt2800_bbp_write(rt2x00dev, 80, 0x0C);
-+ rt2800_bbp_write(rt2x00dev, 81, 0x3A);
-+ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
-+ rt2800_bbp_write(rt2x00dev, 83, 0x9A);
-+ rt2800_bbp_write(rt2x00dev, 84, 0x9A);
-+ rt2800_bbp_write(rt2x00dev, 86, 0x38);
-+ rt2800_bbp_write(rt2x00dev, 88, 0x90);
-+ rt2800_bbp_write(rt2x00dev, 91, 0x04);
-+ rt2800_bbp_write(rt2x00dev, 92, 0x02);
-+ rt2800_bbp_write(rt2x00dev, 95, 0x9A);
-+ rt2800_bbp_write(rt2x00dev, 96, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 103, 0xC0);
-+ rt2800_bbp_write(rt2x00dev, 104, 0x92);
-+ /* FIXME BBP105 owerwrite */
-+ rt2800_bbp_write(rt2x00dev, 105, 0x3C);
-+ rt2800_bbp_write(rt2x00dev, 106, 0x12);
-+ rt2800_bbp_write(rt2x00dev, 109, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 134, 0x10);
-+ rt2800_bbp_write(rt2x00dev, 135, 0xA6);
-+ rt2800_bbp_write(rt2x00dev, 137, 0x04);
-+ rt2800_bbp_write(rt2x00dev, 142, 0x30);
-+ rt2800_bbp_write(rt2x00dev, 143, 0xF7);
-+ rt2800_bbp_write(rt2x00dev, 160, 0xEC);
-+ rt2800_bbp_write(rt2x00dev, 161, 0xC4);
-+ rt2800_bbp_write(rt2x00dev, 162, 0x77);
-+ rt2800_bbp_write(rt2x00dev, 163, 0xF9);
-+ rt2800_bbp_write(rt2x00dev, 164, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 165, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 186, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 187, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 188, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 186, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 187, 0x01);
-+ rt2800_bbp_write(rt2x00dev, 188, 0x00);
-+ rt2800_bbp_write(rt2x00dev, 189, 0x00);
-+
-+ rt2800_bbp_write(rt2x00dev, 91, 0x06);
-+ rt2800_bbp_write(rt2x00dev, 92, 0x04);
-+ rt2800_bbp_write(rt2x00dev, 93, 0x54);
-+ rt2800_bbp_write(rt2x00dev, 99, 0x50);
-+ rt2800_bbp_write(rt2x00dev, 148, 0x84);
-+ rt2800_bbp_write(rt2x00dev, 167, 0x80);
-+ rt2800_bbp_write(rt2x00dev, 178, 0xFF);
-+ rt2800_bbp_write(rt2x00dev, 106, 0x13);
-+
-+ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */
-+ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00);
-+ rt2800_bbp_glrt_write(rt2x00dev, 1, 0x14); /* ? see above */
-+ rt2800_bbp_glrt_write(rt2x00dev, 2, 0x20);
-+ rt2800_bbp_glrt_write(rt2x00dev, 3, 0x0A);
-+ rt2800_bbp_glrt_write(rt2x00dev, 10, 0x16);
-+ rt2800_bbp_glrt_write(rt2x00dev, 11, 0x06);
-+ rt2800_bbp_glrt_write(rt2x00dev, 12, 0x02);
-+ rt2800_bbp_glrt_write(rt2x00dev, 13, 0x07);
-+ rt2800_bbp_glrt_write(rt2x00dev, 14, 0x05);
-+ rt2800_bbp_glrt_write(rt2x00dev, 15, 0x09);
-+ rt2800_bbp_glrt_write(rt2x00dev, 16, 0x20);
-+ rt2800_bbp_glrt_write(rt2x00dev, 17, 0x08);
-+ rt2800_bbp_glrt_write(rt2x00dev, 18, 0x4A);
-+ rt2800_bbp_glrt_write(rt2x00dev, 19, 0x00);
-+ rt2800_bbp_glrt_write(rt2x00dev, 20, 0x00);
-+ rt2800_bbp_glrt_write(rt2x00dev, 128, 0xE0);
-+ rt2800_bbp_glrt_write(rt2x00dev, 129, 0x1F);
-+ rt2800_bbp_glrt_write(rt2x00dev, 130, 0x4F);
-+ rt2800_bbp_glrt_write(rt2x00dev, 131, 0x32);
-+ rt2800_bbp_glrt_write(rt2x00dev, 132, 0x08);
-+ rt2800_bbp_glrt_write(rt2x00dev, 133, 0x28);
-+ rt2800_bbp_glrt_write(rt2x00dev, 134, 0x19);
-+ rt2800_bbp_glrt_write(rt2x00dev, 135, 0x0A);
-+ rt2800_bbp_glrt_write(rt2x00dev, 138, 0x16);
-+ rt2800_bbp_glrt_write(rt2x00dev, 139, 0x10);
-+ rt2800_bbp_glrt_write(rt2x00dev, 140, 0x10);
-+ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1A);
-+ rt2800_bbp_glrt_write(rt2x00dev, 142, 0x36);
-+ rt2800_bbp_glrt_write(rt2x00dev, 143, 0x2C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 144, 0x26);
-+ rt2800_bbp_glrt_write(rt2x00dev, 145, 0x24);
-+ rt2800_bbp_glrt_write(rt2x00dev, 146, 0x42);
-+ rt2800_bbp_glrt_write(rt2x00dev, 147, 0x40);
-+ rt2800_bbp_glrt_write(rt2x00dev, 148, 0x30);
-+ rt2800_bbp_glrt_write(rt2x00dev, 149, 0x29);
-+ rt2800_bbp_glrt_write(rt2x00dev, 150, 0x4C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 151, 0x46);
-+ rt2800_bbp_glrt_write(rt2x00dev, 152, 0x3D);
-+ rt2800_bbp_glrt_write(rt2x00dev, 153, 0x40);
-+ rt2800_bbp_glrt_write(rt2x00dev, 154, 0x3E);
-+ rt2800_bbp_glrt_write(rt2x00dev, 155, 0x38);
-+ rt2800_bbp_glrt_write(rt2x00dev, 156, 0x3D);
-+ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2F);
-+ rt2800_bbp_glrt_write(rt2x00dev, 158, 0x3C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 159, 0x34);
-+ rt2800_bbp_glrt_write(rt2x00dev, 160, 0x2C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 161, 0x2F);
-+ rt2800_bbp_glrt_write(rt2x00dev, 162, 0x3C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 163, 0x35);
-+ rt2800_bbp_glrt_write(rt2x00dev, 164, 0x2E);
-+ rt2800_bbp_glrt_write(rt2x00dev, 165, 0x2F);
-+ rt2800_bbp_glrt_write(rt2x00dev, 166, 0x49);
-+ rt2800_bbp_glrt_write(rt2x00dev, 167, 0x41);
-+ rt2800_bbp_glrt_write(rt2x00dev, 168, 0x36);
-+ rt2800_bbp_glrt_write(rt2x00dev, 169, 0x39);
-+ rt2800_bbp_glrt_write(rt2x00dev, 170, 0x30);
-+ rt2800_bbp_glrt_write(rt2x00dev, 171, 0x30);
-+ rt2800_bbp_glrt_write(rt2x00dev, 172, 0x0E);
-+ rt2800_bbp_glrt_write(rt2x00dev, 173, 0x0D);
-+ rt2800_bbp_glrt_write(rt2x00dev, 174, 0x28);
-+ rt2800_bbp_glrt_write(rt2x00dev, 175, 0x21);
-+ rt2800_bbp_glrt_write(rt2x00dev, 176, 0x1C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 177, 0x16);
-+ rt2800_bbp_glrt_write(rt2x00dev, 178, 0x50);
-+ rt2800_bbp_glrt_write(rt2x00dev, 179, 0x4A);
-+ rt2800_bbp_glrt_write(rt2x00dev, 180, 0x43);
-+ rt2800_bbp_glrt_write(rt2x00dev, 181, 0x50);
-+ rt2800_bbp_glrt_write(rt2x00dev, 182, 0x10);
-+ rt2800_bbp_glrt_write(rt2x00dev, 183, 0x10);
-+ rt2800_bbp_glrt_write(rt2x00dev, 184, 0x10);
-+ rt2800_bbp_glrt_write(rt2x00dev, 185, 0x10);
-+ rt2800_bbp_glrt_write(rt2x00dev, 200, 0x7D);
-+ rt2800_bbp_glrt_write(rt2x00dev, 201, 0x14);
-+ rt2800_bbp_glrt_write(rt2x00dev, 202, 0x32);
-+ rt2800_bbp_glrt_write(rt2x00dev, 203, 0x2C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 204, 0x36);
-+ rt2800_bbp_glrt_write(rt2x00dev, 205, 0x4C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 206, 0x43);
-+ rt2800_bbp_glrt_write(rt2x00dev, 207, 0x2C);
-+ rt2800_bbp_glrt_write(rt2x00dev, 208, 0x2E);
-+ rt2800_bbp_glrt_write(rt2x00dev, 209, 0x36);
-+ rt2800_bbp_glrt_write(rt2x00dev, 210, 0x30);
-+ rt2800_bbp_glrt_write(rt2x00dev, 211, 0x6E);
-+
-+ /* BBP for G band DCOC function */
-+ rt2800_bbp_dcoc_write(rt2x00dev, 140, 0x0C);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 141, 0x00);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 142, 0x10);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 143, 0x10);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 144, 0x10);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 145, 0x10);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 146, 0x08);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 147, 0x40);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 148, 0x04);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 149, 0x04);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 150, 0x08);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 151, 0x08);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 152, 0x03);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 153, 0x03);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 154, 0x03);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 155, 0x02);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 156, 0x40);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 157, 0x40);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 158, 0x64);
-+ rt2800_bbp_dcoc_write(rt2x00dev, 159, 0x64);
-+
-+ rt2800_bbp4_mac_if_ctrl(rt2x00dev);
-+}
-+
- static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
- {
- unsigned int i;
-@@ -6117,7 +6734,10 @@ static void rt2800_init_bbp(struct rt2x0
- return;
- case RT5390:
- case RT5392:
-- rt2800_init_bbp_53xx(rt2x00dev);
-+ if (rt2x00dev->chip.rf == RF7620)
-+ rt2800_init_bbp_7620(rt2x00dev);
-+ else
-+ rt2800_init_bbp_53xx(rt2x00dev);
- break;
- case RT5592:
- rt2800_init_bbp_5592(rt2x00dev);
-@@ -7331,6 +7951,277 @@ static void rt2800_init_rfcsr_5592(struc
- rt2800_led_open_drain_enable(rt2x00dev);
- }
-
-+static void rt2800_init_rfcsr_7620(struct rt2x00_dev *rt2x00dev)
-+{
-+ u8 rfvalue;
-+ u16 freq;
-+
-+ /* Initialize RF central register to default value */
-+ rt2800_rfcsr_write(rt2x00dev, 0, 0x02);
-+ rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
-+ rt2800_rfcsr_write(rt2x00dev, 2, 0x33);
-+ rt2800_rfcsr_write(rt2x00dev, 3, 0xFF);
-+ rt2800_rfcsr_write(rt2x00dev, 4, 0x0C);
-+ rt2800_rfcsr_write(rt2x00dev, 5, 0x40); /* Read only */
-+ rt2800_rfcsr_write(rt2x00dev, 6, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 8, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 9, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 10, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
-+ /* rt2800_rfcsr_write(rt2x00dev, 12, 0x43); *//* EEPROM */
-+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 14, 0x40);
-+ rt2800_rfcsr_write(rt2x00dev, 15, 0x22);
-+ rt2800_rfcsr_write(rt2x00dev, 16, 0x4C);
-+ rt2800_rfcsr_write(rt2x00dev, 17, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 18, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 20, 0xA0);
-+ rt2800_rfcsr_write(rt2x00dev, 21, 0x12);
-+ rt2800_rfcsr_write(rt2x00dev, 22, 0x07);
-+ rt2800_rfcsr_write(rt2x00dev, 23, 0x13);
-+ rt2800_rfcsr_write(rt2x00dev, 24, 0xFE);
-+ rt2800_rfcsr_write(rt2x00dev, 25, 0x24);
-+ rt2800_rfcsr_write(rt2x00dev, 26, 0x7A);
-+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 29, 0x05);
-+ rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 32, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 34, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 35, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 37, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 38, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 39, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 40, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 41, 0xD0);
-+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
-+ rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
-+ if (rt2800_clk_is_20mhz(rt2x00dev))
-+ rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
-+ else
-+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
-+ rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
-+ rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
-+ rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
-+ rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
-+ rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
-+ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
-+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
-+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
-+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
-+ rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
-+ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
-+ rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
-+
-+ rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
-+ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
-+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
-+
-+ /* use rt2800_adjust_freq_offset ? */
-+ rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &freq);
-+ rfvalue = freq & 0xff;
-+ rt2800_rfcsr_write(rt2x00dev, 12, rfvalue);
-+
-+ /* Initialize RF channel register to default value */
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 1, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 2, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 3, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 4, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 5, 0x08);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 6, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 7, 0x51);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x53);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x16);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x61);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 12, 0x22);
-+ /* rt2800_rfcsr_write_chanreg(rt2x00dev, 13, 0x3D); */ /* fails */
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 15, 0x13);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 16, 0x22);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x01);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x52);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 22, 0x80);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 23, 0xB3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 24, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 25, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 26, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 27, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x5C);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0x6B);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 30, 0x6B);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 31, 0x31);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x5D);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 33, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xE6);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 35, 0x55);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 37, 0xBB);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 39, 0xB3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 40, 0x03);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 41, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 42, 0x00);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xB3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xD3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x07);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x68);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xEF);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1C);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x07);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xA8);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0x85);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x10);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x07);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6A);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0x85);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x10);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 62, 0x1C);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 63, 0x00);
-+
-+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5);
-+
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
-+
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
-+
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
-+
-+ /* Initialize RF channel register for DRQFN */
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
-+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
-+
-+ /* Initialize RF DC calibration register to default value */
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 1, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 2, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 6, 0x10);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 7, 0x10);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 8, 0x04);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 9, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 10, 0x07);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 11, 0x01);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 12, 0x07);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 13, 0x07);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 14, 0x07);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 15, 0x20);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 16, 0x22);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 21, 0xF1);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 22, 0x11);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 23, 0x02);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 24, 0x41);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 25, 0x20);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 26, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 27, 0xD7);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 28, 0xA2);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 29, 0x20);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 30, 0x49);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 31, 0x20);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 32, 0x04);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 33, 0xF1);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 34, 0xA1);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 35, 0x01);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 41, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 42, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 43, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 44, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 45, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 46, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 47, 0x3E);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 48, 0x3D);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 49, 0x3E);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 50, 0x3D);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 51, 0x3E);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 52, 0x3D);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 53, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 54, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 55, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 56, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 57, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x10);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x10);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 60, 0x0A);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 61, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00);
-+
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
-+
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
-+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
-+}
-+
- static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
- {
- if (rt2800_is_305x_soc(rt2x00dev)) {
-@@ -7366,7 +8257,10 @@ static void rt2800_init_rfcsr(struct rt2
- rt2800_init_rfcsr_5350(rt2x00dev);
- break;
- case RT5390:
-- rt2800_init_rfcsr_5390(rt2x00dev);
-+ if (rt2x00dev->chip.rf == RF7620)
-+ rt2800_init_rfcsr_7620(rt2x00dev);
-+ else
-+ rt2800_init_rfcsr_5390(rt2x00dev);
- break;
- case RT5392:
- rt2800_init_rfcsr_5392(rt2x00dev);
-@@ -7780,6 +8674,7 @@ static int rt2800_init_eeprom(struct rt2
- case RF5390:
- case RF5392:
- case RF5592:
-+ case RF7620:
- break;
- default:
- rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n",
-@@ -8258,6 +9153,24 @@ static const struct rf_channel rf_vals_5
- {196, 83, 0, 12, 1},
- };
-
-+static const struct rf_channel rf_vals_7620[] = {
-+ /* Channel, Rdiv, N, K | (D >> 8), Ksd */
-+ {1, 3, 0x50, 0 | (0 >> 8), 0x19999},
-+ {2, 3, 0x50, 0 | (0 >> 8), 0x24444},
-+ {3, 3, 0x50, 0 | (0 >> 8), 0x2EEEE},
-+ {4, 3, 0x50, 0 | (0 >> 8), 0x39999},
-+ {5, 3, 0x51, 0 | (0 >> 8), 0x04444},
-+ {6, 3, 0x51, 0 | (0 >> 8), 0x0EEEE},
-+ {7, 3, 0x51, 0 | (0 >> 8), 0x19999},
-+ {8, 3, 0x51, 0 | (0 >> 8), 0x24444},
-+ {9, 3, 0x51, 0 | (0 >> 8), 0x2EEEE},
-+ {10, 3, 0x51, 0 | (0 >> 8), 0x39999},
-+ {11, 3, 0x52, 0 | (0 >> 8), 0x04444},
-+ {12, 3, 0x52, 0 | (0 >> 8), 0x0EEEE},
-+ {13, 3, 0x52, 0 | (0 >> 8), 0x19999},
-+ {14, 3, 0x52, 0 | (0 >> 8), 0x33333},
-+};
-+
- static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
- {
- struct hw_mode_spec *spec = &rt2x00dev->spec;
-@@ -8361,6 +9274,11 @@ static int rt2800_probe_hw_mode(struct r
- spec->channels = rf_vals_3x;
- break;
-
-+ case RF7620:
-+ spec->num_channels = ARRAY_SIZE(rf_vals_7620);
-+ spec->channels = rf_vals_7620;
-+ break;
-+
- case RF3052:
- case RF3053:
- spec->num_channels = ARRAY_SIZE(rf_vals_3x);
-@@ -8498,6 +9416,7 @@ static int rt2800_probe_hw_mode(struct r
- case RF5390:
- case RF5392:
- case RF5592:
-+ case RF7620:
- __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags);
- break;
- }
--- /dev/null
+--- a/drivers/net/wireless/marvell/mwl8k.c
++++ b/drivers/net/wireless/marvell/mwl8k.c
+@@ -5681,6 +5681,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+ MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
+
+ static const struct pci_device_id mwl8k_pci_id_table[] = {
++ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, },
+ { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
+ { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
+ { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
+++ /dev/null
---- a/drivers/net/wireless/marvell/libertas/cfg.c
-+++ b/drivers/net/wireless/marvell/libertas/cfg.c
-@@ -2127,6 +2127,8 @@ struct wireless_dev *lbs_cfg_alloc(struc
- goto err_wiphy_new;
- }
-
-+ set_wiphy_dev(wdev->wiphy, dev);
-+
- lbs_deb_leave(LBS_DEB_CFG80211);
- return wdev;
-
---- a/drivers/net/wireless/marvell/libertas/main.c
-+++ b/drivers/net/wireless/marvell/libertas/main.c
-@@ -986,6 +986,7 @@ struct lbs_private *lbs_add_card(void *c
- goto err_adapter;
- }
-
-+ dev_net_set(dev, wiphy_net(wdev->wiphy));
- dev->ieee80211_ptr = wdev;
- dev->ml_priv = priv;
- SET_NETDEV_DEV(dev, dmdev);
+++ /dev/null
---- a/drivers/net/wireless/marvell/libertas/cfg.c
-+++ b/drivers/net/wireless/marvell/libertas/cfg.c
-@@ -2217,6 +2217,8 @@ int lbs_cfg_register(struct lbs_private
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
- wdev->wiphy->reg_notifier = lbs_reg_notifier;
-
-+ memcpy(wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN);
-+
- ret = wiphy_register(wdev->wiphy);
- if (ret < 0)
- pr_err("cannot register wiphy device\n");
+++ /dev/null
---- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c
-@@ -58,19 +58,12 @@
- (((c) < 149) ? 3 : 4))))
-
- #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
--#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
-- NL80211_RRF_NO_IR)
-+#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, 0)
-
--#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
-- NL80211_RRF_NO_IR)
--#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
-- NL80211_RRF_DFS | \
-- NL80211_RRF_NO_IR)
--#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
-- NL80211_RRF_DFS | \
-- NL80211_RRF_NO_IR)
--#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
-- NL80211_RRF_NO_IR)
-+#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, 0)
-+#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, 0)
-+#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, 0)
-+#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, 0)
-
- static const struct ieee80211_regdomain brcms_regdom_x2 = {
- .n_reg_rules = 6,
+++ /dev/null
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Mon, 8 Jun 2015 16:11:40 +0200
-Subject: [PATCH] brcmfmac: register wiphy(s) during module_init
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is needed by OpenWrt which expects all PHYs to be created after
-module loads successfully.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -1196,6 +1196,7 @@ int __init brcmf_core_init(void)
- {
- if (!schedule_work(&brcmf_driver_work))
- return -EBUSY;
-+ flush_work(&brcmf_driver_work);
-
- return 0;
- }
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
-@@ -444,6 +444,7 @@ struct brcmf_fw {
- u16 bus_nr;
- void (*done)(struct device *dev, const struct firmware *fw,
- void *nvram_image, u32 nvram_len);
-+ struct completion *completion;
- };
-
- static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
-@@ -478,6 +479,8 @@ static void brcmf_fw_request_nvram_done(
- goto fail;
-
- fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
-+ if (fwctx->completion)
-+ complete(fwctx->completion);
- kfree(fwctx);
- return;
-
-@@ -485,6 +488,8 @@ fail:
- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
- release_firmware(fwctx->code);
- device_release_driver(fwctx->dev);
-+ if (fwctx->completion)
-+ complete(fwctx->completion);
- kfree(fwctx);
- }
-
-@@ -500,6 +505,8 @@ static void brcmf_fw_request_code_done(c
- /* only requested code so done here */
- if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
- fwctx->done(fwctx->dev, fw, NULL, 0);
-+ if (fwctx->completion)
-+ complete(fwctx->completion);
- kfree(fwctx);
- return;
- }
-@@ -517,6 +524,8 @@ static void brcmf_fw_request_code_done(c
- fail:
- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
- device_release_driver(fwctx->dev);
-+ if (fwctx->completion)
-+ complete(fwctx->completion);
- kfree(fwctx);
- }
-
-@@ -528,6 +537,8 @@ int brcmf_fw_get_firmwares_pcie(struct d
- u16 domain_nr, u16 bus_nr)
- {
- struct brcmf_fw *fwctx;
-+ struct completion completion;
-+ int err;
-
- brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
- if (!fw_cb || !code)
-@@ -548,9 +559,17 @@ int brcmf_fw_get_firmwares_pcie(struct d
- fwctx->domain_nr = domain_nr;
- fwctx->bus_nr = bus_nr;
-
-- return request_firmware_nowait(THIS_MODULE, true, code, dev,
-+ init_completion(&completion);
-+ fwctx->completion = &completion;
-+
-+ err = request_firmware_nowait(THIS_MODULE, true, code, dev,
- GFP_KERNEL, fwctx,
- brcmf_fw_request_code_done);
-+ if (!err)
-+ wait_for_completion_timeout(fwctx->completion,
-+ msecs_to_jiffies(5000));
-+ fwctx->completion = NULL;
-+ return err;
- }
-
- int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
+++ /dev/null
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 9 Jul 2015 00:07:59 +0200
-Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -656,9 +656,37 @@ static struct wireless_dev *brcmf_cfg802
- u32 *flags,
- struct vif_params *params)
- {
-+ struct net_device *dev;
- struct wireless_dev *wdev;
- int err;
-
-+ /*
-+ * There is a bug with in-firmware BSS management. When adding virtual
-+ * interface brcmfmac first tells firmware to create new BSS and then
-+ * it creates new struct net_device.
-+ *
-+ * If creating/registering netdev(ice) fails, BSS remains in some bugged
-+ * state. It conflicts with existing BSSes by overtaking their auth
-+ * requests.
-+ *
-+ * It results in one BSS (addresss X) sending beacons and another BSS
-+ * (address Y) replying to authentication requests. This makes interface
-+ * unusable as AP.
-+ *
-+ * To workaround this bug we may try to guess if register_netdev(ice)
-+ * will fail. The most obvious case is using interface name that already
-+ * exists. This is actually quite likely with brcmfmac & some user space
-+ * scripts as brcmfmac doesn't allow deleting virtual interfaces.
-+ * So this bug can be triggered even by something trivial like:
-+ * iw dev wlan0 delete
-+ * iw phy phy0 interface add wlan0 type __ap
-+ */
-+ dev = dev_get_by_name(&init_net, name);
-+ if (dev) {
-+ dev_put(dev);
-+ return ERR_PTR(-ENFILE);
-+ }
-+
- brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
- err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
- if (err) {
+++ /dev/null
-From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 9 Mar 2016 17:25:59 +0000
-Subject: [PATCH] brcmfmac: Disable power management
-
-Disable wireless power saving in the brcmfmac WLAN driver. This is a
-temporary measure until the connectivity loss resulting from power
-saving is resolved.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -2775,6 +2775,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
- * preference in cfg struct to apply this to
- * FW later while initializing the dongle
- */
-+#if defined(CONFIG_ARCH_BCM2835)
-+ brcmf_dbg(INFO, "power management disabled\n");
-+ enabled = false;
-+#endif
- cfg->pwr_save = enabled;
- if (!check_vif_up(ifp->vif)) {
-
+++ /dev/null
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] brcmfmac: add in-driver tables with country codes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This adds early support for changing region. Ideally this data should
-be stored in DT as all these mappings are devices specific.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
-@@ -23,6 +23,36 @@
- #include "common.h"
- #include "of.h"
-
-+/* TODO: FIXME: Use DT */
-+static void brcmf_of_probe_cc(struct device *dev,
-+ struct brcmf_mp_device *settings)
-+{
-+ static struct brcmfmac_pd_cc_entry netgear_r8000_cc_ent[] = {
-+ { "JP", "JP", 78 },
-+ { "US", "Q2", 86 },
-+ };
-+ struct brcmfmac_pd_cc_entry *cc_ent = NULL;
-+ int table_size = 0;
-+
-+ if (of_machine_is_compatible("netgear,r8000")) {
-+ cc_ent = netgear_r8000_cc_ent;
-+ table_size = ARRAY_SIZE(netgear_r8000_cc_ent);
-+ }
-+
-+ if (cc_ent && table_size) {
-+ struct brcmfmac_pd_cc *cc;
-+ size_t memsize;
-+
-+ memsize = table_size * sizeof(struct brcmfmac_pd_cc_entry);
-+ cc = devm_kzalloc(dev, sizeof(*cc) + memsize, GFP_KERNEL);
-+ if (!cc)
-+ return;
-+ cc->table_size = table_size;
-+ memcpy(cc->table, cc_ent, memsize);
-+ settings->country_codes = cc;
-+ }
-+}
-+
- void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
- struct brcmf_mp_device *settings)
- {
-@@ -32,6 +62,8 @@ void brcmf_of_probe(struct device *dev,
- u32 irqf;
- u32 val;
-
-+ brcmf_of_probe_cc(dev, settings);
-+
- if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
- !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
- return;
+++ /dev/null
-brcmfmac: do not use internal roaming engine by default
-
-Some evidence of curing disconnects with this disabled, so make it a default.
-Can be overridden with module parameter roamoff=0
-See: http://projectable.me/optimize-my-pi-wi-fi/
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
-@@ -69,7 +69,11 @@ static int brcmf_fcmode;
- module_param_named(fcmode, brcmf_fcmode, int, 0);
- MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
-
-+#if defined(CONFIG_ARCH_BCM2835)
-+static int brcmf_roamoff = 1;
-+#else
- static int brcmf_roamoff;
-+#endif
- module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
- MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
-
--- /dev/null
+--- a/drivers/net/wireless/marvell/mwl8k.c
++++ b/drivers/net/wireless/marvell/mwl8k.c
+@@ -6264,6 +6264,8 @@ static int mwl8k_probe(struct pci_dev *p
+
+ priv->running_bsses = 0;
+
++ wait_for_completion(&priv->firmware_loading_complete);
++
+ return rc;
+
+ err_stop_firmware:
+@@ -6297,8 +6299,6 @@ static void mwl8k_remove(struct pci_dev
+ return;
+ priv = hw->priv;
+
+- wait_for_completion(&priv->firmware_loading_complete);
+-
+ if (priv->fw_state == FW_STATE_ERROR) {
+ mwl8k_hw_reset(priv);
+ goto unmap;
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://www.netfilter.org/projects/libmnl/files \
-
+ ftp://ftp.netfilter.org/pub/libmnl
PKG_HASH:=171f89699f286a5854b72b91d06e8f8e3683064c5901fb09d954a9ab6f551f81
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://www.netfilter.org/projects/libnetfilter_conntrack/files/ \
-
-
+ ftp://ftp.netfilter.org/pub/libnetfilter_conntrack/
PKG_HASH:=efcc08021284e75f4d96d3581c5155a11f08fd63316b1938cbcb269c87f37feb
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://www.netfilter.org/projects/libnetfilter_cthelper/files/ \
-
-
+ ftp://ftp.netfilter.org/pub/libnetfilter_cthelper/
PKG_HASH:=07618e71c4d9a6b6b3dc1986540486ee310a9838ba754926c7d14a17d8fccf3d
PKG_FIXUP:=autoreconf
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://www.netfilter.org/projects/libnetfilter_cttimeout/files/ \
-
+ ftp://ftp.netfilter.org/pub/libnetfilter_cttimeout/
PKG_HASH:=aeab12754f557cba3ce2950a2029963d817490df7edb49880008b34d7ff8feba
PKG_FIXUP:=autoreconf
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://www.netfilter.org/projects/libnetfilter_log/files/ \
-
-
+ ftp://ftp.netfilter.org/pub/libnetfilter_log/
PKG_HASH:=74e0fe75753dba3ac114531b5e73240452c789a3f3adccf5c51217da1d933b21
PKG_MAINTAINER:=Yousong Zhou <yszhou4tech@gmail.com>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://www.netfilter.org/projects/libnfnetlink/files/ \
+ ftp://ftp.netfilter.org/pub/libnfnetlink/ \
http://mirrors.evolva.ro/netfilter.org/libnfnetlink/
-
PKG_HASH:=f270e19de9127642d2a11589ef2ec97ef90a649a74f56cf9a96306b04817b51a
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_LICENSE:=GPL-2.0+
PKG_BUILD_DEPENDS:=lua
include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/libubox
$(CP) $(PKG_BUILD_DIR)/lua/uloop.so $(1)/usr/lib/lua/
endef
+
+CMAKE_HOST_OPTIONS += \
+ -DBUILD_LUA=OFF \
+ -DBUILD_EXAMPLES=OFF \
+
$(eval $(call BuildPackage,libubox))
$(eval $(call BuildPackage,libblobmsg-json))
$(eval $(call BuildPackage,jshn))
$(eval $(call BuildPackage,libjson-script))
$(eval $(call BuildPackage,libubox-lua))
+$(eval $(call HostBuild))
include $(TOPDIR)/rules.mk
PKG_NAME:=mbedtls
-PKG_VERSION:=2.4.2
-PKG_RELEASE:=1
+PKG_VERSION:=2.5.1
+PKG_RELEASE:=2
PKG_USE_MIPS16:=0
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-gpl.tgz
PKG_SOURCE_URL:=https://tls.mbed.org/download/
-PKG_HASH:=d01f2d5586a52055329d194d909103f445bd2d0b6b2b5f1c830fbf828ac6299f
+PKG_HASH:=312f020006f0d8e9ede3ed8e73d907a629baf6475229703941769372ab0adee2
PKG_BUILD_PARALLEL:=1
PKG_LICENSE:=GPL-2.0+
/* \} name SECTION: System support */
-@@ -441,17 +441,17 @@
+@@ -504,17 +504,17 @@
*
* Comment macros to disable the curve and functions for it
*/
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
/**
-@@ -476,8 +476,8 @@
+@@ -539,8 +539,8 @@
* Requires: MBEDTLS_HMAC_DRBG_C
*
* Comment this macro to disable deterministic ECDSA.
/**
* \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
-@@ -523,7 +523,7 @@
+@@ -586,7 +586,7 @@
* MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
* MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
*/
/**
* \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
-@@ -542,8 +542,8 @@
+@@ -605,8 +605,8 @@
* MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
* MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
* MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
/**
* \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
-@@ -568,7 +568,7 @@
+@@ -631,7 +631,7 @@
* MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
* MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
*/
/**
* \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
-@@ -695,7 +695,7 @@
+@@ -758,7 +758,7 @@
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
*/
/**
* \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
-@@ -719,7 +719,7 @@
+@@ -782,7 +782,7 @@
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
*/
/**
* \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
-@@ -823,7 +823,7 @@
+@@ -886,7 +886,7 @@
* This option is only useful if both MBEDTLS_SHA256_C and
* MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used.
*/
/**
* \def MBEDTLS_ENTROPY_NV_SEED
-@@ -917,14 +917,14 @@
+@@ -980,14 +980,14 @@
* Uncomment this macro to disable the use of CRT in RSA.
*
*/
/**
* \def MBEDTLS_SHA256_SMALLER
-@@ -940,7 +940,7 @@
+@@ -1003,7 +1003,7 @@
*
* Uncomment to enable the smaller implementation of SHA256.
*/
/**
* \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
-@@ -1059,8 +1059,8 @@
+@@ -1122,8 +1122,8 @@
* misuse/misunderstand.
*
* Comment this to disable support for renegotiation.
/**
* \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
-@@ -1234,8 +1234,8 @@
+@@ -1297,8 +1297,8 @@
* callbacks are provided by MBEDTLS_SSL_TICKET_C.
*
* Comment this macro to disable support for SSL session tickets
/**
* \def MBEDTLS_SSL_EXPORT_KEYS
-@@ -1265,7 +1265,7 @@
+@@ -1328,7 +1328,7 @@
*
* Comment this macro to disable support for truncated HMAC in SSL
*/
/**
* \def MBEDTLS_THREADING_ALT
-@@ -1299,8 +1299,8 @@
+@@ -1362,8 +1362,8 @@
* Requires: MBEDTLS_VERSION_C
*
* Comment this to disable run-time checking and save ROM space
/**
* \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
-@@ -1621,7 +1621,7 @@
+@@ -1684,7 +1684,7 @@
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
*/
/**
* \def MBEDTLS_CCM_C
-@@ -1635,7 +1635,7 @@
+@@ -1698,7 +1698,7 @@
* This module enables the AES-CCM ciphersuites, if other requisites are
* enabled as well.
*/
/**
* \def MBEDTLS_CERTS_C
-@@ -1647,7 +1647,7 @@
+@@ -1710,7 +1710,7 @@
*
* This module is used for testing (ssl_client/server).
*/
/**
* \def MBEDTLS_CIPHER_C
-@@ -1700,7 +1700,7 @@
+@@ -1763,7 +1763,7 @@
*
* This module provides debugging functions.
*/
/**
* \def MBEDTLS_DES_C
-@@ -1725,8 +1725,8 @@
+@@ -1788,8 +1788,8 @@
* MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
*
* PEM_PARSE uses DES/3DES for decrypting encrypted keys.
/**
* \def MBEDTLS_DHM_C
-@@ -1880,8 +1880,8 @@
+@@ -1943,8 +1943,8 @@
* Requires: MBEDTLS_MD_C
*
* Uncomment to enable the HMAC_DRBG random number geerator.
/**
* \def MBEDTLS_MD_C
-@@ -2158,7 +2158,7 @@
+@@ -2221,7 +2221,7 @@
* Caller: library/md.c
*
*/
/**
* \def MBEDTLS_RSA_C
-@@ -2235,8 +2235,8 @@
+@@ -2299,8 +2299,8 @@
* Caller:
*
* Requires: MBEDTLS_SSL_CACHE_C
/**
* \def MBEDTLS_SSL_COOKIE_C
-@@ -2257,8 +2257,8 @@
+@@ -2321,8 +2321,8 @@
* Caller:
*
* Requires: MBEDTLS_CIPHER_C
/**
* \def MBEDTLS_SSL_CLI_C
-@@ -2357,8 +2357,8 @@
+@@ -2421,8 +2421,8 @@
* Module: library/version.c
*
* This module provides run-time version information.
/**
* \def MBEDTLS_X509_USE_C
-@@ -2468,7 +2468,7 @@
+@@ -2532,7 +2532,7 @@
* Module: library/xtea.c
* Caller:
*/
/* \} name SECTION: mbed TLS modules */
+@@ -2646,7 +2646,7 @@
+ * recommended because of it is possible to generte SHA-1 collisions, however
+ * this may be safe for legacy infrastructure where additional controls apply.
+ */
+-// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
++#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+
+ /**
+ * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
PKG_NAME:=openssl
PKG_BASE:=1.0.2
-PKG_BUGFIX:=l
+PKG_BUGFIX:=k
PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX)
PKG_RELEASE:=1
PKG_USE_MIPS16:=0
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://www.openssl.org/source/ \
+PKG_SOURCE_URL:=http://www.openssl.org/source/ \
+ ftp://ftp.openssl.org/source/ \
http://www.openssl.org/source/old/$(PKG_BASE)/ \
-
-PKG_HASH:=ce07195b659e75f4e1db43552860070061f156a98bb37b672b101ba6e3ddf30c
+ ftp://ftp.funet.fi/pub/crypt/mirrors/ftp.openssl.org/source \
+ ftp://ftp.sunet.se/pub/security/tools/net/openssl/source/
+PKG_HASH:=6b3977c61f2aedf0f96367dcfb5c6e578cf37e7b8d913b4ecb6643c3cb88d8c0
PKG_LICENSE:=OpenSSL
PKG_LICENSE_FILES:=LICENSE
endif
endif
-STAMP_CONFIGURED := $(STAMP_CONFIGURED)_$(subst $(space),_,$(OPENSSL_OPTIONS))
+STAMP_CONFIGURED := $(STAMP_CONFIGURED)_$(shell echo $(OPENSSL_OPTIONS) | mkhash md5)
define Build/Configure
[ -f $(STAMP_CONFIGURED) ] || { \
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(LEDE_GIT)/project/uclient.git
-PKG_SOURCE_DATE:=2016-12-09
-PKG_SOURCE_VERSION:=52d955fd802a4d990b7ff9116f02ff52aa63ffec
-PKG_MIRROR_HASH:=b96f53ccaa62a229e818be836bb4fc85aa4a1ce257fd41fbdbf4e31a959c641f
+PKG_SOURCE_DATE:=2017-09-06
+PKG_SOURCE_VERSION:=24d6eded73dec427fc4a3a20cc73c94227f59c31
+PKG_MIRROR_HASH:=e884ae0c859baa20a5c7f3d924022f8e1f57d28474dbe5fed1efb8fb97790dd0
CMAKE_INSTALL:=1
PKG_BUILD_DEPENDS:=ustream-ssl
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(LEDE_GIT)/project/firewall3.git
-PKG_SOURCE_DATE:=2017-01-13
-PKG_SOURCE_VERSION:=37cb4cb437fd685f31926a4c326ba8afe329e4a6
-PKG_MIRROR_HASH:=7ee075f05977e5d9a78e661b537e6eb077c8f328ff2e71d1e2fbef44cca97355
+PKG_SOURCE_DATE:=2017-05-27
+PKG_SOURCE_VERSION:=a4d98aea373e04f3fdc3c492c1688ba52ce490a9
+PKG_MIRROR_HASH:=55402b1e6bb471f6aed599c61c1c63b58212f5789f094d78247646fc0a7cf435
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_LICENSE:=ISC
option family ipv6
option target ACCEPT
+config rule
+ option name Allow-IPSec-ESP
+ option src wan
+ option dest lan
+ option proto esp
+ option target ACCEPT
+
+config rule
+ option name Allow-ISAKMP
+ option src wan
+ option dest lan
+ option dest_port 500
+ option proto udp
+ option target ACCEPT
+
# include a file with users custom iptables rules
config include
option path /etc/firewall.user
# option dest_port 22
# option proto tcp
-# allow IPsec/ESP and ISAKMP passthrough
-config rule
- option src wan
- option dest lan
- option proto esp
- option target ACCEPT
-
-config rule
- option src wan
- option dest lan
- option dest_port 500
- option proto udp
- option target ACCEPT
-
### FULL CONFIG SECTIONS
#config rule
# option src lan
include $(TOPDIR)/rules.mk
PKG_NAME:=odhcp6c
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=$(LEDE_GIT)/project/odhcp6c.git
esac
# user rules
-[ -f /etc/odhcp6c.user ] && . /etc/odhcp6c.user "@"
+[ -f /etc/odhcp6c.user ] && . /etc/odhcp6c.user "$@"
exit 0
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
-PKG_VERSION:=2.76
+PKG_VERSION:=2.77
PKG_RELEASE:=6
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
-PKG_HASH:=4b92698dee19ca0cb2a8f2e48f1d2dffd01a21eb15d1fbed4cf085630c8c9f96
+PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/
+PKG_HASH:=6eac3b1c50ae25170e3ff8c96ddb55236cf45007633fdb8a35b1f3e02f5f8b8a
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
dhcp_option_add "$cfg" "$networkid"
}
+dhcp_option_append() {
+ local option="$1"
+ local networkid="$2"
+ local force="$3"
+
+ xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$option"
+}
+
dhcp_option_add() {
local cfg="$1"
local networkid="$2"
[ "$force" = "0" ] && force=
- config_get dhcp_option "$cfg" dhcp_option
- for o in $dhcp_option; do
- xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$o"
- done
+ local list_len
+ config_get list_len "$cfg" dhcp_option_LENGTH
+ if [ -n "$list_len" ]; then
+ config_list_foreach "$cfg" dhcp_option dhcp_option_append "$networkid" "$force"
+ else
+ config_get dhcp_option "$cfg" dhcp_option
+
+ [ -n "$dhcp_option" ] && echo "Warning: the 'option dhcp_option' syntax is deprecated, use 'list dhcp_option'" >&2
+
+ local option
+ for option in $dhcp_option; do
+ dhcp_option_append "$option" "$networkid" "$force"
+ done
+ fi
}
dhcp_domain_add() {
if [ -z "$interface" ]; then
xappend "--dhcp-relay=$local_addr,$server_addr"
else
- xappend "--dhcp-relay=$local_addr,$server_addr,$interface"
+ network_get_device ifname "$interface" || return
+ xappend "--dhcp-relay=$local_addr,$server_addr,$ifname"
fi
}
append_bool "$cfg" boguspriv "--bogus-priv"
append_bool "$cfg" expandhosts "--expand-hosts"
config_get tftp_root "$cfg" "tftp_root"
- [ -d "$tftp_root" ] && append_bool "$cfg" enable_tftp "--enable-tftp"
+ [ -n "$tftp_root" ] && mkdir -p "$tftp_root" && append_bool "$cfg" enable_tftp "--enable-tftp"
append_bool "$cfg" tftp_no_fail "--tftp-no-fail"
append_bool "$cfg" nonwildcard "--bind-dynamic"
append_bool "$cfg" fqdn "--dhcp-fqdn"
--- /dev/null
+From 4bb68866a8aeb31db8100492bceae051e33be5d0 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 15 Jun 2017 23:18:44 +0100
+Subject: [PATCH] Tweak ICMP ping check logic for DHCPv4.
+
+---
+ src/rfc2131.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/rfc2131.c b/src/rfc2131.c
+index 1c850e5..75792da 100644
+--- a/src/rfc2131.c
++++ b/src/rfc2131.c
+@@ -1040,7 +1040,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
+ else if (have_config(config, CONFIG_DECLINED) &&
+ difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
+ my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
+- else if (!do_icmp_ping(now, config->addr, 0, loopback))
++ else if ((!lease || lease->addr.s_addr != config->addr.s_addr) && !do_icmp_ping(now, config->addr, 0, loopback))
+ my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by another host"), addrs);
+ else
+ conf = config->addr;
+--
+1.9.1
+
--- /dev/null
+From 1d224949cced9e82440d00b3dbaf32c262bac2ff Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Sat, 8 Jul 2017 20:52:55 +0100
+Subject: [PATCH 1/2] Remove ping-check of configured DHCP address.
+
+This was added in 5ce3e76fbf89e942e8c54ef3e3389facf0d9067a but
+it trips over too many buggy clients that leave an interface configured
+even in DHCPDISCOVER case.
+---
+ src/rfc2131.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/src/rfc2131.c b/src/rfc2131.c
+index 86230b4..785e15c 100644
+--- a/src/rfc2131.c
++++ b/src/rfc2131.c
+@@ -1040,8 +1040,6 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
+ else if (have_config(config, CONFIG_DECLINED) &&
+ difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
+ my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
+- else if ((!lease || lease->addr.s_addr != config->addr.s_addr) && !do_icmp_ping(now, config->addr, 0, loopback))
+- my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by another host"), addrs);
+ else
+ conf = config->addr;
+ }
+--
+2.13.2
+
--- /dev/null
+From 9396752c115b3ab733fa476b30da73237e12e7ba Mon Sep 17 00:00:00 2001
+From: Hans Dedecker <dedeckeh@gmail.com>
+Date: Tue, 27 Jun 2017 22:08:47 +0100
+Subject: [PATCH] Try other servers if first returns REFUSED when
+ --strict-order active.
+
+If a DNS server replies REFUSED for a given DNS query in strict order mode
+no failover to the next DNS server is triggered as the failover logic only
+covers non strict mode.
+As a result the client will be returned the REFUSED reply without first
+falling back to the secondary DNS server(s).
+
+Make failover support work as well for strict mode config in case REFUSED is
+replied by deleting the strict order check and rely only on forwardall being
+equal to 0 which is the case in non strict mode when a single server has been
+contacted or when strict order mode has been configured.
+---
+ CHANGELOG | 4 ++++
+ src/forward.c | 1 -
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -790,7 +790,6 @@ void reply_query(int fd, int family, tim
+ /* Note: if we send extra options in the EDNS0 header, we can't recreate
+ the query from the reply. */
+ if (RCODE(header) == REFUSED &&
+- !option_bool(OPT_ORDER) &&
+ forward->forwardall == 0 &&
+ !(forward->flags & FREC_HAS_EXTRADATA))
+ /* for broken servers, attempt to send to another one. */
--- /dev/null
+From 63437ffbb58837b214b4b92cb1c54bc5f3279928 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Wed, 6 Sep 2017 22:34:21 +0100
+Subject: [PATCH] Fix CVE-2017-13704, which resulted in a crash on a large DNS
+ query.
+
+A DNS query recieved by UDP which exceeds 512 bytes (or the EDNS0 packet size,
+if different.) is enough to cause SIGSEGV.
+---
+ CHANGELOG | 7 +++++++
+ src/auth.c | 5 -----
+ src/forward.c | 8 ++++++++
+ src/rfc1035.c | 5 -----
+ 4 files changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index 3a640f3..7e65912 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -17,6 +17,13 @@ version 2.78
+ --strict-order active. Thanks to Hans Dedecker
+ for the patch
+
++ Fix regression in 2.77, ironically added as a security
++ improvement, which resulted in a crash when a DNS
++ query exceeded 512 bytes (or the EDNS0 packet size,
++ if different.) Thanks to Christian Kujau, Arne Woerner
++ Juan Manuel Fernandez and Kevin Darbyshire-Bryant for
++ chasing this one down. CVE-2017-13704 applies.
++
+
+ version 2.77
+ Generate an error when configured with a CNAME loop,
+diff --git a/src/auth.c b/src/auth.c
+index 2c24e16..7f95f98 100644
+--- a/src/auth.c
++++ b/src/auth.c
+@@ -119,11 +119,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
+ struct cname *a, *candidate;
+ unsigned int wclen;
+
+- /* Clear buffer beyond request to avoid risk of
+- information disclosure. */
+- memset(((char *)header) + qlen, 0,
+- (limit - ((char *)header)) - qlen);
+-
+ if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
+ return 0;
+
+diff --git a/src/forward.c b/src/forward.c
+index f22556a..e3fa94b 100644
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -1188,6 +1188,10 @@ void receive_query(struct listener *listen, time_t now)
+ (msg.msg_flags & MSG_TRUNC) ||
+ (header->hb3 & HB3_QR))
+ return;
++
++ /* Clear buffer beyond request to avoid risk of
++ information disclosure. */
++ memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
+
+ source_addr.sa.sa_family = listen->family;
+
+@@ -1688,6 +1692,10 @@ unsigned char *tcp_request(int confd, time_t now,
+
+ if (size < (int)sizeof(struct dns_header))
+ continue;
++
++ /* Clear buffer beyond request to avoid risk of
++ information disclosure. */
++ memset(payload + size, 0, 65536 - size);
+
+ query_count++;
+
+diff --git a/src/rfc1035.c b/src/rfc1035.c
+index 26f5301..af2fe46 100644
+--- a/src/rfc1035.c
++++ b/src/rfc1035.c
+@@ -1223,11 +1223,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
+ struct mx_srv_record *rec;
+ size_t len;
+
+- /* Clear buffer beyond request to avoid risk of
+- information disclosure. */
+- memset(((char *)header) + qlen, 0,
+- (limit - ((char *)header)) - qlen);
+-
+ if (ntohs(header->ancount) != 0 ||
+ ntohs(header->nscount) != 0 ||
+ ntohs(header->qdcount) == 0 ||
+--
+1.7.10.4
+
--- /dev/null
+From a3303e196e5d304ec955c4d63afb923ade66c6e8 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 7 Sep 2017 20:45:00 +0100
+Subject: [PATCH] Don't return arcount=1 if EDNS0 RR won't fit in the packet.
+
+Omitting the EDNS0 RR but setting arcount gives a malformed packet.
+Also, don't accept UDP packet size less than 512 in recieved EDNS0.
+---
+ src/edns0.c | 5 ++++-
+ src/forward.c | 2 ++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/edns0.c b/src/edns0.c
+index 3fde17f..f5b798c 100644
+--- a/src/edns0.c
++++ b/src/edns0.c
+@@ -208,7 +208,10 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
+ free(buff);
+ p += rdlen;
+ }
+- header->arcount = htons(ntohs(header->arcount) + 1);
++
++ /* Only bump arcount if RR is going to fit */
++ if (((ssize_t)optlen) <= (limit - (p + 4)))
++ header->arcount = htons(ntohs(header->arcount) + 1);
+ }
+
+ if (((ssize_t)optlen) > (limit - (p + 4)))
+diff --git a/src/forward.c b/src/forward.c
+index e3fa94b..942b02d 100644
+--- a/src/forward.c
++++ b/src/forward.c
+@@ -1412,6 +1412,8 @@ void receive_query(struct listener *listen, time_t now)
+ defaults to 512 */
+ if (udp_size > daemon->edns_pktsz)
+ udp_size = daemon->edns_pktsz;
++ else if (udp_size < PACKETSZ)
++ udp_size = PACKETSZ; /* Sanity check - can't reduce below default. RFC 6891 6.2.3 */
+ }
+
+ #ifdef HAVE_AUTH
+--
+1.7.10.4
+
(buffer = safe_malloc(BUFF_SZ)) &&
(ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 &&
(bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1))
-@@ -168,62 +149,16 @@ static int new_add_to_ipset(const char *
- }
-
-
--static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove)
--{
-- socklen_t size;
-- struct ip_set_req_adt_get {
-- unsigned op;
-- unsigned version;
-- union {
-- char name[IPSET_MAXNAMELEN];
-- uint16_t index;
-- } set;
-- char typename[IPSET_MAXNAMELEN];
-- } req_adt_get;
-- struct ip_set_req_adt {
-- unsigned op;
-- uint16_t index;
-- uint32_t ip;
-- } req_adt;
--
-- if (strlen(setname) >= sizeof(req_adt_get.set.name))
-- {
-- errno = ENAMETOOLONG;
-- return -1;
-- }
--
-- req_adt_get.op = 0x10;
-- req_adt_get.version = 3;
-- strcpy(req_adt_get.set.name, setname);
-- size = sizeof(req_adt_get);
-- if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0)
-- return -1;
-- req_adt.op = remove ? 0x102 : 0x101;
-- req_adt.index = req_adt_get.set.index;
-- req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr);
-- if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
-- return -1;
--
-- return 0;
--}
--
--
--
- int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)
- {
- int af = AF_INET;
-
- #ifdef HAVE_IPV6
+@@ -217,17 +198,10 @@ int add_to_ipset(const char *setname, co
if (flags & F_IPV6)
-- {
+ {
af = AF_INET6;
- /* old method only supports IPv4 */
- if (old_kernel)
-- return -1;
-- }
+- {
+- errno = EAFNOSUPPORT ;
+- ret = -1;
+- }
+ }
#endif
-- return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
-+ return new_add_to_ipset(setname, ipaddr, af, remove);
- }
+- if (ret != -1)
+- ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
++ ret = new_add_to_ipset(setname, ipaddr, af, remove);
- #endif
+ if (ret == -1)
+ my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno));
+ if (difftime(now, base) >= 0 && difftime(timestamp_time, now) <= 0)
{
/* time already OK, update timestamp, and do key checking from the start. */
- if (utime(daemon->timestamp_file, NULL) == -1)
+ if (utimes(daemon->timestamp_file, NULL) == -1)
@@ -493,7 +500,7 @@ int setup_timestamp(void)
close(fd);
-- timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
-+ timestamp_time = timbuf.actime = timbuf.modtime = base;
- if (utime(daemon->timestamp_file, &timbuf) == 0)
- goto check_and_exit;
- }
+- timestamp_time = 1420070400; /* 1-1-2015 */
++ timestamp_time = base; /* 1-1-2015 */
+ tv[0].tv_sec = tv[1].tv_sec = timestamp_time;
+ tv[0].tv_usec = tv[1].tv_usec = 0;
+ if (utimes(daemon->timestamp_file, tv) == 0)
include $(TOPDIR)/rules.mk
PKG_NAME:=dropbear
-PKG_VERSION:=2016.74
+PKG_VERSION:=2017.75
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://matt.ucc.asn.au/dropbear/releases/ \
https://dropbear.nl/mirror/releases/
-PKG_HASH:=2720ea54ed009af812701bcc290a2a601d5c107d12993e5d92c0f5f81f718891
+PKG_HASH:=6cbc1dcb1c9709d226dff669e5604172a18cf5dbf9a201474d5618ae4465098c
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE
config_load "${NAME}"
config_foreach load_interfaces dropbear
- [ -n "${interfaces}" ] & {
+ [ -n "${interfaces}" ] && {
for n in $interfaces ; do
procd_add_interface_trigger "interface.*" $n /etc/init.d/dropbear reload
done
--- a/svr-authpubkey.c
+++ b/svr-authpubkey.c
-@@ -218,17 +218,21 @@ static int checkpubkey(char* algo, unsig
+@@ -220,14 +220,20 @@ static int checkpubkey(char* algo, unsig
goto out;
}
- filename = m_malloc(len + 22);
- snprintf(filename, len + 22, "%s/.ssh/authorized_keys",
- ses.authstate.pw_dir);
--
-- /* open the file */
-- authfile = fopen(filename, "r");
+ if (ses.authstate.pw_uid != 0) {
+ /* we don't need to check pw and pw_dir for validity, since
+ * its been done in checkpubkeyperms. */
+ /* allocate max required pathname storage,
+ * = path + "/.ssh/authorized_keys" + '\0' = pathlen + 22 */
+ filename = m_malloc(len + 22);
-+ snprintf(filename, len + 22, "%s/.ssh/authorized_keys",
-+ ses.authstate.pw_dir);
-+
-+ /* open the file */
-+ authfile = fopen(filename, "r");
++ snprintf(filename, len + 22, "%s/.ssh/authorized_keys",
++ ses.authstate.pw_dir);
+ } else {
-+ authfile = fopen("/etc/dropbear/authorized_keys","r");
++ filename = m_malloc(30);
++ strncpy(filename, "/etc/dropbear/authorized_keys", 30);
+ }
- if (authfile == NULL) {
- goto out;
- }
-@@ -381,26 +385,35 @@ static int checkpubkeyperms() {
++
+
+ /* open the file as the authenticating user. */
+ origuid = getuid();
+@@ -396,26 +402,35 @@ static int checkpubkeyperms() {
goto out;
}
include $(TOPDIR)/rules.mk
PKG_NAME:=hostapd
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE_URL:=http://w1.fi/hostap.git
PKG_SOURCE_PROTO:=git
config_add_string country
config_add_boolean country_ie doth
config_add_string require_mode
+ config_add_boolean legacy_rates
hostapd_add_log_config
}
local base="${config%%.conf}"
local base_cfg=
- json_get_vars country country_ie beacon_int doth require_mode
+ json_get_vars country country_ie beacon_int:100 doth require_mode legacy_rates
hostapd_set_log_options base_cfg
set_default country_ie 1
set_default doth 1
+ set_default legacy_rates 1
+
+ [ "$hwmode" = "b" ] && legacy_rates=1
[ -n "$country" ] && {
append base_cfg "country_code=$country" "$N"
[ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N"
[ "$hwmode" = "a" -a "$doth" -gt 0 ] && append base_cfg "ieee80211h=1" "$N"
}
- [ -n "$hwmode" ] && append base_cfg "hw_mode=$hwmode" "$N"
local brlist= br
json_get_values basic_rate_list basic_rate
- for br in $basic_rate_list; do
- hostapd_add_rate brlist "$br"
- done
+ local rlist= r
+ json_get_values rate_list supported_rates
+
+ [ -n "$hwmode" ] && append base_cfg "hw_mode=$hwmode" "$N"
+ [ "$legacy_rates" -eq 0 ] && set_default require_mode g
+
+ [ "$hwmode" = "g" ] && {
+ [ "$legacy_rates" -eq 0 ] && set_default rate_list "6000 9000 12000 18000 24000 36000 48000 54000"
+ [ -n "$require_mode" ] && set_default basic_rate_list "6000 12000 24000"
+ }
+
case "$require_mode" in
- g) brlist="60 120 240" ;;
n) append base_cfg "require_ht=1" "$N";;
ac) append base_cfg "require_vht=1" "$N";;
esac
- local rlist= r
- json_get_values rate_list supported_rates
for r in $rate_list; do
hostapd_add_rate rlist "$r"
done
+ for br in $basic_rate_list; do
+ hostapd_add_rate brlist "$br"
+ done
+
[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
- [ -n "$beacon_int" ] && append base_cfg "beacon_int=$beacon_int" "$N"
+ append base_cfg "beacon_int=$beacon_int" "$N"
cat > "$config" <<EOF
driver=$driver
[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
[ -n "$iapp_interface" ] && {
local ifname
- network_get_device ifname "$iapp_interface" || ifname = "$iapp_interface"
+ network_get_device ifname "$iapp_interface" || ifname="$iapp_interface"
append bss_conf "iapp_interface=$ifname" "$N"
}
}
local beacon_int brates mrate
[ -n "$bssid" ] && append network_data "bssid=$bssid" "$N$T"
- [ -n "$beacon_int" ] && append network_data "beacon_int=$beacon_int" "$N$T"
local bssid_blacklist bssid_whitelist
json_get_values bssid_blacklist bssid_blacklist
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(LEDE_GIT)/project/odhcpd.git
-PKG_SOURCE_DATE:=2017-02-09
-PKG_SOURCE_VERSION:=8df4253ba73246d31f2e65f2004da3f9890c22c5
-PKG_MIRROR_HASH:=0040f94d11d0039505328a90b2ff48968db873e9e7967307631bf40ef5679275
+PKG_SOURCE_DATE:=2017-04-28
+PKG_SOURCE_VERSION:=9268ca65d6e000b6cd4ed72d4a8fa427dada6f06
+PKG_MIRROR_HASH:=3c375291de38034f0965c92e509ca17788d3b31fe13abbc8f541b2e2452bc7fe
PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
PKG_LICENSE:=GPL-2.0
PKG_SOURCE_URL:=\
https://build.openvpn.net/downloads/releases/ \
- https://swupdate.openvpn.net/community/releases/
+ https://swupdate.openvpn.net/community/releases/ \
+ http://www.eurephia.net/openvpn/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_HASH:=15e15fc97f189b52aee7c90ec8355aa77469c773125110b4c2f089abecde36fb
+PKG_HASH:=7aa86167a5b8923e54e8795b814ed77288c793671f59fd830d9ab76d4b480571
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
-@@ -107,7 +107,6 @@ const char title_string[] =
+@@ -106,7 +106,6 @@ const char title_string[] =
#ifdef HAVE_AEAD_CIPHER_MODES
" [AEAD]"
#endif
--- a/src/openvpn/ssl_mbedtls.c
+++ b/src/openvpn/ssl_mbedtls.c
-@@ -1337,7 +1337,7 @@ const char *
+@@ -1336,7 +1336,7 @@ const char *
get_ssl_library_version(void)
{
static char mbedtls_version[30];
--- a/configure.ac
+++ b/configure.ac
-@@ -1058,37 +1058,14 @@ dnl
+@@ -1076,37 +1076,14 @@ dnl
AC_ARG_VAR([LZ4_CFLAGS], [C compiler flags for lz4])
AC_ARG_VAR([LZ4_LIBS], [linker flags for lz4])
if test "$enable_lz4" = "yes" && test "$enable_comp_stub" = "no"; then
--- a/src/openvpn/syshead.h
+++ b/src/openvpn/syshead.h
-@@ -594,11 +594,11 @@ socket_defined(const socket_descriptor_t
+@@ -597,11 +597,11 @@ socket_defined(const socket_descriptor_t
/*
* Should we include NTLM proxy functionality
*/
* Should we include proxy digest auth functionality
--- a/src/openvpn/crypto_mbedtls.c
+++ b/src/openvpn/crypto_mbedtls.c
-@@ -320,6 +320,7 @@ int
+@@ -319,6 +319,7 @@ int
key_des_num_cblocks(const mbedtls_cipher_info_t *kt)
{
int ret = 0;
if (kt->type == MBEDTLS_CIPHER_DES_CBC)
{
ret = 1;
-@@ -332,6 +333,7 @@ key_des_num_cblocks(const mbedtls_cipher
+@@ -331,6 +332,7 @@ key_des_num_cblocks(const mbedtls_cipher
{
ret = 3;
}
dmsg(D_CRYPTO_DEBUG, "CRYPTO INFO: n_DES_cblocks=%d", ret);
return ret;
-@@ -340,6 +342,7 @@ key_des_num_cblocks(const mbedtls_cipher
+@@ -339,6 +341,7 @@ key_des_num_cblocks(const mbedtls_cipher
bool
key_des_check(uint8_t *key, int key_len, int ndc)
{
int i;
struct buffer b;
-@@ -368,11 +371,15 @@ key_des_check(uint8_t *key, int key_len,
+@@ -367,11 +370,15 @@ key_des_check(uint8_t *key, int key_len,
err:
return false;
int i;
struct buffer b;
-@@ -387,6 +394,7 @@ key_des_fixup(uint8_t *key, int key_len,
+@@ -386,6 +393,7 @@ key_des_fixup(uint8_t *key, int key_len,
}
mbedtls_des_key_set_parity(key);
}
}
/*
-@@ -698,10 +706,12 @@ cipher_des_encrypt_ecb(const unsigned ch
+@@ -710,10 +718,12 @@ cipher_des_encrypt_ecb(const unsigned ch
unsigned char *src,
unsigned char *dst)
{
PKG_NAME:=samba
PKG_VERSION:=3.6.25
-PKG_RELEASE:=5
+PKG_RELEASE:=6
PKG_SOURCE_URL:=https://download.samba.org/pub/samba \
https://download.samba.org/pub/samba/stable
PKG_SOURCE_URL=$(LEDE_GIT)/project/mdnsd.git
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2017-03-10
-PKG_SOURCE_VERSION:=d4376788601c38963c4c836d325e3a66498079ea
-PKG_MIRROR_HASH:=be60c437e13cf712b967af08c7cf8bda8dc3ad6d169965e3108fe3107c59009b
+PKG_SOURCE_DATE:=2017-05-22
+PKG_SOURCE_VERSION:=0e8b948ff8dd1cb1763180c99b522390529c7841
+PKG_MIRROR_HASH:=1cdd25464e1be69bef56092bc8547ba254ffc2d7c32f13cf02a80c8742876f1b
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=LGPL-2.1
#!/bin/sh /etc/rc.common
# Copyright (c) 2014 OpenWrt.org
-. /lib/functions/network.sh
-
START=80
USE_PROCD=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
http://www.netfilter.org/projects/conntrack-tools/files \
- http://mirrors.evolva.ro/netfilter.org/conntrack-tools \
-
-
+ ftp://ftp.netfilter.org/pub/conntrack-tools \
+ http://mirrors.evolva.ro/netfilter.org/conntrack-tools
PKG_HASH:=b7caf4fcc4c03575df57d25e5216584d597fd916c891f191dac616ce68bdba6c
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_NAME:=curl
PKG_VERSION:=7.52.1
-PKG_RELEASE:=3
+PKG_RELEASE:=4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://curl.haxx.se/download/ \
http://www.mirrorspace.org/curl/ \
+ ftp://ftp.sunet.se/pub/www/utilities/curl/ \
+ ftp://ftp.planetmirror.com/pub/curl/ \
http://www.mirrormonster.com/curl/download/ \
http://curl.mirrors.cyberservers.net/download/
-
PKG_HASH:=d16185a767cb2c1ba3d5b9096ec54e5ec198b213f45864a38b3bda4bbf87389b
PKG_LICENSE:=MIT
--- /dev/null
+From 6019f1795b4e3b72507b84b0e02dc8c32024f562 Mon Sep 17 00:00:00 2001
+From: Dan Fandrich <dan@coneharvesters.com>
+Date: Sat, 11 Mar 2017 10:59:34 +0100
+Subject: [PATCH] CVE-2017-7407: fixed
+
+Bug: https://curl.haxx.se/docs/adv_20170403.html
+
+Reported-by: Brian Carpenter
+---
+ src/tool_writeout.c | 6 +++---
+ tests/data/Makefile.inc | 2 +-
+ tests/data/test1440 | 31 +++++++++++++++++++++++++++++++
+ tests/data/test1441 | 31 +++++++++++++++++++++++++++++++
+ tests/data/test1442 | 35 +++++++++++++++++++++++++++++++++++
+ 5 files changed, 101 insertions(+), 4 deletions(-)
+ create mode 100644 tests/data/test1440
+ create mode 100644 tests/data/test1441
+ create mode 100644 tests/data/test1442
+
+--- a/src/tool_writeout.c
++++ b/src/tool_writeout.c
+@@ -5,7 +5,7 @@
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
++ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+@@ -113,7 +113,7 @@ void ourWriteOut(CURL *curl, struct OutS
+ double doubleinfo;
+
+ while(ptr && *ptr) {
+- if('%' == *ptr) {
++ if('%' == *ptr && ptr[1]) {
+ if('%' == ptr[1]) {
+ /* an escaped %-letter */
+ fputc('%', stream);
+@@ -341,7 +341,7 @@ void ourWriteOut(CURL *curl, struct OutS
+ }
+ }
+ }
+- else if('\\' == *ptr) {
++ else if('\\' == *ptr && ptr[1]) {
+ switch(ptr[1]) {
+ case 'r':
+ fputc('\r', stream);
+--- a/tests/data/Makefile.inc
++++ b/tests/data/Makefile.inc
+@@ -150,7 +150,7 @@ test1408 test1409 test1410 test1411 test
+ test1416 test1417 test1418 test1419 test1420 test1421 test1422 test1423 \
+ test1424 \
+ test1428 test1429 test1430 test1431 test1432 test1433 test1434 test1435 \
+-test1436 test1437 test1438 test1439 \
++test1436 test1437 test1438 test1439 test1440 test1441 test1442 \
+ \
+ test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
+ test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
+--- /dev/null
++++ b/tests/data/test1440
+@@ -0,0 +1,31 @@
++<testcase>
++<info>
++<keywords>
++--write-out
++</keywords>
++</info>
++# Server-side
++<reply>
++</reply>
++
++# Client-side
++<client>
++<server>
++file
++</server>
++
++<name>
++Check --write-out with trailing %{
++</name>
++<command>
++file://localhost/%PWD/log/ --write-out '%{'
++</command>
++</client>
++
++# Verify data
++<verify>
++<stdout nonewline="yes">
++%{
++</stdout>
++</verify>
++</testcase>
+--- /dev/null
++++ b/tests/data/test1441
+@@ -0,0 +1,31 @@
++<testcase>
++<info>
++<keywords>
++--write-out
++</keywords>
++</info>
++# Server-side
++<reply>
++</reply>
++
++# Client-side
++<client>
++<server>
++file
++</server>
++
++<name>
++Check --write-out with trailing %
++</name>
++<command>
++file://localhost/%PWD/log/ --write-out '%'
++</command>
++</client>
++
++# Verify data
++<verify>
++<stdout nonewline="yes">
++%
++</stdout>
++</verify>
++</testcase>
+--- /dev/null
++++ b/tests/data/test1442
+@@ -0,0 +1,35 @@
++<testcase>
++<info>
++<keywords>
++--write-out
++FILE
++</keywords>
++</info>
++# Server-side
++<reply>
++</reply>
++
++# Client-side
++<client>
++<server>
++file
++</server>
++
++<name>
++Check --write-out with trailing \
++</name>
++<command>
++file://localhost/%PWD/log/non-existent-file.txt --write-out '\'
++</command>
++</client>
++
++# Verify data
++<verify>
++<errorcode>
++37
++</errorcode>
++<stdout nonewline="yes">
++\
++</stdout>
++</verify>
++</testcase>
--- /dev/null
+From 8166b637bce299f4ac64d371c20cd5afea72c364 Mon Sep 17 00:00:00 2001
+From: Jay Satiro <raysatiro@yahoo.com>
+Date: Wed, 22 Mar 2017 01:59:49 -0400
+Subject: [PATCH] TLS: Fix switching off SSL session id when client cert is
+ used
+
+- Move the sessionid flag to ssl_primary_config so that ssl and
+ proxy_ssl will each have their own sessionid flag.
+
+Regression since HTTPS-Proxy support was added in cb4e2be. Prior to that
+this issue had been fixed in 247d890, CVE-2016-5419.
+
+Bug: https://github.com/curl/curl/issues/1341
+Reported-by: lijian996@users.noreply.github.com
+---
+ lib/url.c | 5 +++--
+ lib/urldata.h | 2 +-
+ lib/vtls/axtls.c | 4 ++--
+ lib/vtls/cyassl.c | 4 ++--
+ lib/vtls/darwinssl.c | 2 +-
+ lib/vtls/gtls.c | 4 ++--
+ lib/vtls/mbedtls.c | 4 ++--
+ lib/vtls/nss.c | 2 +-
+ lib/vtls/openssl.c | 4 ++--
+ lib/vtls/polarssl.c | 4 ++--
+ lib/vtls/schannel.c | 4 ++--
+ lib/vtls/vtls.c | 9 ++++++---
+ 12 files changed, 26 insertions(+), 22 deletions(-)
+
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -548,7 +548,7 @@ CURLcode Curl_init_userdefined(struct Us
+ #endif
+ set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
+ type */
+- set->general_ssl.sessionid = TRUE; /* session ID caching enabled by
++ set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
+ default */
+ set->proxy_ssl = set->ssl;
+
+@@ -2470,8 +2470,9 @@ CURLcode Curl_setopt(struct Curl_easy *d
+ break;
+
+ case CURLOPT_SSL_SESSIONID_CACHE:
+- data->set.general_ssl.sessionid = (0 != va_arg(param, long)) ?
++ data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
+ TRUE : FALSE;
++ data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
+ break;
+
+ #ifdef USE_LIBSSH2
+--- a/lib/urldata.h
++++ b/lib/urldata.h
+@@ -354,6 +354,7 @@ struct ssl_primary_config {
+ char *random_file; /* path to file containing "random" data */
+ char *egdsocket; /* path to file containing the EGD daemon socket */
+ char *cipher_list; /* list of ciphers to use */
++ bool sessionid; /* cache session IDs or not */
+ };
+
+ struct ssl_config_data {
+@@ -383,7 +384,6 @@ struct ssl_config_data {
+ };
+
+ struct ssl_general_config {
+- bool sessionid; /* cache session IDs or not */
+ size_t max_ssl_sessions; /* SSL session id cache size */
+ };
+
+--- a/lib/vtls/axtls.c
++++ b/lib/vtls/axtls.c
+@@ -256,7 +256,7 @@ static CURLcode connect_prep(struct conn
+ * 2) setting up callbacks. these seem gnutls specific
+ */
+
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ const uint8_t *ssl_sessionid;
+ size_t ssl_idsize;
+
+@@ -386,7 +386,7 @@ static CURLcode connect_finish(struct co
+ conn->send[sockindex] = axtls_send;
+
+ /* Put our freshly minted SSL session in cache */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ const uint8_t *ssl_sessionid = ssl_get_session_id_size(ssl);
+ size_t ssl_idsize = ssl_get_session_id(ssl);
+ Curl_ssl_sessionid_lock(conn);
+--- a/lib/vtls/cyassl.c
++++ b/lib/vtls/cyassl.c
+@@ -383,7 +383,7 @@ cyassl_connect_step1(struct connectdata
+ #endif /* HAVE_ALPN */
+
+ /* Check if there's a cached ID we can/should use here! */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ void *ssl_sessionid = NULL;
+
+ Curl_ssl_sessionid_lock(conn);
+@@ -597,7 +597,7 @@ cyassl_connect_step3(struct connectdata
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ bool incache;
+ SSL_SESSION *our_ssl_sessionid;
+ void *old_ssl_sessionid = NULL;
+--- a/lib/vtls/darwinssl.c
++++ b/lib/vtls/darwinssl.c
+@@ -1541,7 +1541,7 @@ static CURLcode darwinssl_connect_step1(
+ #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+ /* Check if there's a cached ID we can/should use here! */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ char *ssl_sessionid;
+ size_t ssl_sessionid_len;
+
+--- a/lib/vtls/gtls.c
++++ b/lib/vtls/gtls.c
+@@ -782,7 +782,7 @@ gtls_connect_step1(struct connectdata *c
+
+ /* This might be a reconnect, so we check for a session ID in the cache
+ to speed up things */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ void *ssl_sessionid;
+ size_t ssl_idsize;
+
+@@ -1311,7 +1311,7 @@ gtls_connect_step3(struct connectdata *c
+ conn->recv[sockindex] = gtls_recv;
+ conn->send[sockindex] = gtls_send;
+
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ /* we always unconditionally get the session id here, as even if we
+ already got it from the cache and asked to use it in the connection, it
+ might've been rejected and then a new one is in use now and we need to
+--- a/lib/vtls/mbedtls.c
++++ b/lib/vtls/mbedtls.c
+@@ -374,7 +374,7 @@ mbed_connect_step1(struct connectdata *c
+ mbedtls_ssl_list_ciphersuites());
+
+ /* Check if there's a cached ID we can/should use here! */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ void *old_session = NULL;
+
+ Curl_ssl_sessionid_lock(conn);
+@@ -618,7 +618,7 @@ mbed_connect_step3(struct connectdata *c
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ int ret;
+ mbedtls_ssl_session *our_ssl_sessionid;
+ void *old_ssl_sessionid = NULL;
+--- a/lib/vtls/nss.c
++++ b/lib/vtls/nss.c
+@@ -1696,7 +1696,7 @@ static CURLcode nss_setup_connect(struct
+ goto error;
+
+ /* do not use SSL cache if disabled or we are not going to verify peer */
+- ssl_no_cache = (data->set.general_ssl.sessionid
++ ssl_no_cache = (SSL_SET_OPTION(primary.sessionid)
+ && SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
+ if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
+ goto error;
+--- a/lib/vtls/openssl.c
++++ b/lib/vtls/openssl.c
+@@ -2161,7 +2161,7 @@ static CURLcode ossl_connect_step1(struc
+ #endif
+
+ /* Check if there's a cached ID we can/should use here! */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ void *ssl_sessionid = NULL;
+
+ Curl_ssl_sessionid_lock(conn);
+@@ -2915,7 +2915,7 @@ static CURLcode ossl_connect_step3(struc
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ bool incache;
+ SSL_SESSION *our_ssl_sessionid;
+ void *old_ssl_sessionid = NULL;
+--- a/lib/vtls/polarssl.c
++++ b/lib/vtls/polarssl.c
+@@ -327,7 +327,7 @@ polarssl_connect_step1(struct connectdat
+ ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
+
+ /* Check if there's a cached ID we can/should use here! */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ void *old_session = NULL;
+
+ Curl_ssl_sessionid_lock(conn);
+@@ -555,7 +555,7 @@ polarssl_connect_step3(struct connectdat
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ int ret;
+ ssl_session *our_ssl_sessionid;
+ void *old_ssl_sessionid = NULL;
+--- a/lib/vtls/schannel.c
++++ b/lib/vtls/schannel.c
+@@ -145,7 +145,7 @@ schannel_connect_step1(struct connectdat
+ connssl->cred = NULL;
+
+ /* check for an existing re-usable credential handle */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ Curl_ssl_sessionid_lock(conn);
+ if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
+ connssl->cred = old_cred;
+@@ -714,7 +714,7 @@ schannel_connect_step3(struct connectdat
+ #endif
+
+ /* save the current session data for possible re-use */
+- if(data->set.general_ssl.sessionid) {
++ if(SSL_SET_OPTION(primary.sessionid)) {
+ bool incache;
+ struct curl_schannel_cred *old_cred = NULL;
+
+--- a/lib/vtls/vtls.c
++++ b/lib/vtls/vtls.c
+@@ -120,6 +120,9 @@ Curl_clone_primary_ssl_config(struct ssl
+ CLONE_STRING(egdsocket);
+ CLONE_STRING(random_file);
+ CLONE_STRING(clientcert);
++
++ /* Disable dest sessionid cache if a client cert is used, CVE-2016-5419. */
++ dest->sessionid = (dest->clientcert ? false : source->sessionid);
+ return TRUE;
+ }
+
+@@ -293,9 +296,9 @@ bool Curl_ssl_getsessionid(struct connec
+ int port = isProxy ? (int)conn->port : conn->remote_port;
+ *ssl_sessionid = NULL;
+
+- DEBUGASSERT(data->set.general_ssl.sessionid);
++ DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
+
+- if(!data->set.general_ssl.sessionid)
++ if(!SSL_SET_OPTION(primary.sessionid))
+ /* session ID re-use is disabled */
+ return TRUE;
+
+@@ -397,7 +400,7 @@ CURLcode Curl_ssl_addsessionid(struct co
+ &conn->proxy_ssl_config :
+ &conn->ssl_config;
+
+- DEBUGASSERT(data->set.general_ssl.sessionid);
++ DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
+
+ clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
+ if(!clone_host)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://www.netfilter.org/projects/iptables/files \
-
-
+ ftp://ftp.be.netfilter.org/pub/netfilter/iptables/ \
+ ftp://ftp.de.netfilter.org/pub/netfilter/iptables/ \
+ ftp://ftp.no.netfilter.org/pub/netfilter/iptables/
PKG_HASH:=52004c68021da9a599feed27f65defcfb22128f7da2c0531c0f75de0f479d3e0
PKG_FIXUP:=autoreconf
printf("\t\t * RIFS: %d\n", (data[1] & 0x8)>>3);
printf("\t\t * HT protection: %s\n", protection[data[2] & 0x3]);
printf("\t\t * non-GF present: %d\n", (data[2] & 0x4) >> 2);
-@@ -1380,6 +1381,13 @@ static void print_ie(const struct ie_pri
+@@ -1380,6 +1381,14 @@ static void print_ie(const struct ie_pri
static const struct ie_print ieprinters[] = {
[0] = { "SSID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+ [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
+ [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), },
+ [62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), },
++ [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+ [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), },
+ [192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), },
+#if 0
[1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
[3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), },
[5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), },
-@@ -1389,14 +1397,8 @@ static const struct ie_print ieprinters[
+@@ -1389,21 +1398,15 @@ static const struct ie_print ieprinters[
[32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), },
[35] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), },
[42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
- [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), },
[50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
[113] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), },
- [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
-@@ -1404,6 +1406,7 @@ static const struct ie_print ieprinters[
+- [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+ [127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), },
[107] = { "802.11u Interworking", print_interworking, 0, 255, BIT(PRINT_SCAN), },
[108] = { "802.11u Advertisement", print_11u_advert, 0, 255, BIT(PRINT_SCAN), },
[111] = { "802.11u Roaming Consortium", print_11u_rcon, 0, 255, BIT(PRINT_SCAN), },
include $(TOPDIR)/rules.mk
PKG_NAME:=tcpdump
-PKG_VERSION:=4.9.0
+PKG_VERSION:=4.9.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.tcpdump.org/release/ \
http://www.at.tcpdump.org/
-PKG_HASH:=eae98121cbb1c9adbedd9a777bf2eae9fa1c1c676424a54740311c8abcee5a5e
+PKG_HASH:=f9448cf4deb2049acf713655c736342662e652ef40dbe0a8f6f8d5b9ce5bd8f3
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_BUILD_PARALLEL:=1
include $(TOPDIR)/rules.mk
PKG_NAME:=ca-certificates
-PKG_VERSION:=20161130
+PKG_VERSION:=20161130+nmu1
PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/c/ca-certificates
-PKG_HASH:=04bca9e142a90a834aca0311f7ced237368d71fee7bd5c9f68ef7f4611aee471
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+PKG_HASH:=77f9aca431e3122bf04aa0ffd989b723d906db4d1c106e3290e463d73c177f0e
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-20161130
PKG_INSTALL:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(LEDE_GIT)/project/fstools.git
-PKG_SOURCE_DATE:=2016-12-04
-PKG_SOURCE_VERSION:=84b530a732b12cca1cd5ee9ba163b7ead7a83de3
-PKG_MIRROR_HASH:=b607138de1adbb7f49e53daebe28ac1352910fa2b29278365edeabafc5b46a91
+PKG_SOURCE_DATE:=2017-06-30
+PKG_SOURCE_VERSION:=bdcb075fafdac0bfe3207c23f64acd58432bad86
+PKG_MIRROR_HASH:=760a1fdbd379f1191947ac6ba9881a85a9b8c43f4a96d49db18d4654b0c312c4
+PKG_RELEASE:=1
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0
include $(INCLUDE_DIR)/feeds.mk
PKG_NAME:=opkg
-PKG_RELEASE:=17
+PKG_RELEASE:=1
+PKG_FLAGS:=essential
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=http://git.yoctoproject.org/git/opkg
-PKG_SOURCE_DATE:=2011-04-08
-PKG_SOURCE_VERSION:=9c97d5ecd795709c8584e972bfdf3aee3a5b846d
-PKG_MIRROR_HASH:=55e05270f3eb2f3aff5d3791463ce3d13b8197ca7b301cd58e731a249552c48f
-PKG_FIXUP:=autoreconf
-PKG_REMOVE_FILES = autogen.sh aclocal.m4
+PKG_SOURCE_URL:=https://git.lede-project.org/project/opkg-lede.git
+PKG_SOURCE_DATE:=2017-03-23
+PKG_SOURCE_VERSION:=1d0263bb40e3c099501fc1f2431907636230e7f2
+PKG_MIRROR_HASH:=1f527179e60b9404affa5f3c9c506d4249e085bf521f770819b8648273a1010c
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_FLAGS := nonshared
-PKG_CONFIG_DEPENDS := CONFIG_SIGNED_PACKAGES
+PKG_CONFIG_DEPENDS := CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH
PKG_BUILD_PARALLEL:=1
HOST_BUILD_PARALLEL:=1
PKG_INSTALL:=1
+HOST_BUILD_DEPENDS:=libubox/host
+
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
define Package/opkg
SECTION:=base
CATEGORY:=Base system
TITLE:=opkg package manager
- DEPENDS:=+uclient-fetch +libpthread
- URL:=http://wiki.openmoko.org/wiki/Opkg
+ DEPENDS:=+uclient-fetch +libpthread +libubox
+ URL:=https://git.lede-project.org/?p=project/opkg-lede.git
MENU:=1
endef
opkg knows how to install both .ipk and .deb packages.
endef
-define Package/opkg/config
-config OPKG_SUPPORT_MD5
- bool
- default n
- depends on PACKAGE_opkg
- prompt "Support reading old md5 hashes."
- help
- Old opkg used md5s, new uses sha. This options enables understanding both while prefering sha.
-endef
-
define Package/opkg/conffiles
/etc/opkg.conf
/etc/opkg/keys/
TARGET_CFLAGS += -ffunction-sections -fdata-sections
EXTRA_CFLAGS += $(TARGET_CPPFLAGS)
-CONFIGURE_ARGS += \
- --disable-curl \
- --disable-gpg \
- --enable-sha256 \
- --with-opkgetcdir=/etc \
- --with-opkglockfile=/var/lock/opkg.lock
-
-ifndef CONFIG_SIGNED_PACKAGES
- CONFIGURE_ARGS += --disable-usign
-endif
-ifeq ($(CONFIG_OPKG_SUPPORT_MD5),y)
- CONFIGURE_ARGS += --enable-md5
-else
- CONFIGURE_ARGS += --disable-md5
-endif
-
-MAKE_FLAGS = \
- CC="$(TARGET_CC)" \
- DESTDIR="$(PKG_INSTALL_DIR)" \
- HOST_CPU="$(PKGARCH)" \
- LDFLAGS="-Wl,--gc-sections" \
-
-define Package/opkg/Default/install
+CMAKE_OPTIONS += \
+ -DBUILD_TESTS=OFF \
+ -DHOST_CPU=$(PKGARCH) \
+ -DPATH_SPEC="$(TARGET_INIT_PATH)" \
+ -DVERSION="$(PKG_SOURCE_VERSION) ($(PKG_SOURCE_DATE))"
+
+CMAKE_HOST_OPTIONS += \
+ -DSTATIC_UBOX=ON \
+ -DBUILD_TESTS=OFF \
+ -DHOST_CPU=$(PKGARCH) \
+ -DLOCK_FILE=/tmp/opkg.lock \
+ -DVERSION="$(PKG_SOURCE_VERSION) ($(PKG_SOURCE_DATE))"
+
+define Package/opkg/install
$(INSTALL_DIR) $(1)/usr/lib/opkg
$(INSTALL_DIR) $(1)/bin
$(INSTALL_DIR) $(1)/etc/opkg
$(VERSION_SED) $(1)/etc/opkg/distfeeds.conf
$(INSTALL_BIN) ./files/20_migrate-feeds $(1)/etc/uci-defaults/
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/opkg-cl $(1)/bin/opkg
-endef
-
-define Package/opkg/install
- $(call Package/opkg/Default/install,$(1),)
ifneq ($(CONFIG_SIGNED_PACKAGES),)
echo "option check_signature 1" >> $(1)/etc/opkg.conf
endif
- mkdir $(1)/usr/sbin
+ $(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/opkg-key $(1)/usr/sbin/
endef
-define Build/InstallDev
- mkdir -p $(1)/usr/include
- $(CP) $(PKG_INSTALL_DIR)/usr/include/libopkg $(1)/usr/include/
-endef
-
-
-HOST_CONFIGURE_ARGS+= \
- --disable-curl \
- --disable-gpg \
- --enable-sha256 \
- --with-opkgetcdir=/etc \
- --with-opkglockfile=/tmp/opkg.lock
-
-define Host/Compile
- +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) CC="$(HOSTCC)" all
-endef
-
define Host/Install
$(INSTALL_BIN) $(HOST_BUILD_DIR)/src/opkg-cl $(STAGING_DIR_HOST)/bin/opkg
endef
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(LEDE_GIT)/project/procd.git
-PKG_SOURCE_DATE:=2017-02-15
-PKG_SOURCE_VERSION:=5f9124103410c178d816bb5229fba7dd2286a49b
-PKG_MIRROR_HASH:=ec887b349fc60ad3882fc9eaefb5cd299d64e7d43c062df9f7b7500591ba3e85
+PKG_SOURCE_DATE:=2017-08-08
+PKG_SOURCE_VERSION:=66be6a23d71fcc068d6b813f0e0be2f8f0b6aa88
+PKG_MIRROR_HASH:=286dcc8855f1dc403895bc9252f617c14be6f7f6ec36f13d4f4de7c4a715f08c
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0
/etc/config/rpcd
endef
+TARGET_LDFLAGS += -lcrypt
+
define Package/rpcd/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/rpcd.init $(1)/etc/init.d/rpcd
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(LEDE_GIT)/project/ubox.git
-PKG_SOURCE_DATE:=2017-01-15
-PKG_SOURCE_VERSION:=5649c028c426060616e2bd4e7ea83271cd333d21
-PKG_MIRROR_HASH:=ae77504a4397f92173a7646fa3555e5b51abd7ff1dd1c419770223359e41937a
+PKG_SOURCE_DATE:=2017-03-10
+PKG_SOURCE_VERSION:=16f7e16181e2f3e9cf3e2ce56a7e291844900d09
+PKG_MIRROR_HASH:=5f10f3df134eb8a69d281a73d39f5d2e2fc96af531a2f3960b0c6116ff11a707
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0
bool
default y
config BUSYBOX_DEFAULT_NSLOOKUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_NSLOOKUP_LEDE
bool
default y
config BUSYBOX_DEFAULT_NTPD
PKG_NAME:=busybox
PKG_VERSION:=1.25.1
-PKG_RELEASE:=2
+PKG_RELEASE:=4
PKG_FLAGS:=essential
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
LDLIBS += pam pam_misc pthread
endif
+ifdef CONFIG_BUSYBOX_DEFAULT_NSLOOKUP_LEDE
+ ifeq ($(CONFIG_USE_GLIBC),y)
+ LDLIBS += resolv
+ endif
+endif
+
define Build/Compile
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
help
nslookup is a tool to query Internet name servers.
+config BUSYBOX_CONFIG_NSLOOKUP_LEDE
+ bool "nslookup_lede"
+ depends on !BUSYBOX_CONFIG_NSLOOKUP
+ default BUSYBOX_DEFAULT_NSLOOKUP_LEDE
+ help
+ nslookup is a tool to query Internet name servers (LEDE flavor).
+
+config BUSYBOX_CONFIG_FEATURE_NSLOOKUP_LEDE_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_NSLOOKUP_LEDE_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_NSLOOKUP_LEDE && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the nslookup applet.
+
config BUSYBOX_CONFIG_NTPD
bool "ntpd"
default BUSYBOX_DEFAULT_NTPD
[ $use_dhcp = 1 ] && get_dhcp_ntp_servers "$dhcp_interface"
- [ -z "$server" ] && return
+ [ -z "$server" -a "$enable_server" = "0" ] && return
procd_open_instance
procd_set_param command "$PROG" -n -N
--- /dev/null
+From ab0f8bb80527928f513297ab93e3ec8c8b48dd50 Mon Sep 17 00:00:00 2001
+From: Jo-Philipp Wich <jo@mein.io>
+Date: Tue, 14 Mar 2017 22:21:34 +0100
+Subject: [PATCH] networking: add LEDE nslookup applet
+
+Add a new LEDE nslookup applet which is compatible with musl libc
+and providing more features like ability to specify query type.
+
+In contrast to busybox' builtin nslookup applet, this variant does
+not rely on libc resolver internals but uses explicit send logic
+and the libresolv primitives to parse received DNS responses.
+
+Signed-off-by: Jo-Philipp Wich <jo@mein.io>
+---
+ Makefile.flags | 6 +
+ networking/nslookup_lede.c | 915 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 921 insertions(+)
+ create mode 100644 networking/nslookup_lede.c
+
+diff --git a/Makefile.flags b/Makefile.flags
+index 65021de25..096ab7756 100644
+--- a/Makefile.flags
++++ b/Makefile.flags
+@@ -134,6 +134,12 @@ else
+ LDLIBS += m
+ endif
+
++# nslookup_lede might need the resolv library
++RESOLV_AVAILABLE := $(shell echo 'int main(void){res_init();return 0;}' >resolvtest.c; $(CC) $(CFLAGS) -include resolv.h -lresolv -o /dev/null resolvtest.c >/dev/null 2>&1 && echo "y"; rm resolvtest.c)
++ifeq ($(RESOLV_AVAILABLE),y)
++LDLIBS += resolv
++endif
++
+ # libpam may use libpthread, libdl and/or libaudit.
+ # On some platforms that requires an explicit -lpthread, -ldl, -laudit.
+ # However, on *other platforms* it fails when some of those flags
+diff --git a/networking/nslookup_lede.c b/networking/nslookup_lede.c
+new file mode 100644
+index 000000000..c6c90ddf3
+--- /dev/null
++++ b/networking/nslookup_lede.c
+@@ -0,0 +1,915 @@
++/*
++ * nslookup_lede - musl compatible replacement for busybox nslookup
++ *
++ * Copyright (C) 2017 Jo-Philipp Wich <jo@mein.io>
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++//config:config NSLOOKUP_LEDE
++//config: bool "nslookup_lede"
++//config: depends on !NSLOOKUP
++//config: default y
++//config: help
++//config: nslookup is a tool to query Internet name servers (LEDE flavor).
++//config:
++//config:config FEATURE_NSLOOKUP_LEDE_LONG_OPTIONS
++//config: bool "Enable long options"
++//config: default y
++//config: depends on NSLOOKUP_LEDE && LONG_OPTS
++//config: help
++//config: Support long options for the nslookup applet.
++
++//applet:IF_NSLOOKUP_LEDE(APPLET(nslookup, BB_DIR_USR_BIN, BB_SUID_DROP))
++
++//kbuild:lib-$(CONFIG_NSLOOKUP_LEDE) += nslookup_lede.o
++
++//usage:#define nslookup_lede_trivial_usage
++//usage: "[HOST] [SERVER]"
++//usage:#define nslookup_lede_full_usage "\n\n"
++//usage: "Query the nameserver for the IP address of the given HOST\n"
++//usage: "optionally using a specified DNS server"
++//usage:
++//usage:#define nslookup_lede_example_usage
++//usage: "$ nslookup localhost\n"
++//usage: "Server: default\n"
++//usage: "Address: default\n"
++//usage: "\n"
++//usage: "Name: debian\n"
++//usage: "Address: 127.0.0.1\n"
++
++#include <stdio.h>
++#include <resolv.h>
++#include <string.h>
++#include <errno.h>
++#include <time.h>
++#include <poll.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <sys/socket.h>
++#include <arpa/inet.h>
++#include <net/if.h>
++#include <netdb.h>
++
++#include "libbb.h"
++
++struct ns {
++ const char *name;
++ len_and_sockaddr addr;
++ int failures;
++ int replies;
++};
++
++struct query {
++ const char *name;
++ size_t qlen, rlen;
++ unsigned char query[512], reply[512];
++ unsigned long latency;
++ int rcode, n_ns;
++};
++
++static struct {
++ int type;
++ const char *name;
++} qtypes[] = {
++ { ns_t_soa, "SOA" },
++ { ns_t_ns, "NS" },
++ { ns_t_a, "A" },
++#if ENABLE_FEATURE_IPV6
++ { ns_t_aaaa, "AAAA" },
++#endif
++ { ns_t_cname, "CNAME" },
++ { ns_t_mx, "MX" },
++ { ns_t_txt, "TXT" },
++ { ns_t_ptr, "PTR" },
++ { ns_t_any, "ANY" },
++ { }
++};
++
++static const char *rcodes[] = {
++ "NOERROR",
++ "FORMERR",
++ "SERVFAIL",
++ "NXDOMAIN",
++ "NOTIMP",
++ "REFUSED",
++ "YXDOMAIN",
++ "YXRRSET",
++ "NXRRSET",
++ "NOTAUTH",
++ "NOTZONE",
++ "RESERVED11",
++ "RESERVED12",
++ "RESERVED13",
++ "RESERVED14",
++ "RESERVED15",
++ "BADVERS"
++};
++
++static unsigned int default_port = 53;
++static unsigned int default_retry = 2;
++static unsigned int default_timeout = 5;
++
++
++static int parse_reply(const unsigned char *msg, size_t len, int *bb_style_counter)
++{
++ ns_msg handle;
++ ns_rr rr;
++ int i, n, rdlen;
++ const char *format = NULL;
++ char astr[INET6_ADDRSTRLEN], dname[MAXDNAME];
++ const unsigned char *cp;
++
++ if (ns_initparse(msg, len, &handle) != 0) {
++ //fprintf(stderr, "Unable to parse reply: %s\n", strerror(errno));
++ return -1;
++ }
++
++ for (i = 0; i < ns_msg_count(handle, ns_s_an); i++) {
++ if (ns_parserr(&handle, ns_s_an, i, &rr) != 0) {
++ //fprintf(stderr, "Unable to parse resource record: %s\n", strerror(errno));
++ return -1;
++ }
++
++ if (bb_style_counter && *bb_style_counter == 1)
++ printf("Name: %s\n", ns_rr_name(rr));
++
++ rdlen = ns_rr_rdlen(rr);
++
++ switch (ns_rr_type(rr))
++ {
++ case ns_t_a:
++ if (rdlen != 4) {
++ //fprintf(stderr, "Unexpected A record length\n");
++ return -1;
++ }
++ inet_ntop(AF_INET, ns_rr_rdata(rr), astr, sizeof(astr));
++ if (bb_style_counter)
++ printf("Address %d: %s\n", (*bb_style_counter)++, astr);
++ else
++ printf("Name:\t%s\nAddress: %s\n", ns_rr_name(rr), astr);
++ break;
++
++#if ENABLE_FEATURE_IPV6
++ case ns_t_aaaa:
++ if (rdlen != 16) {
++ //fprintf(stderr, "Unexpected AAAA record length\n");
++ return -1;
++ }
++ inet_ntop(AF_INET6, ns_rr_rdata(rr), astr, sizeof(astr));
++ if (bb_style_counter)
++ printf("Address %d: %s\n", (*bb_style_counter)++, astr);
++ else
++ printf("%s\thas AAAA address %s\n", ns_rr_name(rr), astr);
++ break;
++#endif
++
++ case ns_t_ns:
++ if (!format)
++ format = "%s\tnameserver = %s\n";
++ /* fall through */
++
++ case ns_t_cname:
++ if (!format)
++ format = "%s\tcanonical name = %s\n";
++ /* fall through */
++
++ case ns_t_ptr:
++ if (!format)
++ format = "%s\tname = %s\n";
++ if (ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
++ ns_rr_rdata(rr), dname, sizeof(dname)) < 0) {
++ //fprintf(stderr, "Unable to uncompress domain: %s\n", strerror(errno));
++ return -1;
++ }
++ printf(format, ns_rr_name(rr), dname);
++ break;
++
++ case ns_t_mx:
++ if (rdlen < 2) {
++ fprintf(stderr, "MX record too short\n");
++ return -1;
++ }
++ n = ns_get16(ns_rr_rdata(rr));
++ if (ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
++ ns_rr_rdata(rr) + 2, dname, sizeof(dname)) < 0) {
++ //fprintf(stderr, "Cannot uncompress MX domain: %s\n", strerror(errno));
++ return -1;
++ }
++ printf("%s\tmail exchanger = %d %s\n", ns_rr_name(rr), n, dname);
++ break;
++
++ case ns_t_txt:
++ if (rdlen < 1) {
++ //fprintf(stderr, "TXT record too short\n");
++ return -1;
++ }
++ n = *(unsigned char *)ns_rr_rdata(rr);
++ if (n > 0) {
++ memset(dname, 0, sizeof(dname));
++ memcpy(dname, ns_rr_rdata(rr) + 1, n);
++ printf("%s\ttext = \"%s\"\n", ns_rr_name(rr), dname);
++ }
++ break;
++
++ case ns_t_soa:
++ if (rdlen < 20) {
++ //fprintf(stderr, "SOA record too short\n");
++ return -1;
++ }
++
++ printf("%s\n", ns_rr_name(rr));
++
++ cp = ns_rr_rdata(rr);
++ n = ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
++ cp, dname, sizeof(dname));
++
++ if (n < 0) {
++ //fprintf(stderr, "Unable to uncompress domain: %s\n", strerror(errno));
++ return -1;
++ }
++
++ printf("\torigin = %s\n", dname);
++ cp += n;
++
++ n = ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle),
++ cp, dname, sizeof(dname));
++
++ if (n < 0) {
++ //fprintf(stderr, "Unable to uncompress domain: %s\n", strerror(errno));
++ return -1;
++ }
++
++ printf("\tmail addr = %s\n", dname);
++ cp += n;
++
++ printf("\tserial = %lu\n", ns_get32(cp));
++ cp += 4;
++
++ printf("\trefresh = %lu\n", ns_get32(cp));
++ cp += 4;
++
++ printf("\tretry = %lu\n", ns_get32(cp));
++ cp += 4;
++
++ printf("\texpire = %lu\n", ns_get32(cp));
++ cp += 4;
++
++ printf("\tminimum = %lu\n", ns_get32(cp));
++ break;
++
++ default:
++ break;
++ }
++ }
++
++ return i;
++}
++
++static int parse_nsaddr(const char *addrstr, len_and_sockaddr *lsa)
++{
++ char *eptr, *hash, ifname[IFNAMSIZ];
++ unsigned int port = default_port;
++ unsigned int scope = 0;
++
++ hash = strchr(addrstr, '#');
++
++ if (hash) {
++ *hash++ = '\0';
++ port = strtoul(hash, &eptr, 10);
++
++ if (eptr == hash || *eptr != '\0' || port > 65535) {
++ errno = EINVAL;
++ return -1;
++ }
++ }
++
++ hash = strchr(addrstr, '%');
++
++ if (hash) {
++ for (eptr = ++hash; *eptr != '\0' && *eptr != '#'; eptr++) {
++ if ((eptr - hash) >= IFNAMSIZ) {
++ errno = ENODEV;
++ return -1;
++ }
++
++ ifname[eptr - hash] = *eptr;
++ }
++
++ ifname[eptr - hash] = '\0';
++ scope = if_nametoindex(ifname);
++
++ if (scope == 0) {
++ errno = ENODEV;
++ return -1;
++ }
++ }
++
++#if ENABLE_FEATURE_IPV6
++ if (inet_pton(AF_INET6, addrstr, &lsa->u.sin6.sin6_addr)) {
++ lsa->u.sin6.sin6_family = AF_INET6;
++ lsa->u.sin6.sin6_port = htons(port);
++ lsa->u.sin6.sin6_scope_id = scope;
++ lsa->len = sizeof(lsa->u.sin6);
++ return 0;
++ }
++#endif
++
++ if (!scope && inet_pton(AF_INET, addrstr, &lsa->u.sin.sin_addr)) {
++ lsa->u.sin.sin_family = AF_INET;
++ lsa->u.sin.sin_port = htons(port);
++ lsa->len = sizeof(lsa->u.sin);
++ return 0;
++ }
++
++ errno = EINVAL;
++ return -1;
++}
++
++static char *make_ptr(const char *addrstr)
++{
++ const char *hexdigit = "0123456789abcdef";
++ static char ptrstr[73];
++ unsigned char addr[16];
++ char *ptr = ptrstr;
++ int i;
++
++ if (inet_pton(AF_INET6, addrstr, addr)) {
++ if (memcmp(addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12) != 0) {
++ for (i = 0; i < 16; i++) {
++ *ptr++ = hexdigit[(unsigned char)addr[15 - i] & 0xf];
++ *ptr++ = '.';
++ *ptr++ = hexdigit[(unsigned char)addr[15 - i] >> 4];
++ *ptr++ = '.';
++ }
++ strcpy(ptr, "ip6.arpa");
++ }
++ else {
++ sprintf(ptr, "%u.%u.%u.%u.in-addr.arpa",
++ addr[15], addr[14], addr[13], addr[12]);
++ }
++
++ return ptrstr;
++ }
++
++ if (inet_pton(AF_INET, addrstr, addr)) {
++ sprintf(ptr, "%u.%u.%u.%u.in-addr.arpa",
++ addr[3], addr[2], addr[1], addr[0]);
++ return ptrstr;
++ }
++
++ return NULL;
++}
++
++static unsigned long mtime(void)
++{
++ struct timespec ts;
++ clock_gettime(CLOCK_REALTIME, &ts);
++ return (unsigned long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
++}
++
++#if ENABLE_FEATURE_IPV6
++static void to_v4_mapped(len_and_sockaddr *a)
++{
++ if (a->u.sa.sa_family != AF_INET)
++ return;
++
++ memcpy(a->u.sin6.sin6_addr.s6_addr + 12,
++ &a->u.sin.sin_addr, 4);
++
++ memcpy(a->u.sin6.sin6_addr.s6_addr,
++ "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
++
++ a->u.sin6.sin6_family = AF_INET6;
++ a->u.sin6.sin6_flowinfo = 0;
++ a->u.sin6.sin6_scope_id = 0;
++ a->len = sizeof(a->u.sin6);
++}
++#endif
++
++
++/*
++ * Function logic borrowed & modified from musl libc, res_msend.c
++ */
++
++static int send_queries(struct ns *ns, int n_ns, struct query *queries, int n_queries)
++{
++ int fd;
++ int timeout = default_timeout * 1000, retry_interval, servfail_retry = 0;
++ len_and_sockaddr from = { };
++#if ENABLE_FEATURE_IPV6
++ int one = 1;
++#endif
++ int recvlen = 0;
++ int n_replies = 0;
++ struct pollfd pfd;
++ unsigned long t0, t1, t2;
++ int nn, qn, next_query = 0;
++
++ from.u.sa.sa_family = AF_INET;
++ from.len = sizeof(from.u.sin);
++
++#if ENABLE_FEATURE_IPV6
++ for (nn = 0; nn < n_ns; nn++) {
++ if (ns[nn].addr.u.sa.sa_family == AF_INET6) {
++ from.u.sa.sa_family = AF_INET6;
++ from.len = sizeof(from.u.sin6);
++ break;
++ }
++ }
++#endif
++
++ /* Get local address and open/bind a socket */
++ fd = socket(from.u.sa.sa_family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
++
++#if ENABLE_FEATURE_IPV6
++ /* Handle case where system lacks IPv6 support */
++ if (fd < 0 && from.u.sa.sa_family == AF_INET6 && errno == EAFNOSUPPORT) {
++ fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
++ from.u.sa.sa_family = AF_INET;
++ }
++#endif
++
++ if (fd < 0)
++ return -1;
++
++ if (bind(fd, &from.u.sa, from.len) < 0) {
++ close(fd);
++ return -1;
++ }
++
++#if ENABLE_FEATURE_IPV6
++ /* Convert any IPv4 addresses in a mixed environment to v4-mapped */
++ if (from.u.sa.sa_family == AF_INET6) {
++ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
++
++ for (nn = 0; nn < n_ns; nn++)
++ to_v4_mapped(&ns[nn].addr);
++ }
++#endif
++
++ pfd.fd = fd;
++ pfd.events = POLLIN;
++ retry_interval = timeout / default_retry;
++ t0 = t2 = mtime();
++ t1 = t2 - retry_interval;
++
++ for (; t2 - t0 < timeout; t2 = mtime()) {
++ if (t2 - t1 >= retry_interval) {
++ for (qn = 0; qn < n_queries; qn++) {
++ if (queries[qn].rlen)
++ continue;
++
++ for (nn = 0; nn < n_ns; nn++) {
++ sendto(fd, queries[qn].query, queries[qn].qlen,
++ MSG_NOSIGNAL, &ns[nn].addr.u.sa, ns[nn].addr.len);
++ }
++ }
++
++ t1 = t2;
++ servfail_retry = 2 * n_queries;
++ }
++
++ /* Wait for a response, or until time to retry */
++ if (poll(&pfd, 1, t1+retry_interval-t2) <= 0)
++ continue;
++
++ while (1) {
++ recvlen = recvfrom(fd, queries[next_query].reply,
++ sizeof(queries[next_query].reply), 0,
++ &from.u.sa, &from.len);
++
++ /* read error */
++ if (recvlen < 0)
++ break;
++
++ /* Ignore non-identifiable packets */
++ if (recvlen < 4)
++ continue;
++
++ /* Ignore replies from addresses we didn't send to */
++ for (nn = 0; nn < n_ns; nn++)
++ if (memcmp(&from.u.sa, &ns[nn].addr.u.sa, from.len) == 0)
++ break;
++
++ if (nn >= n_ns)
++ continue;
++
++ /* Find which query this answer goes with, if any */
++ for (qn = next_query; qn < n_queries; qn++)
++ if (!memcmp(queries[next_query].reply, queries[qn].query, 2))
++ break;
++
++ if (qn >= n_queries || queries[qn].rlen)
++ continue;
++
++ queries[qn].rcode = queries[next_query].reply[3] & 15;
++ queries[qn].latency = mtime() - t0;
++ queries[qn].n_ns = nn;
++
++ ns[nn].replies++;
++
++ /* Only accept positive or negative responses;
++ * retry immediately on server failure, and ignore
++ * all other codes such as refusal. */
++ switch (queries[qn].rcode) {
++ case 0:
++ case 3:
++ break;
++
++ case 2:
++ if (servfail_retry && servfail_retry--) {
++ ns[nn].failures++;
++ sendto(fd, queries[qn].query, queries[qn].qlen,
++ MSG_NOSIGNAL, &ns[nn].addr.u.sa, ns[nn].addr.len);
++ }
++ /* fall through */
++
++ default:
++ continue;
++ }
++
++ /* Store answer */
++ n_replies++;
++
++ queries[qn].rlen = recvlen;
++
++ if (qn == next_query) {
++ while (next_query < n_queries) {
++ if (!queries[next_query].rlen)
++ break;
++
++ next_query++;
++ }
++ }
++ else {
++ memcpy(queries[qn].reply, queries[next_query].reply, recvlen);
++ }
++
++ if (next_query >= n_queries)
++ return n_replies;
++ }
++ }
++
++ return n_replies;
++}
++
++static struct ns *add_ns(struct ns **ns, int *n_ns, const char *addr)
++{
++ char portstr[sizeof("65535")], *p;
++ len_and_sockaddr a = { };
++ struct ns *tmp;
++ struct addrinfo *ai, *aip, hints = {
++ .ai_flags = AI_NUMERICSERV,
++ .ai_socktype = SOCK_DGRAM
++ };
++
++ if (parse_nsaddr(addr, &a)) {
++ /* Maybe we got a domain name, attempt to resolve it using the standard
++ * resolver routines */
++
++ p = strchr(addr, '#');
++ snprintf(portstr, sizeof(portstr), "%hu",
++ (unsigned short)(p ? strtoul(p, NULL, 10) : default_port));
++
++ if (!getaddrinfo(addr, portstr, &hints, &ai)) {
++ for (aip = ai; aip; aip = aip->ai_next) {
++ if (aip->ai_addr->sa_family != AF_INET &&
++ aip->ai_addr->sa_family != AF_INET6)
++ continue;
++
++#if ! ENABLE_FEATURE_IPV6
++ if (aip->ai_addr->sa_family != AF_INET)
++ continue;
++#endif
++
++ tmp = realloc(*ns, sizeof(**ns) * (*n_ns + 1));
++
++ if (!tmp)
++ return NULL;
++
++ *ns = tmp;
++
++ (*ns)[*n_ns].name = addr;
++ (*ns)[*n_ns].replies = 0;
++ (*ns)[*n_ns].failures = 0;
++ (*ns)[*n_ns].addr.len = aip->ai_addrlen;
++
++ memcpy(&(*ns)[*n_ns].addr.u.sa, aip->ai_addr, aip->ai_addrlen);
++
++ (*n_ns)++;
++ }
++
++ freeaddrinfo(ai);
++
++ return &(*ns)[*n_ns];
++ }
++
++ return NULL;
++ }
++
++ tmp = realloc(*ns, sizeof(**ns) * (*n_ns + 1));
++
++ if (!tmp)
++ return NULL;
++
++ *ns = tmp;
++
++ (*ns)[*n_ns].addr = a;
++ (*ns)[*n_ns].name = addr;
++ (*ns)[*n_ns].replies = 0;
++ (*ns)[*n_ns].failures = 0;
++
++ return &(*ns)[(*n_ns)++];
++}
++
++static int parse_resolvconf(struct ns **ns, int *n_ns)
++{
++ int prev_n_ns = *n_ns;
++ char line[128], *p;
++ FILE *resolv;
++
++ if ((resolv = fopen("/etc/resolv.conf", "r")) != NULL) {
++ while (fgets(line, sizeof(line), resolv)) {
++ p = strtok(line, " \t\n");
++
++ if (!p || strcmp(p, "nameserver"))
++ continue;
++
++ p = strtok(NULL, " \t\n");
++
++ if (!p)
++ continue;
++
++ if (!add_ns(ns, n_ns, strdup(p))) {
++ free(p);
++ break;
++ }
++ }
++
++ fclose(resolv);
++ }
++
++ return *n_ns - prev_n_ns;
++}
++
++static struct query *add_query(struct query **queries, int *n_queries,
++ int type, const char *dname)
++{
++ struct query *tmp;
++ ssize_t qlen;
++
++ tmp = realloc(*queries, sizeof(**queries) * (*n_queries + 1));
++
++ if (!tmp)
++ return NULL;
++
++ memset(&tmp[*n_queries], 0, sizeof(*tmp));
++
++ qlen = res_mkquery(QUERY, dname, C_IN, type, NULL, 0, NULL,
++ tmp[*n_queries].query, sizeof(tmp[*n_queries].query));
++
++ tmp[*n_queries].qlen = qlen;
++ tmp[*n_queries].name = dname;
++ *queries = tmp;
++
++ return &tmp[(*n_queries)++];
++}
++
++static char *sal2str(len_and_sockaddr *a)
++{
++ static char buf[INET6_ADDRSTRLEN + 1 + IFNAMSIZ + 1 + 5 + 1];
++ char *p = buf;
++
++#if ENABLE_FEATURE_IPV6
++ if (a->u.sa.sa_family == AF_INET6) {
++ inet_ntop(AF_INET6, &a->u.sin6.sin6_addr, buf, sizeof(buf));
++ p += strlen(p);
++
++ if (a->u.sin6.sin6_scope_id) {
++ if (if_indextoname(a->u.sin6.sin6_scope_id, p + 1)) {
++ *p++ = '%';
++ p += strlen(p);
++ }
++ }
++ }
++ else
++#endif
++ {
++ inet_ntop(AF_INET, &a->u.sin.sin_addr, buf, sizeof(buf));
++ p += strlen(p);
++ }
++
++ sprintf(p, "#%hu", ntohs(a->u.sin.sin_port));
++
++ return buf;
++}
++
++
++#if ENABLE_FEATURE_NSLOOKUP_LEDE_LONG_OPTIONS
++static const char nslookup_longopts[] ALIGN1 =
++ "type\0" Required_argument "q"
++ "querytype\0" Required_argument "q"
++ "port\0" Required_argument "p"
++ "retry\0" Required_argument "r"
++ "timeout\0" Required_argument "t"
++ "stats\0" Required_argument "s"
++ ;
++#endif
++
++int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
++int nslookup_main(int argc, char **argv)
++{
++ int rc = 1;
++ char *ptr, *chr;
++ struct ns *ns = NULL;
++ struct query *queries = NULL;
++ llist_t *type_strings = NULL;
++ int n_ns = 0, n_queries = 0;
++ int c, opts, option_index = 0;
++ int stats = 0, bb_style_counter = 0;
++ unsigned int types = 0;
++ HEADER *header;
++
++#if ENABLE_FEATURE_NSLOOKUP_LEDE_LONG_OPTIONS
++ applet_long_options = nslookup_longopts;
++#endif
++
++ opt_complementary = "q::";
++ opts = getopt32(argv, "+q:*p:+r:+t:+s",
++ &type_strings, &default_port,
++ &default_retry, &default_timeout);
++
++ while (type_strings) {
++ ptr = llist_pop(&type_strings);
++
++ /* skip leading text, e.g. when invoked with -querytype=AAAA */
++ if ((chr = strchr(ptr, '=')) != NULL)
++ ptr = chr + 1;
++
++ for (c = 0; qtypes[c].name; c++)
++ if (!strcmp(qtypes[c].name, ptr))
++ break;
++
++ if (!qtypes[c].name) {
++ fprintf(stderr, "Invalid query type \"%s\"\n", ptr);
++ goto out;
++ }
++
++ types |= (1 << c);
++ }
++
++ if (default_port > 65535) {
++ fprintf(stderr, "Invalid server port\n");
++ goto out;
++ }
++
++ if (!default_retry) {
++ fprintf(stderr, "Invalid retry value\n");
++ goto out;
++ }
++
++ if (!default_timeout) {
++ fprintf(stderr, "Invalid timeout value\n");
++ goto out;
++ }
++
++ stats = (opts & 16);
++
++ if (optind >= argc)
++ bb_show_usage();
++
++ for (option_index = optind;
++ option_index < ((argc - optind) > 1 ? argc - 1 : argc);
++ option_index++) {
++
++ /* No explicit type given, guess query type.
++ * If we can convert the domain argument into a ptr (means that
++ * inet_pton() could read it) we assume a PTR request, else
++ * we issue A+AAAA queries and switch to an output format
++ * mimicking the one of the traditional nslookup applet. */
++ if (types == 0) {
++ ptr = make_ptr(argv[option_index]);
++
++ if (ptr) {
++ add_query(&queries, &n_queries, T_PTR, ptr);
++ }
++ else {
++ bb_style_counter = 1;
++ add_query(&queries, &n_queries, T_A, argv[option_index]);
++#if ENABLE_FEATURE_IPV6
++ add_query(&queries, &n_queries, T_AAAA, argv[option_index]);
++#endif
++ }
++ }
++ else {
++ for (c = 0; qtypes[c].name; c++)
++ if (types & (1 << c))
++ add_query(&queries, &n_queries, qtypes[c].type,
++ argv[option_index]);
++ }
++ }
++
++ /* Use given DNS server if present */
++ if (option_index < argc) {
++ if (!add_ns(&ns, &n_ns, argv[option_index])) {
++ fprintf(stderr, "Invalid NS server address \"%s\": %s\n",
++ argv[option_index], strerror(errno));
++ goto out;
++ }
++ }
++ else {
++ parse_resolvconf(&ns, &n_ns);
++ }
++
++ /* Fall back to localhost if we could not find NS in resolv.conf */
++ if (n_ns == 0) {
++ add_ns(&ns, &n_ns, "127.0.0.1");
++ }
++
++ for (c = 0; c < n_ns; c++) {
++ rc = send_queries(&ns[c], 1, queries, n_queries);
++
++ if (rc < 0) {
++ fprintf(stderr, "Failed to send queries: %s\n", strerror(errno));
++ goto out;
++ } else if (rc > 0) {
++ break;
++ }
++ }
++
++ if (c >= n_ns) {
++ fprintf(stderr,
++ ";; connection timed out; no servers could be reached\n\n");
++
++ return 1;
++ }
++
++ printf("Server:\t\t%s\n", ns[c].name);
++ printf("Address:\t%s\n", sal2str(&ns[c].addr));
++
++ if (stats) {
++ printf("Replies:\t%d\n", ns[c].replies);
++ printf("Failures:\t%d\n", ns[c].failures);
++ }
++
++ printf("\n");
++
++ for (rc = 0; rc < n_queries; rc++) {
++ if (stats) {
++ printf("Query #%d completed in %lums:\n", rc, queries[rc].latency);
++ }
++
++ if (queries[rc].rcode != 0) {
++ printf("** server can't find %s: %s\n", queries[rc].name,
++ rcodes[queries[rc].rcode]);
++ continue;
++ }
++
++ c = 0;
++
++ if (queries[rc].rlen) {
++ if (!bb_style_counter) {
++ header = (HEADER *)queries[rc].reply;
++
++ if (!header->aa)
++ printf("Non-authoritative answer:\n");
++
++ c = parse_reply(queries[rc].reply, queries[rc].rlen, NULL);
++ }
++ else {
++ c = parse_reply(queries[rc].reply, queries[rc].rlen,
++ &bb_style_counter);
++ }
++ }
++
++ if (c == 0)
++ printf("*** Can't find %s: No answer\n", queries[rc].name);
++ else if (c < 0)
++ printf("*** Can't find %s: Parse error\n", queries[rc].name);
++
++ if (!bb_style_counter)
++ printf("\n");
++ }
++
++ rc = 0;
++
++out:
++ if (n_ns)
++ free(ns);
++
++ if (n_queries)
++ free(queries);
++
++ return rc;
++}
+--
+2.11.0
+
--- /dev/null
+From e88608eae24ae5934034e1ecb6c494fefbf1b9ae Mon Sep 17 00:00:00 2001
+From: Denys Vlasenko <vda.linux@googlemail.com>
+Date: Mon, 13 Mar 2017 20:50:42 +0100
+Subject: [PATCH 1/2] vi: don't touch file with :x when modified_count == 0
+
+Along with it, there are other changes
+
+ - Check for uppercase X is removed as the expression will be always false and
+ :X itself is another totally different command in standard vim
+ - The status line will show number of written lines instead of lines requested
+ by the colon command. This is also how the standard vim is doing, though
+ the difference is that '!' has to be explicitly specified in vim to allow
+ partial writes
+
+Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
+Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
+---
+ editors/vi.c | 43 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 26 insertions(+), 17 deletions(-)
+
+--- a/editors/vi.c
++++ b/editors/vi.c
+@@ -1038,7 +1038,9 @@ static void colon(char *buf)
+ || strncmp(p, "wn", cnt) == 0
+ || (p[0] == 'x' && !p[1])
+ ) {
+- cnt = file_write(current_filename, text, end - 1);
++ if (modified_count != 0 || p[0] != 'x') {
++ cnt = file_write(current_filename, text, end - 1);
++ }
+ if (cnt < 0) {
+ if (cnt == -1)
+ status_line_bold("Write error: %s", strerror(errno));
+@@ -1049,8 +1051,9 @@ static void colon(char *buf)
+ current_filename,
+ count_lines(text, end - 1), cnt
+ );
+- if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
+- || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
++ if (p[0] == 'x'
++ || p[1] == 'q' || p[1] == 'n'
++ || p[1] == 'Q' || p[1] == 'N'
+ ) {
+ editing = 0;
+ }
+@@ -1480,16 +1483,19 @@ static void colon(char *buf)
+ goto ret;
+ }
+ #endif
+- // how many lines in text[]?
+- li = count_lines(q, r);
+- size = r - q + 1;
+ //if (useforce) {
+ // if "fn" is not write-able, chmod u+w
+ // sprintf(syscmd, "chmod u+w %s", fn);
+ // system(syscmd);
+ // forced = TRUE;
+ //}
+- l = file_write(fn, q, r);
++ if (modified_count != 0 || cmd[0] != 'x') {
++ size = r - q + 1;
++ l = file_write(fn, q, r);
++ } else {
++ size = 0;
++ l = 0;
++ }
+ //if (useforce && forced) {
+ // chmod u-w
+ // sprintf(syscmd, "chmod u-w %s", fn);
+@@ -1500,17 +1506,20 @@ static void colon(char *buf)
+ if (l == -1)
+ status_line_bold_errno(fn);
+ } else {
++ // how many lines written
++ li = count_lines(q, q + l - 1);
+ status_line("'%s' %dL, %dC", fn, li, l);
+- if (q == text && r == end - 1 && l == size) {
+- modified_count = 0;
+- last_modified_count = -1;
+- }
+- if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n'
+- || cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N'
+- )
+- && l == size
+- ) {
+- editing = 0;
++ if (l == size) {
++ if (q == text && q + l == end) {
++ modified_count = 0;
++ last_modified_count = -1;
++ }
++ if (cmd[0] == 'x'
++ || cmd[1] == 'q' || cmd[1] == 'n'
++ || cmd[1] == 'Q' || cmd[1] == 'N'
++ ) {
++ editing = 0;
++ }
+ }
+ }
+ #if ENABLE_FEATURE_VI_YANKMARK
--- /dev/null
+From 8f3bf4f0d3605b50a8e4c48c89aeabc455f04884 Mon Sep 17 00:00:00 2001
+From: Yousong Zhou <yszhou4tech@gmail.com>
+Date: Fri, 24 Mar 2017 21:13:10 +0100
+Subject: [PATCH 2/2] vi: avoid touching a new file with ZZ when no editing has
+ been done
+
+This is the behaviour observed with standard vim and busybox vi of at
+least 1.22.1. It was changed with commit "32afd3a vi: some
+simplifications" which happened before 1.23.0.
+
+Mistyping filename on command line happens fairly often and it's better
+we restore the old behaviour to avoid a few unnecessary flash writes and
+sometimes efforts of debugging bugs caused by those unneeded stray
+files.
+
+Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
+Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
+---
+ editors/vi.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/editors/vi.c
++++ b/editors/vi.c
+@@ -719,14 +719,6 @@ static int init_text_buffer(char *fn)
+ {
+ int rc;
+
+- flush_undo_data();
+- modified_count = 0;
+- last_modified_count = -1;
+-#if ENABLE_FEATURE_VI_YANKMARK
+- /* init the marks */
+- memset(mark, 0, sizeof(mark));
+-#endif
+-
+ /* allocate/reallocate text buffer */
+ free(text);
+ text_size = 10240;
+@@ -741,6 +733,14 @@ static int init_text_buffer(char *fn)
+ // file doesnt exist. Start empty buf with dummy line
+ char_insert(text, '\n', NO_UNDO);
+ }
++
++ flush_undo_data();
++ modified_count = 0;
++ last_modified_count = -1;
++#if ENABLE_FEATURE_VI_YANKMARK
++ /* init the marks */
++ memset(mark, 0, sizeof(mark));
++#endif
+ return rc;
+ }
+
bugcheck_generic()
{
- echo "libreCMC crashlog report" > $CRASHDIR/info.txt
+ echo "LEDE crashlog report" > $CRASHDIR/info.txt
date >> $CRASHDIR/info.txt
echo >> $CRASHDIR/info.txt
echo "uname" >> $CRASHDIR/info.txt
include $(TOPDIR)/rules.mk
PKG_NAME:=f2fs-tools
-PKG_VERSION:=1.7.0
-PKG_RELEASE:=1
+PKG_VERSION:=1.8.0
+PKG_RELEASE:=3
PKG_LICENSE:=GPLv2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs-tools.git/snapshot/
-PKG_HASH:=33d454c2e95aabef5659949c4fff15f6c9877b48349e64411de502bc62b0cbd4
+PKG_SOURCE_URL:=https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git/snapshot/
+PKG_HASH:=d4dbecf55560c548bf0758c9f641d1beec1e960b38cbbc19951195d5144d39ae
PKG_FIXUP:=autoreconf
PKG_BUILD_PARALLEL:=1
DEPENDS:=+libuuid
endef
+CONFIGURE_ARGS += \
+ --without-selinux
+
+CONFIGURE_VARS += \
+ ac_cv_file__git=no
+
define Package/libf2fs/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) \
--- /dev/null
+From 31873d5cdf8a97d5f7921451c54f6d293293c6cc Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Wed, 23 Aug 2017 13:33:00 -0700
+Subject: [PATCH] mkfs.f2fs: fix missing cpu_to_le64 for checkpoint version
+
+The error on mips was reported by Stijn as follow.
+
+Commit 8399a29df92d6867d226df362edbf2e0efa527c1 in f2fs-tools
+("mkfs.f2fs: give random checkpoint version") causes a bug when mounting
+a filesystem created with it on a MIPS64 device running a 4.4(.83)
+kernel. The following kernel warning appears several times per second,
+for 30 seconds:
+
+[ 23.837262] ------------[ cut here ]------------
+[ 23.842039] WARNING: CPU: 0 PID: 935 at fs/f2fs/segment.c:718
+update_sit_entry+0x1c0/0x2b0()
+[ 23.850507] Modules linked in: pppoe ppp_async l2tp_ppp iptable_nat
+[ 24.174064] Call Trace:
+[ 24.176527] [<ffffffff81126e14>] show_stack+0x68/0xb4
+[ 24.181595] [<ffffffff81321fc4>] dump_stack+0x8c/0xc4
+[ 24.186660] [<ffffffff8113d004>] warn_slowpath_common+0xa0/0xd0
+[ 24.192597] [<ffffffff812e0148>] update_sit_entry+0x1c0/0x2b0
+[ 24.198353] [<ffffffff812e0a70>] refresh_sit_entry+0x70/0xf8
+[ 24.204022] [<ffffffff812e251c>] allocate_data_block+0x1f0/0x310
+[ 24.210038] [<ffffffff812e28d8>] do_write_page+0x29c/0x2bc
+[ 24.215532] [<ffffffff812e2a88>] write_data_page+0xa0/0xd8
+[ 24.221028] [<ffffffff812d844c>] do_write_data_page+0xe4/0x384
+[ 24.226870] [<ffffffff812d88f4>] f2fs_write_data_page+0x208/0x464
+[ 24.232972] [<ffffffff812d5184>] __f2fs_writepage+0x1c/0x74
+[ 24.238553] [<ffffffff812d54dc>]
+f2fs_write_cache_pages.constprop.7+0x250/0x394
+[ 24.245869] [<ffffffff812d57f4>] f2fs_write_data_pages+0x130/0x1b0
+[ 24.252066] [<ffffffff811a9f80>] __filemap_fdatawrite_range+0xa0/0xd4
+[ 24.258515] [<ffffffff812d2338>] sync_dirty_dir_inodes+0x94/0xd8
+[ 24.264530] [<ffffffff812d2484>] write_checkpoint+0x108/0xb9c
+[ 24.270283] [<ffffffff812cc398>] f2fs_sync_fs+0x68/0xb0
+[ 24.275526] [<ffffffff812c641c>] f2fs_sync_file+0x2e8/0x518
+[ 24.281107] [<ffffffff81213ff4>] do_fsync+0x38/0x70
+[ 24.285992] [<ffffffff812142e8>] SyS_fsync+0x14/0x20
+[ 24.290972] [<ffffffff81103950>] syscall_common+0x34/0x58
+[ 24.296372]
+[ 24.298096] ---[ end trace fd3ac44449b218ab ]---
+
+Fix: 8399a29df92d68 ("mkfs.f2fs: give random checkpoint version")
+Reported-And-Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+---
+ mkfs/f2fs_format.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
+index 92876b8..b379e80 100644
+--- a/mkfs/f2fs_format.c
++++ b/mkfs/f2fs_format.c
+@@ -546,7 +546,7 @@ static int f2fs_write_check_point_pack(void)
+ }
+
+ /* 1. cp page 1 of checkpoint pack 1 */
+- cp->checkpoint_ver = rand() | 0x1;
++ cp->checkpoint_ver = cpu_to_le64(rand() | 0x1);
+ set_cp(cur_node_segno[0], c.cur_seg[CURSEG_HOT_NODE]);
+ set_cp(cur_node_segno[1], c.cur_seg[CURSEG_WARM_NODE]);
+ set_cp(cur_node_segno[2], c.cur_seg[CURSEG_COLD_NODE]);
+--
+2.13.5
+
PKG_FLAGS:=nonshared
-PKG_BUILD_DEPENDS:=util-linux liblzo zlib
+PKG_BUILD_DEPENDS:=util-linux lzo zlib
PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=
include $(TOPDIR)/rules.mk
PKG_NAME:=ugps
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE_URL=$(LEDE_GIT)/project/ugps.git
PKG_SOURCE_PROTO:=git
local tty="$(uci get gps.@gps[-1].tty)"
local atime="$(uci get gps.@gps[-1].adjust_time)"
- [ -d "/sys/class/tty/$tty/" ] || return
+ [ -c "$tty" ] || {
+ tty="/dev/$tty"
+ [ -c "$tty" ] || return
+ }
procd_open_instance
- procd_set_param command "$PROG" "/dev/$tty"
+ procd_set_param command "$PROG"
[ "$atime" -eq 0 ] || procd_append_param command "-a"
+ procd_append_param command "$tty"
procd_set_param respawn
procd_close_instance
}
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(LEDE_GIT)/project/usbmode.git
-PKG_SOURCE_DATE:=2014-08-26
-PKG_SOURCE_VERSION:=993a9a542791953c4804f7ddbb3a07756738e37a
-PKG_MIRROR_HASH:=dc4daa80a0d51524b41c6bf67cb368ca51fcfba1217adedd6823b24a68be5bf4
+PKG_SOURCE_DATE:=2017-05-24
+PKG_SOURCE_VERSION:=453da8e540b1c53d357b897d6c70372cd4633390
+PKG_MIRROR_HASH:=b4a7132b940192f2e9a74bd890bd7008ede701e1d52284c3ade0cdc7d663929f
CMAKE_INSTALL:=1
PKG_LICENSE:=GPL-2.0
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
-PKG_DATA_VERSION:=20150115
+PKG_DATA_VERSION:=20170205
PKG_DATA_URL:=http://www.draisberghof.de/usb_modeswitch
PKG_DATA_PATH:=usb-modeswitch-data-$(PKG_DATA_VERSION)
PKG_DATA_FILENAME:=$(PKG_DATA_PATH).tar.bz2
define Download/data
FILE:=$(PKG_DATA_FILENAME)
URL:=$(PKG_DATA_URL)
- HASH:=90549f589835a68279369c3dc0d47eb7338ee3bad09d737e7b85e1ab15bd2d8b
+ HASH:=e2dcfd9d28928d8d8f03381571a23442b3c50d48d343bc40a1a07d01662738d1
endef
$(eval $(call Download,data))
include $(TOPDIR)/rules.mk
PKG_NAME:=util-linux
-PKG_VERSION:=2.28
+PKG_VERSION:=2.29.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_SOURCE_URL:=@KERNEL/linux/utils/$(PKG_NAME)/v2.28
-PKG_HASH:=395847e2a18a2c317170f238892751e73a57104565344f8644090c8b091014bb
+PKG_SOURCE_URL:=@KERNEL/linux/utils/$(PKG_NAME)/v2.29
+PKG_HASH:=accea4d678209f97f634f40a93b7e9fcad5915d1f4749f6c47bee6bf110fe8e3
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:= COPYING \
libuuid/COPYING \
Documentation/licenses/COPYING.BSD-3
-PKG_BUILD_PARALLEL:=0
-
-PKG_CONFIG_DEPENDS:= \
- CONFIG_PACKAGE_cal \
- CONFIG_PACKAGE_cfdisk \
- CONFIG_PACKAGE_setterm
+PKG_BUILD_PARALLEL:=1
PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
--without-python \
--without-udev \
--without-readline \
- $(if $(CONFIG_PACKAGE_cal)$(CONFIG_PACKAGE_cfdisk)$(CONFIG_PACKAGE_setterm),--with-ncurses,--without-ncurses)
+ --disable-more \
+ --with-ncursesw
TARGET_CFLAGS += $(FPIC) -std=gnu99
+++ /dev/null
-From 180c908e2e80552b19bf3552667fc197d6edf7b3 Mon Sep 17 00:00:00 2001
-From: Waldemar Brodkorb <wbx@uclibc-ng.org>
-Date: Fri, 3 Jun 2016 04:13:08 +0200
-Subject: [PATCH] fix uClibc-ng scanf check
-
-uClibc-ng tries to be compatible with GNU libc and defines
-__GLIBC__ and pretend to be version 2.2.
-We once changed it to 2.10, but then some hard to fix problems
-in different software packages (gcc) occured.
-It would be better if we disable the special GNU libc checks
-for uClibc-ng here. uClibc-ng implements the required scanf
-functionality.
-
-Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>
----
- configure.ac | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/configure.ac b/configure.ac
-index f36b18c..4661c0d 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -581,7 +581,7 @@ AC_CACHE_VAL([scanf_cv_alloc_modifier],
- #include <stdio.h>
- #include <unistd.h>
-
-- #ifdef __GLIBC__
-+ #if defined(__GLIBC__) && !defined(__UCLIBC__)
-
- #if !(__GLIBC_PREREQ(2, 7))
- #error %m is not available
---
-2.1.4
-
--- /dev/null
+From feda4342df1ced25df3d200ed23469e740196c86 Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Wed, 18 Jan 2017 13:17:21 +0100
+Subject: build-sys: use -lm for scriptreplay if necessary
+
+Reported-by: Bert van Hall <bert.vanhall@avionic-design.de>
+Addresses: https://github.com/karelzak/util-linux/pull/397
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+ configure.ac | 7 +++++++
+ term-utils/Makemodule.am | 2 +-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+--- a/term-utils/Makemodule.am
++++ b/term-utils/Makemodule.am
+@@ -21,7 +21,7 @@ if BUILD_SCRIPTREPLAY
+ usrbin_exec_PROGRAMS += scriptreplay
+ dist_man_MANS += term-utils/scriptreplay.1
+ scriptreplay_SOURCES = term-utils/scriptreplay.c
+-scriptreplay_LDADD = $(LDADD) libcommon.la
++scriptreplay_LDADD = $(LDADD) libcommon.la $(MATH_LIBS)
+ endif # BUILD_SCRIPTREPLAY
+
+
endif # BUILD_LIBUUID
--- a/configure.ac
+++ b/configure.ac
-@@ -2122,18 +2122,23 @@ AC_CONFIG_HEADERS([config.h])
+@@ -2165,18 +2165,23 @@ AC_CONFIG_HEADERS([config.h])
#
AC_CONFIG_FILES([
Makefile
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 15 May 2016 13:09:20 +0200
-Subject: [PATCH] MIPS: ath79: fix regression in PCI window initialization
-
-ath79_ddr_pci_win_base has the type void __iomem *, so register offsets
-need to be a multiple of 4.
-
-Cc: Alban Bedel <albeu@free.fr>
-Fixes: 24b0e3e84fbf ("MIPS: ath79: Improve the DDR controller interface")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/mips/ath79/common.c
-+++ b/arch/mips/ath79/common.c
-@@ -76,14 +76,14 @@ void ath79_ddr_set_pci_windows(void)
- {
- BUG_ON(!ath79_ddr_pci_win_base);
-
-- __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0);
-- __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 1);
-- __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 2);
-- __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 3);
-- __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 4);
-- __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 5);
-- __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 6);
-- __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 7);
-+ __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0x0);
-+ __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 0x4);
-+ __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 0x8);
-+ __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 0xc);
-+ __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 0x10);
-+ __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 0x14);
-+ __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 0x18);
-+ __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 0x1c);
- }
- EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows);
-
} while (word != stop);
return csum_fold(csum);
-@@ -212,73 +216,6 @@ static inline __sum16 ip_compute_csum(co
+@@ -214,73 +218,6 @@ static inline __sum16 ip_compute_csum(co
return csum_fold(csum_partial(buff, len, 0));
}
#include <linux/uaccess.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
-@@ -779,10 +780,10 @@ static void tcp_v6_send_response(const s
+@@ -786,10 +787,10 @@ static void tcp_v6_send_response(const s
topt = (__be32 *)(t1 + 1);
if (tsecr) {
*/
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
-@@ -429,7 +429,7 @@ int ipv6_recv_error(struct sock *sk, str
+@@ -433,7 +433,7 @@ int ipv6_recv_error(struct sock *sk, str
ipv6_iface_scope_id(&sin->sin6_addr,
IP6CB(skb)->iif);
} else {
&sin->sin6_addr);
sin->sin6_scope_id = 0;
}
-@@ -766,12 +766,12 @@ int ip6_datagram_send_ctl(struct net *ne
+@@ -770,12 +770,12 @@ int ip6_datagram_send_ctl(struct net *ne
}
if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
-@@ -1407,7 +1407,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
+@@ -1409,7 +1409,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
dsfield = ipv6_get_dsfield(ipv6h);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
goto next_ht;
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
-@@ -222,7 +222,7 @@ static struct sk_buff **ipv6_gro_receive
+@@ -225,7 +225,7 @@ static struct sk_buff **ipv6_gro_receive
continue;
iph2 = (struct ipv6hdr *)(p->data + off);
* XXX skbs on the gro_list have all been parsed and pulled
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
-@@ -43,7 +43,7 @@ struct prefix_info {
+@@ -45,7 +45,7 @@ struct prefix_info {
__be32 reserved2;
struct in6_addr prefix;
if (xb)
return i * 32 + 31 - __fls(ntohl(xb));
}
-@@ -799,17 +803,18 @@ static inline int ip6_default_np_autolab
+@@ -804,17 +808,18 @@ static inline int ip6_default_np_autolab
static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
__be32 flowlabel)
{
---
--- a/include/linux/module.h
+++ b/include/linux/module.h
-@@ -84,9 +84,10 @@ void trim_init_extable(struct module *m)
+@@ -84,6 +84,7 @@ void trim_init_extable(struct module *m)
/* Generic info of form tag = "info" */
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info)
/* For userspace: you can also call me... */
--#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
-+#define MODULE_ALIAS(_alias) MODULE_INFO_STRIP(alias, _alias)
-
- /* Soft module dependencies. See man modprobe.d for details.
- * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz")
+ #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
@@ -127,12 +128,12 @@ void trim_init_extable(struct module *m)
* Author(s), use "Name <email>" or just "Name", for multiple
* authors use multiple MODULE_AUTHOR() statements/lines.
+++ /dev/null
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -668,11 +668,36 @@ static int bcma_device_uevent(struct dev
- core->id.rev, core->id.class);
- }
-
--static int __init bcma_modinit(void)
-+static unsigned int bcma_bus_registered;
-+
-+/*
-+ * If built-in, bus has to be registered early, before any driver calls
-+ * bcma_driver_register.
-+ * Otherwise registering driver would trigger BUG in driver_register.
-+ */
-+static int __init bcma_init_bus_register(void)
- {
- int err;
-
-+ if (bcma_bus_registered)
-+ return 0;
-+
- err = bus_register(&bcma_bus_type);
-+ if (!err)
-+ bcma_bus_registered = 1;
-+
-+ return err;
-+}
-+#ifndef MODULE
-+fs_initcall(bcma_init_bus_register);
-+#endif
-+
-+/* Main initialization has to be done with SPI/mtd/NAND/SPROM available */
-+static int __init bcma_modinit(void)
-+{
-+ int err;
-+
-+ err = bcma_init_bus_register();
- if (err)
- return err;
-
-@@ -691,7 +716,7 @@ static int __init bcma_modinit(void)
-
- return err;
- }
--fs_initcall(bcma_modinit);
-+module_init(bcma_modinit);
-
- static void __exit bcma_modexit(void)
- {
+++ /dev/null
---- a/drivers/bcma/driver_chipcommon.c
-+++ b/drivers/bcma/driver_chipcommon.c
-@@ -15,6 +15,8 @@
- #include <linux/platform_device.h>
- #include <linux/bcma/bcma.h>
-
-+static void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
-+
- static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
- u32 mask, u32 value)
- {
-@@ -113,8 +115,37 @@ int bcma_chipco_watchdog_register(struct
- return 0;
- }
-
-+static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc)
-+{
-+ struct bcma_bus *bus = cc->core->bus;
-+
-+ switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
-+ case BCMA_CC_FLASHT_STSER:
-+ case BCMA_CC_FLASHT_ATSER:
-+ bcma_debug(bus, "Found serial flash\n");
-+ bcma_sflash_init(cc);
-+ break;
-+ case BCMA_CC_FLASHT_PARA:
-+ bcma_debug(bus, "Found parallel flash\n");
-+ bcma_pflash_init(cc);
-+ break;
-+ default:
-+ bcma_err(bus, "Flash type not supported\n");
-+ }
-+
-+ if (cc->core->id.rev == 38 ||
-+ bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
-+ if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
-+ bcma_debug(bus, "Found NAND flash\n");
-+ bcma_nflash_init(cc);
-+ }
-+ }
-+}
-+
- void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
- {
-+ struct bcma_bus *bus = cc->core->bus;
-+
- if (cc->early_setup_done)
- return;
-
-@@ -129,6 +160,12 @@ void bcma_core_chipcommon_early_init(str
- if (cc->capabilities & BCMA_CC_CAP_PMU)
- bcma_pmu_early_init(cc);
-
-+ if (IS_BUILTIN(CONFIG_BCM47XX) && bus->hosttype == BCMA_HOSTTYPE_SOC)
-+ bcma_chipco_serial_init(cc);
-+
-+ if (bus->hosttype == BCMA_HOSTTYPE_SOC)
-+ bcma_core_chipcommon_flash_detect(cc);
-+
- cc->early_setup_done = true;
- }
-
-@@ -185,11 +222,12 @@ u32 bcma_chipco_watchdog_timer_set(struc
- ticks = 2;
- else if (ticks > maxt)
- ticks = maxt;
-- bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
- } else {
- struct bcma_bus *bus = cc->core->bus;
-
- if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 &&
-+ bus->chipinfo.id != BCMA_CHIP_ID_BCM47094 &&
- bus->chipinfo.id != BCMA_CHIP_ID_BCM53018)
- bcma_core_set_clockmode(cc->core,
- ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC);
-@@ -314,9 +352,9 @@ u32 bcma_chipco_gpio_pulldown(struct bcm
- return res;
- }
-
--#ifdef CONFIG_BCMA_DRIVER_MIPS
--void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
-+static void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
- {
-+#if IS_BUILTIN(CONFIG_BCM47XX)
- unsigned int irq;
- u32 baud_base;
- u32 i;
-@@ -358,5 +396,5 @@ void bcma_chipco_serial_init(struct bcma
- ports[i].baud_base = baud_base;
- ports[i].reg_shift = 0;
- }
-+#endif /* CONFIG_BCM47XX */
- }
--#endif /* CONFIG_BCMA_DRIVER_MIPS */
---- a/drivers/bcma/driver_chipcommon_pmu.c
-+++ b/drivers/bcma/driver_chipcommon_pmu.c
-@@ -15,44 +15,44 @@
-
- u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
- {
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
-- bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
-- return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
-+ bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR);
-+ return bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA);
- }
- EXPORT_SYMBOL_GPL(bcma_chipco_pll_read);
-
- void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
- {
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
-- bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
-+ bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value);
- }
- EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
-
- void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
- u32 set)
- {
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
-- bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
-- bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
-+ bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR);
-+ bcma_pmu_maskset32(cc, BCMA_CC_PMU_PLLCTL_DATA, mask, set);
- }
- EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
-
- void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
- u32 offset, u32 mask, u32 set)
- {
-- bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
-- bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
-- bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_CHIPCTL_ADDR, offset);
-+ bcma_pmu_read32(cc, BCMA_CC_PMU_CHIPCTL_ADDR);
-+ bcma_pmu_maskset32(cc, BCMA_CC_PMU_CHIPCTL_DATA, mask, set);
- }
- EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
-
- void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
- u32 set)
- {
-- bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
-- bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
-- bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_REGCTL_ADDR, offset);
-+ bcma_pmu_read32(cc, BCMA_CC_PMU_REGCTL_ADDR);
-+ bcma_pmu_maskset32(cc, BCMA_CC_PMU_REGCTL_DATA, mask, set);
- }
- EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
-
-@@ -60,18 +60,18 @@ static u32 bcma_pmu_xtalfreq(struct bcma
- {
- u32 ilp_ctl, alp_hz;
-
-- if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
-+ if (!(bcma_pmu_read32(cc, BCMA_CC_PMU_STAT) &
- BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
- return 0;
-
-- bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
-- BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
-+ BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
- usleep_range(1000, 2000);
-
-- ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
-+ ilp_ctl = bcma_pmu_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
- ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
-
-- bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
-
- alp_hz = ilp_ctl * 32768 / 4;
- return (alp_hz + 50000) / 100000 * 100;
-@@ -127,8 +127,8 @@ static void bcma_pmu2_pll_init0(struct b
- mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
- BCMA_RES_4314_MACPHY_CLK_AVAIL);
-
-- bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
-- bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
-+ bcma_pmu_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
-+ bcma_pmu_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
- bcma_wait_value(cc->core, BCMA_CLKCTLST,
- BCMA_CLKCTLST_HAVEHT, 0, 20000);
- break;
-@@ -140,7 +140,7 @@ static void bcma_pmu2_pll_init0(struct b
-
- /* Flush */
- if (cc->pmu.rev >= 2)
-- bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
-+ bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
-
- /* TODO: Do we need to update OTP? */
- }
-@@ -195,9 +195,9 @@ static void bcma_pmu_resources_init(stru
-
- /* Set the resource masks. */
- if (min_msk)
-- bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
- if (max_msk)
-- bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
-
- /*
- * Add some delay; allow resources to come up and settle.
-@@ -269,23 +269,33 @@ static void bcma_pmu_workarounds(struct
-
- void bcma_pmu_early_init(struct bcma_drv_cc *cc)
- {
-+ struct bcma_bus *bus = cc->core->bus;
- u32 pmucap;
-
-- pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
-+ if (cc->core->id.rev >= 35 &&
-+ cc->capabilities_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) {
-+ cc->pmu.core = bcma_find_core(bus, BCMA_CORE_PMU);
-+ if (!cc->pmu.core)
-+ bcma_warn(bus, "Couldn't find expected PMU core");
-+ }
-+ if (!cc->pmu.core)
-+ cc->pmu.core = cc->core;
-+
-+ pmucap = bcma_pmu_read32(cc, BCMA_CC_PMU_CAP);
- cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
-
-- bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n",
-- cc->pmu.rev, pmucap);
-+ bcma_debug(bus, "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
-+ pmucap);
- }
-
- void bcma_pmu_init(struct bcma_drv_cc *cc)
- {
- if (cc->pmu.rev == 1)
-- bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
-- ~BCMA_CC_PMU_CTL_NOILPONW);
-+ bcma_pmu_mask32(cc, BCMA_CC_PMU_CTL,
-+ ~BCMA_CC_PMU_CTL_NOILPONW);
- else
-- bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
-- BCMA_CC_PMU_CTL_NOILPONW);
-+ bcma_pmu_set32(cc, BCMA_CC_PMU_CTL,
-+ BCMA_CC_PMU_CTL_NOILPONW);
-
- bcma_pmu_pll_init(cc);
- bcma_pmu_resources_init(cc);
-@@ -472,8 +482,8 @@ u32 bcma_pmu_get_cpu_clock(struct bcma_d
- static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset,
- u32 value)
- {
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value);
- }
-
- void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
-@@ -497,20 +507,20 @@ void bcma_pmu_spuravoid_pllupdate(struct
- bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0;
-
- /* RMW only the P1 divider */
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR,
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR,
- BCMA_CC_PMU_PLL_CTL0 + phypll_offset);
-- tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
-+ tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA);
- tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK));
- tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT);
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp);
-
- /* RMW only the int feedback divider */
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR,
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR,
- BCMA_CC_PMU_PLL_CTL2 + phypll_offset);
-- tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
-+ tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA);
- tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK);
- tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT;
-- bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp);
-
- tmp = BCMA_CC_PMU_CTL_PLL_UPD;
- break;
-@@ -646,7 +656,7 @@ void bcma_pmu_spuravoid_pllupdate(struct
- break;
- }
-
-- tmp |= bcma_cc_read32(cc, BCMA_CC_PMU_CTL);
-- bcma_cc_write32(cc, BCMA_CC_PMU_CTL, tmp);
-+ tmp |= bcma_pmu_read32(cc, BCMA_CC_PMU_CTL);
-+ bcma_pmu_write32(cc, BCMA_CC_PMU_CTL, tmp);
- }
- EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate);
---- a/drivers/bcma/driver_chipcommon_sflash.c
-+++ b/drivers/bcma/driver_chipcommon_sflash.c
-@@ -38,6 +38,7 @@ static const struct bcma_sflash_tbl_e bc
- { "M25P32", 0x15, 0x10000, 64, },
- { "M25P64", 0x16, 0x10000, 128, },
- { "M25FL128", 0x17, 0x10000, 256, },
-+ { "MX25L25635F", 0x18, 0x10000, 512, },
- { NULL },
- };
-
---- a/drivers/bcma/scan.c
-+++ b/drivers/bcma/scan.c
-@@ -98,6 +98,9 @@ static const struct bcma_device_id_name
- { BCMA_CORE_SHIM, "SHIM" },
- { BCMA_CORE_PCIE2, "PCIe Gen2" },
- { BCMA_CORE_ARM_CR4, "ARM CR4" },
-+ { BCMA_CORE_GCI, "GCI" },
-+ { BCMA_CORE_CMEM, "CNDS DDR2/3 memory controller" },
-+ { BCMA_CORE_ARM_CA7, "ARM CA7" },
- { BCMA_CORE_DEFAULT, "Default" },
- };
-
-@@ -315,6 +318,8 @@ static int bcma_get_next_core(struct bcm
- switch (core->id.id) {
- case BCMA_CORE_4706_MAC_GBIT_COMMON:
- case BCMA_CORE_NS_CHIPCOMMON_B:
-+ case BCMA_CORE_PMU:
-+ case BCMA_CORE_GCI:
- /* Not used yet: case BCMA_CORE_OOB_ROUTER: */
- break;
- default:
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -1215,10 +1215,10 @@ void b43_wireless_core_phy_pll_reset(str
- case B43_BUS_BCMA:
- bcma_cc = &dev->dev->bdev->bus->drv_cc;
-
-- bcma_cc_write32(bcma_cc, BCMA_CC_CHIPCTL_ADDR, 0);
-- bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4);
-- bcma_cc_set32(bcma_cc, BCMA_CC_CHIPCTL_DATA, 0x4);
-- bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4);
-+ bcma_cc_write32(bcma_cc, BCMA_CC_PMU_CHIPCTL_ADDR, 0);
-+ bcma_cc_mask32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, ~0x4);
-+ bcma_cc_set32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, 0x4);
-+ bcma_cc_mask32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, ~0x4);
- break;
- #endif
- #ifdef CONFIG_B43_SSB
---- a/include/linux/bcma/bcma.h
-+++ b/include/linux/bcma/bcma.h
-@@ -151,6 +151,8 @@ struct bcma_host_ops {
- #define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */
- #define BCMA_CORE_USB30_DEV 0x83D
- #define BCMA_CORE_ARM_CR4 0x83E
-+#define BCMA_CORE_GCI 0x840
-+#define BCMA_CORE_CMEM 0x846 /* CNDS DDR2/3 memory controller */
- #define BCMA_CORE_ARM_CA7 0x847
- #define BCMA_CORE_SYS_MEM 0x849
- #define BCMA_CORE_DEFAULT 0xFFF
-@@ -200,6 +202,7 @@ struct bcma_host_ops {
- #define BCMA_PKG_ID_BCM4707 1
- #define BCMA_PKG_ID_BCM4708 2
- #define BCMA_PKG_ID_BCM4709 0
-+#define BCMA_CHIP_ID_BCM47094 53030
- #define BCMA_CHIP_ID_BCM53018 53018
-
- /* Board types (on PCI usually equals to the subsystem dev id) */
---- a/include/linux/bcma/bcma_driver_chipcommon.h
-+++ b/include/linux/bcma/bcma_driver_chipcommon.h
-@@ -217,6 +217,11 @@
- #define BCMA_CC_CLKDIV_JTAG_SHIFT 8
- #define BCMA_CC_CLKDIV_UART 0x000000FF
- #define BCMA_CC_CAP_EXT 0x00AC /* Capabilities */
-+#define BCMA_CC_CAP_EXT_SECI_PRESENT 0x00000001
-+#define BCMA_CC_CAP_EXT_GSIO_PRESENT 0x00000002
-+#define BCMA_CC_CAP_EXT_GCI_PRESENT 0x00000004
-+#define BCMA_CC_CAP_EXT_SECI_PUART_PRESENT 0x00000008 /* UART present */
-+#define BCMA_CC_CAP_EXT_AOB_PRESENT 0x00000040
- #define BCMA_CC_PLLONDELAY 0x00B0 /* Rev >= 4 only */
- #define BCMA_CC_FREFSELDELAY 0x00B4 /* Rev >= 4 only */
- #define BCMA_CC_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */
-@@ -351,12 +356,12 @@
- #define BCMA_CC_PMU_RES_REQTS 0x0640 /* PMU res req timer sel */
- #define BCMA_CC_PMU_RES_REQT 0x0644 /* PMU res req timer */
- #define BCMA_CC_PMU_RES_REQM 0x0648 /* PMU res req mask */
--#define BCMA_CC_CHIPCTL_ADDR 0x0650
--#define BCMA_CC_CHIPCTL_DATA 0x0654
--#define BCMA_CC_REGCTL_ADDR 0x0658
--#define BCMA_CC_REGCTL_DATA 0x065C
--#define BCMA_CC_PLLCTL_ADDR 0x0660
--#define BCMA_CC_PLLCTL_DATA 0x0664
-+#define BCMA_CC_PMU_CHIPCTL_ADDR 0x0650
-+#define BCMA_CC_PMU_CHIPCTL_DATA 0x0654
-+#define BCMA_CC_PMU_REGCTL_ADDR 0x0658
-+#define BCMA_CC_PMU_REGCTL_DATA 0x065C
-+#define BCMA_CC_PMU_PLLCTL_ADDR 0x0660
-+#define BCMA_CC_PMU_PLLCTL_DATA 0x0664
- #define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */
- #define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */
- #define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF
-@@ -566,17 +571,16 @@
- * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
- */
- struct bcma_chipcommon_pmu {
-+ struct bcma_device *core; /* Can be separated core or just ChipCommon one */
- u8 rev; /* PMU revision */
- u32 crystalfreq; /* The active crystal frequency (in kHz) */
- };
-
--#ifdef CONFIG_BCMA_DRIVER_MIPS
-+#ifdef CONFIG_BCMA_PFLASH
- struct bcma_pflash {
- bool present;
-- u8 buswidth;
-- u32 window;
-- u32 window_size;
- };
-+#endif
-
- #ifdef CONFIG_BCMA_SFLASH
- struct bcma_sflash {
-@@ -602,6 +606,7 @@ struct bcma_nflash {
- };
- #endif
-
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
- struct bcma_serial_port {
- void *regs;
- unsigned long clockspeed;
-@@ -621,8 +626,9 @@ struct bcma_drv_cc {
- /* Fast Powerup Delay constant */
- u16 fast_pwrup_delay;
- struct bcma_chipcommon_pmu pmu;
--#ifdef CONFIG_BCMA_DRIVER_MIPS
-+#ifdef CONFIG_BCMA_PFLASH
- struct bcma_pflash pflash;
-+#endif
- #ifdef CONFIG_BCMA_SFLASH
- struct bcma_sflash sflash;
- #endif
-@@ -630,6 +636,7 @@ struct bcma_drv_cc {
- struct bcma_nflash nflash;
- #endif
-
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
- int nr_serial_ports;
- struct bcma_serial_port serial_ports[4];
- #endif /* CONFIG_BCMA_DRIVER_MIPS */
-@@ -662,6 +669,19 @@ struct bcma_drv_cc_b {
- #define bcma_cc_maskset32(cc, offset, mask, set) \
- bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
-
-+/* PMU registers access */
-+#define bcma_pmu_read32(cc, offset) \
-+ bcma_read32((cc)->pmu.core, offset)
-+#define bcma_pmu_write32(cc, offset, val) \
-+ bcma_write32((cc)->pmu.core, offset, val)
-+
-+#define bcma_pmu_mask32(cc, offset, mask) \
-+ bcma_pmu_write32(cc, offset, bcma_pmu_read32(cc, offset) & (mask))
-+#define bcma_pmu_set32(cc, offset, set) \
-+ bcma_pmu_write32(cc, offset, bcma_pmu_read32(cc, offset) | (set))
-+#define bcma_pmu_maskset32(cc, offset, mask, set) \
-+ bcma_pmu_write32(cc, offset, (bcma_pmu_read32(cc, offset) & (mask)) | (set))
-+
- extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks);
-
- extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc);
---- a/drivers/bcma/bcma_private.h
-+++ b/drivers/bcma/bcma_private.h
-@@ -45,10 +45,6 @@ int bcma_sprom_get(struct bcma_bus *bus)
- void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc);
- void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
- void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
--#ifdef CONFIG_BCMA_DRIVER_MIPS
--void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
--extern struct platform_device bcma_pflash_dev;
--#endif /* CONFIG_BCMA_DRIVER_MIPS */
-
- /* driver_chipcommon_b.c */
- int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb);
-@@ -60,6 +56,21 @@ void bcma_pmu_init(struct bcma_drv_cc *c
- u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
- u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
-
-+/**************************************************
-+ * driver_chipcommon_sflash.c
-+ **************************************************/
-+
-+#ifdef CONFIG_BCMA_PFLASH
-+extern struct platform_device bcma_pflash_dev;
-+int bcma_pflash_init(struct bcma_drv_cc *cc);
-+#else
-+static inline int bcma_pflash_init(struct bcma_drv_cc *cc)
-+{
-+ bcma_err(cc->core->bus, "Parallel flash not supported\n");
-+ return 0;
-+}
-+#endif /* CONFIG_BCMA_PFLASH */
-+
- #ifdef CONFIG_BCMA_SFLASH
- /* driver_chipcommon_sflash.c */
- int bcma_sflash_init(struct bcma_drv_cc *cc);
---- a/drivers/bcma/driver_gpio.c
-+++ b/drivers/bcma/driver_gpio.c
-@@ -197,6 +197,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
- case BCMA_CHIP_ID_BCM4707:
- case BCMA_CHIP_ID_BCM5357:
- case BCMA_CHIP_ID_BCM53572:
-+ case BCMA_CHIP_ID_BCM47094:
- chip->ngpio = 32;
- break;
- default:
---- a/drivers/bcma/driver_mips.c
-+++ b/drivers/bcma/driver_mips.c
-@@ -14,8 +14,6 @@
-
- #include <linux/bcma/bcma.h>
-
--#include <linux/mtd/physmap.h>
--#include <linux/platform_device.h>
- #include <linux/serial.h>
- #include <linux/serial_core.h>
- #include <linux/serial_reg.h>
-@@ -32,26 +30,6 @@ enum bcma_boot_dev {
- BCMA_BOOT_DEV_NAND,
- };
-
--static const char * const part_probes[] = { "bcm47xxpart", NULL };
--
--static struct physmap_flash_data bcma_pflash_data = {
-- .part_probe_types = part_probes,
--};
--
--static struct resource bcma_pflash_resource = {
-- .name = "bcma_pflash",
-- .flags = IORESOURCE_MEM,
--};
--
--struct platform_device bcma_pflash_dev = {
-- .name = "physmap-flash",
-- .dev = {
-- .platform_data = &bcma_pflash_data,
-- },
-- .resource = &bcma_pflash_resource,
-- .num_resources = 1,
--};
--
- /* The 47162a0 hangs when reading MIPS DMP registers registers */
- static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
- {
-@@ -272,48 +250,11 @@ static enum bcma_boot_dev bcma_boot_dev(
- return BCMA_BOOT_DEV_SERIAL;
- }
-
--static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
-+static void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore)
- {
- struct bcma_bus *bus = mcore->core->bus;
-- struct bcma_drv_cc *cc = &bus->drv_cc;
-- struct bcma_pflash *pflash = &cc->pflash;
- enum bcma_boot_dev boot_dev;
-
-- switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
-- case BCMA_CC_FLASHT_STSER:
-- case BCMA_CC_FLASHT_ATSER:
-- bcma_debug(bus, "Found serial flash\n");
-- bcma_sflash_init(cc);
-- break;
-- case BCMA_CC_FLASHT_PARA:
-- bcma_debug(bus, "Found parallel flash\n");
-- pflash->present = true;
-- pflash->window = BCMA_SOC_FLASH2;
-- pflash->window_size = BCMA_SOC_FLASH2_SZ;
--
-- if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) &
-- BCMA_CC_FLASH_CFG_DS) == 0)
-- pflash->buswidth = 1;
-- else
-- pflash->buswidth = 2;
--
-- bcma_pflash_data.width = pflash->buswidth;
-- bcma_pflash_resource.start = pflash->window;
-- bcma_pflash_resource.end = pflash->window + pflash->window_size;
--
-- break;
-- default:
-- bcma_err(bus, "Flash type not supported\n");
-- }
--
-- if (cc->core->id.rev == 38 ||
-- bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
-- if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
-- bcma_debug(bus, "Found NAND flash\n");
-- bcma_nflash_init(cc);
-- }
-- }
--
- /* Determine flash type this SoC boots from */
- boot_dev = bcma_boot_dev(bus);
- switch (boot_dev) {
-@@ -337,13 +278,10 @@ static void bcma_core_mips_flash_detect(
-
- void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
- {
-- struct bcma_bus *bus = mcore->core->bus;
--
- if (mcore->early_setup_done)
- return;
-
-- bcma_chipco_serial_init(&bus->drv_cc);
-- bcma_core_mips_flash_detect(mcore);
-+ bcma_core_mips_nvram_init(mcore);
-
- mcore->early_setup_done = true;
- }
---- a/drivers/bcma/host_pci.c
-+++ b/drivers/bcma/host_pci.c
-@@ -294,7 +294,8 @@ static const struct pci_device_id bcma_p
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) },
-- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
-+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) },
-+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_FOXCONN, 0xe092) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
- { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -70,6 +70,11 @@ config BCMA_DRIVER_MIPS
-
- If unsure, say N
-
-+config BCMA_PFLASH
-+ bool
-+ depends on BCMA_DRIVER_MIPS
-+ default y
-+
- config BCMA_SFLASH
- bool
- depends on BCMA_DRIVER_MIPS
---- a/drivers/bcma/Makefile
-+++ b/drivers/bcma/Makefile
-@@ -1,6 +1,7 @@
- bcma-y += main.o scan.o core.o sprom.o
- bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
- bcma-y += driver_chipcommon_b.o
-+bcma-$(CONFIG_BCMA_PFLASH) += driver_chipcommon_pflash.o
- bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o
- bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o
- bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o
---- /dev/null
-+++ b/drivers/bcma/driver_chipcommon_pflash.c
-@@ -0,0 +1,49 @@
-+/*
-+ * Broadcom specific AMBA
-+ * ChipCommon parallel flash
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+
-+#include <linux/bcma/bcma.h>
-+#include <linux/mtd/physmap.h>
-+#include <linux/platform_device.h>
-+
-+static const char * const part_probes[] = { "bcm47xxpart", NULL };
-+
-+static struct physmap_flash_data bcma_pflash_data = {
-+ .part_probe_types = part_probes,
-+};
-+
-+static struct resource bcma_pflash_resource = {
-+ .name = "bcma_pflash",
-+ .flags = IORESOURCE_MEM,
-+};
-+
-+struct platform_device bcma_pflash_dev = {
-+ .name = "physmap-flash",
-+ .dev = {
-+ .platform_data = &bcma_pflash_data,
-+ },
-+ .resource = &bcma_pflash_resource,
-+ .num_resources = 1,
-+};
-+
-+int bcma_pflash_init(struct bcma_drv_cc *cc)
-+{
-+ struct bcma_pflash *pflash = &cc->pflash;
-+
-+ pflash->present = true;
-+
-+ if (!(bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & BCMA_CC_FLASH_CFG_DS))
-+ bcma_pflash_data.width = 1;
-+ else
-+ bcma_pflash_data.width = 2;
-+
-+ bcma_pflash_resource.start = BCMA_SOC_FLASH2;
-+ bcma_pflash_resource.end = BCMA_SOC_FLASH2 + BCMA_SOC_FLASH2_SZ;
-+
-+ return 0;
-+}
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -136,7 +136,6 @@ static bool bcma_is_core_needed_early(u1
- return false;
- }
-
--#if defined(CONFIG_OF) && defined(CONFIG_OF_ADDRESS)
- static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
- struct bcma_device *core)
- {
-@@ -184,7 +183,7 @@ static unsigned int bcma_of_get_irq(stru
- struct of_phandle_args out_irq;
- int ret;
-
-- if (!parent || !parent->dev.of_node)
-+ if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent || !parent->dev.of_node)
- return 0;
-
- ret = bcma_of_irq_parse(parent, core, &out_irq, num);
-@@ -202,23 +201,15 @@ static void bcma_of_fill_device(struct p
- {
- struct device_node *node;
-
-+ if (!IS_ENABLED(CONFIG_OF_IRQ))
-+ return;
-+
- node = bcma_of_find_child_device(parent, core);
- if (node)
- core->dev.of_node = node;
-
- core->irq = bcma_of_get_irq(parent, core, 0);
- }
--#else
--static void bcma_of_fill_device(struct platform_device *parent,
-- struct bcma_device *core)
--{
--}
--static inline unsigned int bcma_of_get_irq(struct platform_device *parent,
-- struct bcma_device *core, int num)
--{
-- return 0;
--}
--#endif /* CONFIG_OF */
-
- unsigned int bcma_core_irq(struct bcma_device *core, int num)
- {
-@@ -350,7 +341,7 @@ static int bcma_register_devices(struct
- bcma_register_core(bus, core);
- }
-
--#ifdef CONFIG_BCMA_DRIVER_MIPS
-+#ifdef CONFIG_BCMA_PFLASH
- if (bus->drv_cc.pflash.present) {
- err = platform_device_register(&bcma_pflash_dev);
- if (err)
+++ /dev/null
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -76,9 +76,16 @@ config BCMA_PFLASH
- default y
-
- config BCMA_SFLASH
-- bool
-- depends on BCMA_DRIVER_MIPS
-+ bool "ChipCommon-attached serial flash support"
-+ depends on BCMA_HOST_SOC
- default y
-+ help
-+ Some cheap devices have serial flash connected to the ChipCommon
-+ instead of independent SPI controller. It requires using a separated
-+ driver that implements ChipCommon specific interface communication.
-+
-+ Enabling this symbol will let bcma recognize serial flash and register
-+ it as platform device.
-
- config BCMA_NFLASH
- bool
---- a/drivers/bcma/driver_chipcommon_b.c
-+++ b/drivers/bcma/driver_chipcommon_b.c
-@@ -33,11 +33,12 @@ static bool bcma_wait_reg(struct bcma_bu
- void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value)
- {
- struct bcma_bus *bus = ccb->core->bus;
-+ void __iomem *mii = ccb->mii;
-
-- writel(offset, ccb->mii + 0x00);
-- bcma_wait_reg(bus, ccb->mii + 0x00, 0x0100, 0x0000, 100);
-- writel(value, ccb->mii + 0x04);
-- bcma_wait_reg(bus, ccb->mii + 0x00, 0x0100, 0x0000, 100);
-+ writel(offset, mii + BCMA_CCB_MII_MNG_CTL);
-+ bcma_wait_reg(bus, mii + BCMA_CCB_MII_MNG_CTL, 0x0100, 0x0000, 100);
-+ writel(value, mii + BCMA_CCB_MII_MNG_CMD_DATA);
-+ bcma_wait_reg(bus, mii + BCMA_CCB_MII_MNG_CTL, 0x0100, 0x0000, 100);
- }
- EXPORT_SYMBOL_GPL(bcma_chipco_b_mii_write);
-
---- a/include/linux/bcma/bcma_driver_chipcommon.h
-+++ b/include/linux/bcma/bcma_driver_chipcommon.h
-@@ -504,6 +504,9 @@
- #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000
- #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT 20
-
-+#define BCMA_CCB_MII_MNG_CTL 0x0000
-+#define BCMA_CCB_MII_MNG_CMD_DATA 0x0004
-+
- /* BCM4331 ChipControl numbers. */
- #define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
- #define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
+++ /dev/null
---- a/drivers/bcma/driver_chipcommon.c
-+++ b/drivers/bcma/driver_chipcommon.c
-@@ -36,12 +36,31 @@ u32 bcma_chipco_get_alp_clock(struct bcm
- }
- EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock);
-
-+static bool bcma_core_cc_has_pmu_watchdog(struct bcma_drv_cc *cc)
-+{
-+ struct bcma_bus *bus = cc->core->bus;
-+
-+ if (cc->capabilities & BCMA_CC_CAP_PMU) {
-+ if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573) {
-+ WARN(bus->chipinfo.rev <= 1, "No watchdog available\n");
-+ /* 53573B0 and 53573B1 have bugged PMU watchdog. It can
-+ * be enabled but timer can't be bumped. Use CC one
-+ * instead.
-+ */
-+ return false;
-+ }
-+ return true;
-+ } else {
-+ return false;
-+ }
-+}
-+
- static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
- {
- struct bcma_bus *bus = cc->core->bus;
- u32 nb;
-
-- if (cc->capabilities & BCMA_CC_CAP_PMU) {
-+ if (bcma_core_cc_has_pmu_watchdog(cc)) {
- if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
- nb = 32;
- else if (cc->core->id.rev < 26)
-@@ -95,9 +114,16 @@ static int bcma_chipco_watchdog_ticks_pe
-
- int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
- {
-+ struct bcma_bus *bus = cc->core->bus;
- struct bcm47xx_wdt wdt = {};
- struct platform_device *pdev;
-
-+ if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573 &&
-+ bus->chipinfo.rev <= 1) {
-+ pr_debug("No watchdog on 53573A0 / 53573A1\n");
-+ return 0;
-+ }
-+
- wdt.driver_data = cc;
- wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
- wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
-@@ -105,7 +131,7 @@ int bcma_chipco_watchdog_register(struct
- bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
-
- pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
-- cc->core->bus->num, &wdt,
-+ bus->num, &wdt,
- sizeof(wdt));
- if (IS_ERR(pdev))
- return PTR_ERR(pdev);
-@@ -217,7 +243,7 @@ u32 bcma_chipco_watchdog_timer_set(struc
- u32 maxt;
-
- maxt = bcma_chipco_watchdog_get_max_timer(cc);
-- if (cc->capabilities & BCMA_CC_CAP_PMU) {
-+ if (bcma_core_cc_has_pmu_watchdog(cc)) {
- if (ticks == 1)
- ticks = 2;
- else if (ticks > maxt)
---- a/include/linux/bcma/bcma.h
-+++ b/include/linux/bcma/bcma.h
-@@ -204,6 +204,9 @@ struct bcma_host_ops {
- #define BCMA_PKG_ID_BCM4709 0
- #define BCMA_CHIP_ID_BCM47094 53030
- #define BCMA_CHIP_ID_BCM53018 53018
-+#define BCMA_CHIP_ID_BCM53573 53573
-+#define BCMA_PKG_ID_BCM53573 0
-+#define BCMA_PKG_ID_BCM47189 1
-
- /* Board types (on PCI usually equals to the subsystem dev id) */
- /* BCM4313 */
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -209,6 +209,8 @@ static void bcma_of_fill_device(struct p
- core->dev.of_node = node;
-
- core->irq = bcma_of_get_irq(parent, core, 0);
-+
-+ of_dma_configure(&core->dev, node);
- }
-
- unsigned int bcma_core_irq(struct bcma_device *core, int num)
-@@ -248,12 +250,12 @@ void bcma_prepare_core(struct bcma_bus *
- core->irq = bus->host_pci->irq;
- break;
- case BCMA_HOSTTYPE_SOC:
-- core->dev.dma_mask = &core->dev.coherent_dma_mask;
-- if (bus->host_pdev) {
-+ if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
- core->dma_dev = &bus->host_pdev->dev;
- core->dev.parent = &bus->host_pdev->dev;
- bcma_of_fill_device(bus->host_pdev, core);
- } else {
-+ core->dev.dma_mask = &core->dev.coherent_dma_mask;
- core->dma_dev = &core->dev;
- }
- break;
+++ /dev/null
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -136,17 +136,17 @@ static bool bcma_is_core_needed_early(u1
- return false;
- }
-
--static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
-+static struct device_node *bcma_of_find_child_device(struct device *parent,
- struct bcma_device *core)
- {
- struct device_node *node;
- u64 size;
- const __be32 *reg;
-
-- if (!parent || !parent->dev.of_node)
-+ if (!parent->of_node)
- return NULL;
-
-- for_each_child_of_node(parent->dev.of_node, node) {
-+ for_each_child_of_node(parent->of_node, node) {
- reg = of_get_address(node, 0, &size, NULL);
- if (!reg)
- continue;
-@@ -156,7 +156,7 @@ static struct device_node *bcma_of_find_
- return NULL;
- }
-
--static int bcma_of_irq_parse(struct platform_device *parent,
-+static int bcma_of_irq_parse(struct device *parent,
- struct bcma_device *core,
- struct of_phandle_args *out_irq, int num)
- {
-@@ -169,7 +169,7 @@ static int bcma_of_irq_parse(struct plat
- return rc;
- }
-
-- out_irq->np = parent->dev.of_node;
-+ out_irq->np = parent->of_node;
- out_irq->args_count = 1;
- out_irq->args[0] = num;
-
-@@ -177,13 +177,13 @@ static int bcma_of_irq_parse(struct plat
- return of_irq_parse_raw(laddr, out_irq);
- }
-
--static unsigned int bcma_of_get_irq(struct platform_device *parent,
-+static unsigned int bcma_of_get_irq(struct device *parent,
- struct bcma_device *core, int num)
- {
- struct of_phandle_args out_irq;
- int ret;
-
-- if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent || !parent->dev.of_node)
-+ if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent->of_node)
- return 0;
-
- ret = bcma_of_irq_parse(parent, core, &out_irq, num);
-@@ -196,7 +196,7 @@ static unsigned int bcma_of_get_irq(stru
- return irq_create_of_mapping(&out_irq);
- }
-
--static void bcma_of_fill_device(struct platform_device *parent,
-+static void bcma_of_fill_device(struct device *parent,
- struct bcma_device *core)
- {
- struct device_node *node;
-@@ -227,7 +227,7 @@ unsigned int bcma_core_irq(struct bcma_d
- return mips_irq <= 4 ? mips_irq + 2 : 0;
- }
- if (bus->host_pdev)
-- return bcma_of_get_irq(bus->host_pdev, core, num);
-+ return bcma_of_get_irq(&bus->host_pdev->dev, core, num);
- return 0;
- case BCMA_HOSTTYPE_SDIO:
- return 0;
-@@ -253,7 +253,8 @@ void bcma_prepare_core(struct bcma_bus *
- if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
- core->dma_dev = &bus->host_pdev->dev;
- core->dev.parent = &bus->host_pdev->dev;
-- bcma_of_fill_device(bus->host_pdev, core);
-+ if (core->dev.parent)
-+ bcma_of_fill_device(core->dev.parent, core);
- } else {
- core->dev.dma_mask = &core->dev.coherent_dma_mask;
- core->dma_dev = &core->dev;
-@@ -633,8 +634,11 @@ static int bcma_device_probe(struct devi
- drv);
- int err = 0;
-
-+ get_device(dev);
- if (adrv->probe)
- err = adrv->probe(core);
-+ if (err)
-+ put_device(dev);
-
- return err;
- }
-@@ -647,6 +651,7 @@ static int bcma_device_remove(struct dev
-
- if (adrv->remove)
- adrv->remove(core);
-+ put_device(dev);
-
- return 0;
- }
--- /dev/null
+From e9156cd26a495a18706e796f02a81fee41ec14f4 Mon Sep 17 00:00:00 2001
+From: James Hughes <james.hughes@raspberrypi.org>
+Date: Wed, 19 Apr 2017 11:13:40 +0100
+Subject: [PATCH] smsc95xx: Use skb_cow_head to deal with cloned skbs
+
+The driver was failing to check that the SKB wasn't cloned
+before adding checksum data.
+Replace existing handling to extend/copy the header buffer
+with skb_cow_head.
+
+Signed-off-by: James Hughes <james.hughes@raspberrypi.org>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Woojung Huh <Woojung.Huh@microchip.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -1835,13 +1835,13 @@ static struct sk_buff *smsc95xx_tx_fixup
+ /* We do not advertise SG, so skbs should be already linearized */
+ BUG_ON(skb_shinfo(skb)->nr_frags);
+
+- if (skb_headroom(skb) < overhead) {
+- struct sk_buff *skb2 = skb_copy_expand(skb,
+- overhead, 0, flags);
++ /* Make writable and expand header space by overhead if required */
++ if (skb_cow_head(skb, overhead)) {
++ /* Must deallocate here as returning NULL to indicate error
++ * means the skb won't be deallocated in the caller.
++ */
+ dev_kfree_skb_any(skb);
+- skb = skb2;
+- if (!skb)
+- return NULL;
++ return NULL;
+ }
+
+ if (csum) {
--- /dev/null
+From b7c6d2675899cfff0180412c63fc9cbd5bacdb4d Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 19 Apr 2017 09:59:21 -0700
+Subject: [PATCH] smsc75xx: use skb_cow_head() to deal with cloned skbs
+
+We need to ensure there is enough headroom to push extra header,
+but we also need to check if we are allowed to change headers.
+
+skb_cow_head() is the proper helper to deal with this.
+
+Fixes: d0cad871703b ("smsc75xx: SMSC LAN75xx USB gigabit ethernet adapter driver")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Hughes <james.hughes@raspberrypi.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc75xx.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/usb/smsc75xx.c
++++ b/drivers/net/usb/smsc75xx.c
+@@ -2193,13 +2193,9 @@ static struct sk_buff *smsc75xx_tx_fixup
+ {
+ u32 tx_cmd_a, tx_cmd_b;
+
+- if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
+- struct sk_buff *skb2 =
+- skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
++ if (skb_cow_head(skb, SMSC75XX_TX_OVERHEAD)) {
+ dev_kfree_skb_any(skb);
+- skb = skb2;
+- if (!skb)
+- return NULL;
++ return NULL;
+ }
+
+ tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;
--- /dev/null
+From a9e840a2081ed28c2b7caa6a9a0041c950b3c37d Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 19 Apr 2017 09:59:22 -0700
+Subject: [PATCH] cx82310_eth: use skb_cow_head() to deal with cloned skbs
+
+We need to ensure there is enough headroom to push extra header,
+but we also need to check if we are allowed to change headers.
+
+skb_cow_head() is the proper helper to deal with this.
+
+Fixes: cc28a20e77b2 ("introduce cx82310_eth: Conexant CX82310-based ADSL router USB ethernet driver")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Hughes <james.hughes@raspberrypi.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/cx82310_eth.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/usb/cx82310_eth.c
++++ b/drivers/net/usb/cx82310_eth.c
+@@ -293,12 +293,9 @@ static struct sk_buff *cx82310_tx_fixup(
+ {
+ int len = skb->len;
+
+- if (skb_headroom(skb) < 2) {
+- struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags);
++ if (skb_cow_head(skb, 2)) {
+ dev_kfree_skb_any(skb);
+- skb = skb2;
+- if (!skb)
+- return NULL;
++ return NULL;
+ }
+ skb_push(skb, 2);
+
--- /dev/null
+From d532c1082f68176363ed766d09bf187616e282fe Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 19 Apr 2017 09:59:23 -0700
+Subject: [PATCH] sr9700: use skb_cow_head() to deal with cloned skbs
+
+We need to ensure there is enough headroom to push extra header,
+but we also need to check if we are allowed to change headers.
+
+skb_cow_head() is the proper helper to deal with this.
+
+Fixes: c9b37458e956 ("USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Hughes <james.hughes@raspberrypi.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/sr9700.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/usb/sr9700.c
++++ b/drivers/net/usb/sr9700.c
+@@ -456,14 +456,9 @@ static struct sk_buff *sr9700_tx_fixup(s
+
+ len = skb->len;
+
+- if (skb_headroom(skb) < SR_TX_OVERHEAD) {
+- struct sk_buff *skb2;
+-
+- skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags);
++ if (skb_cow_head(skb, SR_TX_OVERHEAD)) {
+ dev_kfree_skb_any(skb);
+- skb = skb2;
+- if (!skb)
+- return NULL;
++ return NULL;
+ }
+
+ __skb_push(skb, SR_TX_OVERHEAD);
--- /dev/null
+From d4ca73591916b760478d2b04334d5dcadc028e9c Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 19 Apr 2017 09:59:24 -0700
+Subject: [PATCH] lan78xx: use skb_cow_head() to deal with cloned skbs
+
+We need to ensure there is enough headroom to push extra header,
+but we also need to check if we are allowed to change headers.
+
+skb_cow_head() is the proper helper to deal with this.
+
+Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Hughes <james.hughes@raspberrypi.org>
+Cc: Woojung Huh <woojung.huh@microchip.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/lan78xx.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -2050,14 +2050,9 @@ static struct sk_buff *lan78xx_tx_prep(s
+ {
+ u32 tx_cmd_a, tx_cmd_b;
+
+- if (skb_headroom(skb) < TX_OVERHEAD) {
+- struct sk_buff *skb2;
+-
+- skb2 = skb_copy_expand(skb, TX_OVERHEAD, 0, flags);
++ if (skb_cow_head(skb, TX_OVERHEAD)) {
+ dev_kfree_skb_any(skb);
+- skb = skb2;
+- if (!skb)
+- return NULL;
++ return NULL;
+ }
+
+ if (lan78xx_linearize(skb) < 0)
--- /dev/null
+From 6bc6895bdd6744e0136eaa4a11fbdb20a7db4e40 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 19 Apr 2017 09:59:25 -0700
+Subject: [PATCH] ch9200: use skb_cow_head() to deal with cloned skbs
+
+We need to ensure there is enough headroom to push extra header,
+but we also need to check if we are allowed to change headers.
+
+skb_cow_head() is the proper helper to deal with this.
+
+Fixes: 4a476bd6d1d9 ("usbnet: New driver for QinHeng CH9200 devices")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Hughes <james.hughes@raspberrypi.org>
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/ch9200.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/usb/ch9200.c
++++ b/drivers/net/usb/ch9200.c
+@@ -255,14 +255,9 @@ static struct sk_buff *ch9200_tx_fixup(s
+ tx_overhead = 0x40;
+
+ len = skb->len;
+- if (skb_headroom(skb) < tx_overhead) {
+- struct sk_buff *skb2;
+-
+- skb2 = skb_copy_expand(skb, tx_overhead, 0, flags);
++ if (skb_cow_head(skb, tx_overhead)) {
+ dev_kfree_skb_any(skb);
+- skb = skb2;
+- if (!skb)
+- return NULL;
++ return NULL;
+ }
+
+ __skb_push(skb, tx_overhead);
--- /dev/null
+From 39fba7835aacda65284a86e611774cbba71dac20 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 19 Apr 2017 09:59:26 -0700
+Subject: [PATCH] kaweth: use skb_cow_head() to deal with cloned skbs
+
+We can use skb_cow_head() to properly deal with clones,
+especially the ones coming from TCP stack that allow their head being
+modified. This avoids a copy.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Hughes <james.hughes@raspberrypi.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/kaweth.c | 18 ++++++------------
+ 1 file changed, 6 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/usb/kaweth.c
++++ b/drivers/net/usb/kaweth.c
+@@ -812,18 +812,12 @@ static netdev_tx_t kaweth_start_xmit(str
+ }
+
+ /* We now decide whether we can put our special header into the sk_buff */
+- if (skb_cloned(skb) || skb_headroom(skb) < 2) {
+- /* no such luck - we make our own */
+- struct sk_buff *copied_skb;
+- copied_skb = skb_copy_expand(skb, 2, 0, GFP_ATOMIC);
+- dev_kfree_skb_irq(skb);
+- skb = copied_skb;
+- if (!copied_skb) {
+- kaweth->stats.tx_errors++;
+- netif_start_queue(net);
+- spin_unlock_irq(&kaweth->device_lock);
+- return NETDEV_TX_OK;
+- }
++ if (skb_cow_head(skb, 2)) {
++ kaweth->stats.tx_errors++;
++ netif_start_queue(net);
++ spin_unlock_irq(&kaweth->device_lock);
++ dev_kfree_skb_any(skb);
++ return NETDEV_TX_OK;
+ }
+
+ private_header = (__le16 *)__skb_push(skb, 2);
+++ /dev/null
-From 2a36a5c30eab9cd1c9d2d08bd27cd763325d70c5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Sat, 5 Dec 2015 02:09:43 +0100
-Subject: [PATCH] mtd: bcm47xxpart: limit scanned flash area on BCM47XX (MIPS)
- only
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We allowed using bcm47xxpart on BCM5301X arch with commit:
-9e3afa5f5c7 ("mtd: bcm47xxpart: allow enabling on ARCH_BCM_5301X")
-
-BCM5301X devices may contain some partitions in higher memory, e.g.
-Netgear R8000 has board_data at 0x2600000. To detect them we should
-use size limit on MIPS only.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -118,8 +118,8 @@ static int bcm47xxpart_parse(struct mtd_
- /* Parse block by block looking for magics */
- for (offset = 0; offset <= master->size - blocksize;
- offset += blocksize) {
-- /* Nothing more in higher memory */
-- if (offset >= 0x2000000)
-+ /* Nothing more in higher memory on BCM47XX (MIPS) */
-+ if (config_enabled(CONFIG_BCM47XX) && offset >= 0x2000000)
- break;
-
- if (curr_part >= BCM47XXPART_MAX_PARTS) {
+++ /dev/null
-From 36bcc0c9c2bc8f56569cd735ba531a51358d7c2b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Sun, 6 Dec 2015 11:31:38 +0100
-Subject: [PATCH] mtd: bcm47xxpart: don't fail because of bit-flips
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Bit-flip errors may occur on NAND flashes and are harmless. Handle them
-gracefully as read content is still reliable and can be parsed.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 38 ++++++++++++++++++++++----------------
- 1 file changed, 22 insertions(+), 16 deletions(-)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -66,11 +66,13 @@ static const char *bcm47xxpart_trx_data_
- {
- uint32_t buf;
- size_t bytes_read;
-+ int err;
-
-- if (mtd_read(master, offset, sizeof(buf), &bytes_read,
-- (uint8_t *)&buf) < 0) {
-- pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
-- offset);
-+ err = mtd_read(master, offset, sizeof(buf), &bytes_read,
-+ (uint8_t *)&buf);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
-+ offset, err);
- goto out_default;
- }
-
-@@ -95,6 +97,7 @@ static int bcm47xxpart_parse(struct mtd_
- int trx_part = -1;
- int last_trx_part = -1;
- int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
-+ int err;
-
- /*
- * Some really old flashes (like AT45DB*) had smaller erasesize-s, but
-@@ -128,10 +131,11 @@ static int bcm47xxpart_parse(struct mtd_
- }
-
- /* Read beginning of the block */
-- if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
-- &bytes_read, (uint8_t *)buf) < 0) {
-- pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
-- offset);
-+ err = mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
-+ &bytes_read, (uint8_t *)buf);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
-+ offset, err);
- continue;
- }
-
-@@ -254,10 +258,11 @@ static int bcm47xxpart_parse(struct mtd_
- }
-
- /* Read middle of the block */
-- if (mtd_read(master, offset + 0x8000, 0x4,
-- &bytes_read, (uint8_t *)buf) < 0) {
-- pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
-- offset);
-+ err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read,
-+ (uint8_t *)buf);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
-+ offset, err);
- continue;
- }
-
-@@ -277,10 +282,11 @@ static int bcm47xxpart_parse(struct mtd_
- }
-
- offset = master->size - possible_nvram_sizes[i];
-- if (mtd_read(master, offset, 0x4, &bytes_read,
-- (uint8_t *)buf) < 0) {
-- pr_err("mtd_read error while reading at offset 0x%X!\n",
-- offset);
-+ err = mtd_read(master, offset, 0x4, &bytes_read,
-+ (uint8_t *)buf);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("mtd_read error while reading (offset 0x%X): %d\n",
-+ offset, err);
- continue;
- }
-
+++ /dev/null
-From 5651d6aaf489d1db48c253cf884b40214e91c2c5 Mon Sep 17 00:00:00 2001
-From: Brian Norris <computersforpeace@gmail.com>
-Date: Fri, 26 Feb 2016 11:50:28 +0100
-Subject: [PATCH] mtd: bcm47xxsflash: use ioremap_cache() instead of
- KSEG0ADDR()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Using KSEG0ADDR makes code highly MIPS dependent and not portable.
-Thanks to the fix a68f376 ("MIPS: io.h: Define `ioremap_cache'") we can
-use ioremap_cache which is generic and supported on MIPS as well now.
-
-KSEG0ADDR was translating 0x1c000000 into 0x9c000000. With ioremap_cache
-we use MIPS's __ioremap (and then remap_area_pages). This results in
-different address (e.g. 0xc0080000) but it still should be cached as
-expected and it was successfully tested with BCM47186B0.
-
-Other than that drivers/bcma/driver_chipcommon_sflash.c nicely setups a
-struct resource for access window, but we wren't using it. Use it now
-and drop duplicated info.
-
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/drivers/bcma/driver_chipcommon_sflash.c
-+++ b/drivers/bcma/driver_chipcommon_sflash.c
-@@ -146,7 +146,6 @@ int bcma_sflash_init(struct bcma_drv_cc
- return -ENOTSUPP;
- }
-
-- sflash->window = BCMA_SOC_FLASH2;
- sflash->blocksize = e->blocksize;
- sflash->numblocks = e->numblocks;
- sflash->size = sflash->blocksize * sflash->numblocks;
---- a/drivers/mtd/devices/bcm47xxsflash.c
-+++ b/drivers/mtd/devices/bcm47xxsflash.c
-@@ -2,6 +2,7 @@
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/delay.h>
-+#include <linux/ioport.h>
- #include <linux/mtd/mtd.h>
- #include <linux/platform_device.h>
- #include <linux/bcma/bcma.h>
-@@ -109,8 +110,7 @@ static int bcm47xxsflash_read(struct mtd
- if ((from + len) > mtd->size)
- return -EINVAL;
-
-- memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(b47s->window + from),
-- len);
-+ memcpy_fromio(buf, b47s->window + from, len);
- *retlen = len;
-
- return len;
-@@ -275,15 +275,33 @@ static void bcm47xxsflash_bcma_cc_write(
-
- static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
- {
-- struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
-+ struct device *dev = &pdev->dev;
-+ struct bcma_sflash *sflash = dev_get_platdata(dev);
- struct bcm47xxsflash *b47s;
-+ struct resource *res;
- int err;
-
-- b47s = devm_kzalloc(&pdev->dev, sizeof(*b47s), GFP_KERNEL);
-+ b47s = devm_kzalloc(dev, sizeof(*b47s), GFP_KERNEL);
- if (!b47s)
- return -ENOMEM;
- sflash->priv = b47s;
-
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res) {
-+ dev_err(dev, "invalid resource\n");
-+ return -EINVAL;
-+ }
-+ if (!devm_request_mem_region(dev, res->start, resource_size(res),
-+ res->name)) {
-+ dev_err(dev, "can't request region for resource %pR\n", res);
-+ return -EBUSY;
-+ }
-+ b47s->window = ioremap_cache(res->start, resource_size(res));
-+ if (!b47s->window) {
-+ dev_err(dev, "ioremap failed for resource %pR\n", res);
-+ return -ENOMEM;
-+ }
-+
- b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash);
- b47s->cc_read = bcm47xxsflash_bcma_cc_read;
- b47s->cc_write = bcm47xxsflash_bcma_cc_write;
-@@ -297,7 +315,6 @@ static int bcm47xxsflash_bcma_probe(stru
- break;
- }
-
-- b47s->window = sflash->window;
- b47s->blocksize = sflash->blocksize;
- b47s->numblocks = sflash->numblocks;
- b47s->size = sflash->size;
-@@ -306,6 +323,7 @@ static int bcm47xxsflash_bcma_probe(stru
- err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
- if (err) {
- pr_err("Failed to register MTD device: %d\n", err);
-+ iounmap(b47s->window);
- return err;
- }
-
-@@ -321,6 +339,7 @@ static int bcm47xxsflash_bcma_remove(str
- struct bcm47xxsflash *b47s = sflash->priv;
-
- mtd_device_unregister(&b47s->mtd);
-+ iounmap(b47s->window);
-
- return 0;
- }
---- a/drivers/mtd/devices/bcm47xxsflash.h
-+++ b/drivers/mtd/devices/bcm47xxsflash.h
-@@ -65,7 +65,8 @@ struct bcm47xxsflash {
-
- enum bcm47xxsflash_type type;
-
-- u32 window;
-+ void __iomem *window;
-+
- u32 blocksize;
- u16 numblocks;
- u32 size;
---- a/include/linux/bcma/bcma_driver_chipcommon.h
-+++ b/include/linux/bcma/bcma_driver_chipcommon.h
-@@ -588,7 +588,6 @@ struct bcma_pflash {
- #ifdef CONFIG_BCMA_SFLASH
- struct bcma_sflash {
- bool present;
-- u32 window;
- u32 blocksize;
- u16 numblocks;
- u32 size;
+++ /dev/null
-From 64ad46379fcf14f437553f654d1adcd3d0e0d7f9 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Aug 2016 14:21:28 +0200
-Subject: [PATCH] mtd: bcm47xxsflash: use uncached MMIO access for BCM53573
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53573 is a new series of Broadcom's SoCs. It's based on ARM and uses
-this old ChipCommon-based flash access. Early tests resulted in flash
-corruptions that were tracked down to using cached MMIO for flash read
-access. Switch to ioremap_nocache conditionally to support BCM53573 and
-don't break performance on old MIPS devices.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/devices/bcm47xxsflash.c | 24 +++++++++++++++++++-----
- 1 file changed, 19 insertions(+), 5 deletions(-)
-
---- a/drivers/mtd/devices/bcm47xxsflash.c
-+++ b/drivers/mtd/devices/bcm47xxsflash.c
-@@ -296,16 +296,30 @@ static int bcm47xxsflash_bcma_probe(stru
- dev_err(dev, "can't request region for resource %pR\n", res);
- return -EBUSY;
- }
-- b47s->window = ioremap_cache(res->start, resource_size(res));
-- if (!b47s->window) {
-- dev_err(dev, "ioremap failed for resource %pR\n", res);
-- return -ENOMEM;
-- }
-
- b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash);
- b47s->cc_read = bcm47xxsflash_bcma_cc_read;
- b47s->cc_write = bcm47xxsflash_bcma_cc_write;
-
-+ /*
-+ * On old MIPS devices cache was magically invalidated when needed,
-+ * allowing us to use cached access and gain some performance. Trying
-+ * the same on ARM based BCM53573 results in flash corruptions, we need
-+ * to use uncached access for it.
-+ *
-+ * It may be arch specific, but right now there is only 1 ARM SoC using
-+ * this driver, so let's follow Broadcom's reference code and check
-+ * ChipCommon revision.
-+ */
-+ if (b47s->bcma_cc->core->id.rev == 54)
-+ b47s->window = ioremap_nocache(res->start, resource_size(res));
-+ else
-+ b47s->window = ioremap_cache(res->start, resource_size(res));
-+ if (!b47s->window) {
-+ dev_err(dev, "ioremap failed for resource %pR\n", res);
-+ return -ENOMEM;
-+ }
-+
- switch (b47s->bcma_cc->capabilities & BCMA_CC_CAP_FLASHT) {
- case BCMA_CC_FLASHT_STSER:
- b47s->type = BCM47XXSFLASH_TYPE_ST;
+++ /dev/null
-From bd5d21310133921021d78995ad6346f908483124 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 20 Nov 2016 16:09:30 +0100
-Subject: [PATCH] mtd: bcm47xxpart: fix parsing first block after aligned TRX
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-After parsing TRX we should skip to the first block placed behind it.
-Our code was working only with TRX with length not aligned to the
-blocksize. In other cases (length aligned) it was missing the block
-places right after TRX.
-
-This fixes calculation and simplifies the comment.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -229,12 +229,10 @@ static int bcm47xxpart_parse(struct mtd_
-
- last_trx_part = curr_part - 1;
-
-- /*
-- * We have whole TRX scanned, skip to the next part. Use
-- * roundown (not roundup), as the loop will increase
-- * offset in next step.
-- */
-- offset = rounddown(offset + trx->length, blocksize);
-+ /* Jump to the end of TRX */
-+ offset = roundup(offset + trx->length, blocksize);
-+ /* Next loop iteration will increase the offset */
-+ offset -= blocksize;
- continue;
- }
-
+++ /dev/null
-From be5e5099183301fb7920f8f6b66bd3ac1f820a97 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 16 Jan 2017 17:28:18 +0100
-Subject: [PATCH] mtd: bcm47xxsflash: use platform_(set|get)_drvdata
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We have generic place & helpers for storing platform driver data so
-there is no reason for using custom priv pointer.
-
-This allows cleaning up struct bcma_sflash from unneeded fields.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Kalle Valo <kvalo@codeaurora.org>
-Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/devices/bcm47xxsflash.c | 6 +++---
- include/linux/bcma/bcma_driver_chipcommon.h | 3 ---
- 2 files changed, 3 insertions(+), 6 deletions(-)
-
---- a/drivers/mtd/devices/bcm47xxsflash.c
-+++ b/drivers/mtd/devices/bcm47xxsflash.c
-@@ -284,7 +284,6 @@ static int bcm47xxsflash_bcma_probe(stru
- b47s = devm_kzalloc(dev, sizeof(*b47s), GFP_KERNEL);
- if (!b47s)
- return -ENOMEM;
-- sflash->priv = b47s;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
-@@ -334,6 +333,8 @@ static int bcm47xxsflash_bcma_probe(stru
- b47s->size = sflash->size;
- bcm47xxsflash_fill_mtd(b47s, &pdev->dev);
-
-+ platform_set_drvdata(pdev, b47s);
-+
- err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
- if (err) {
- pr_err("Failed to register MTD device: %d\n", err);
-@@ -349,8 +350,7 @@ static int bcm47xxsflash_bcma_probe(stru
-
- static int bcm47xxsflash_bcma_remove(struct platform_device *pdev)
- {
-- struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
-- struct bcm47xxsflash *b47s = sflash->priv;
-+ struct bcm47xxsflash *b47s = platform_get_drvdata(pdev);
-
- mtd_device_unregister(&b47s->mtd);
- iounmap(b47s->window);
---- a/include/linux/bcma/bcma_driver_chipcommon.h
-+++ b/include/linux/bcma/bcma_driver_chipcommon.h
-@@ -591,9 +591,6 @@ struct bcma_sflash {
- u32 blocksize;
- u16 numblocks;
- u32 size;
--
-- struct mtd_info *mtd;
-- void *priv;
- };
- #endif
-
+++ /dev/null
-From ccc38234fdc70120be79e7fb2df5c27ca5cd4c8a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 8 Feb 2017 23:53:44 +0100
-Subject: [PATCH] mtd: bcm47xxsflash: support reading flash out of mapping
- window
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-For reading flash content we use MMIO but it's possible to read only
-first 16 MiB this way. It's simply an arch design/limitation.
-To support flash sizes bigger than 16 MiB implement indirect access
-using ChipCommon registers.
-This has been tested using MX25L25635F.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Marek Vasut <marek.vasut@gmail.com>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/devices/bcm47xxsflash.c | 24 +++++++++++++++++++++---
- drivers/mtd/devices/bcm47xxsflash.h | 3 +++
- 2 files changed, 24 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/devices/bcm47xxsflash.c
-+++ b/drivers/mtd/devices/bcm47xxsflash.c
-@@ -105,15 +105,33 @@ static int bcm47xxsflash_read(struct mtd
- size_t *retlen, u_char *buf)
- {
- struct bcm47xxsflash *b47s = mtd->priv;
-+ size_t orig_len = len;
-
- /* Check address range */
- if ((from + len) > mtd->size)
- return -EINVAL;
-
-- memcpy_fromio(buf, b47s->window + from, len);
-- *retlen = len;
-+ /* Read as much as possible using fast MMIO window */
-+ if (from < BCM47XXSFLASH_WINDOW_SZ) {
-+ size_t memcpy_len;
-
-- return len;
-+ memcpy_len = min(len, (size_t)(BCM47XXSFLASH_WINDOW_SZ - from));
-+ memcpy_fromio(buf, b47s->window + from, memcpy_len);
-+ from += memcpy_len;
-+ len -= memcpy_len;
-+ buf += memcpy_len;
-+ }
-+
-+ /* Use indirect access for content out of the window */
-+ for (; len; len--) {
-+ b47s->cc_write(b47s, BCMA_CC_FLASHADDR, from++);
-+ bcm47xxsflash_cmd(b47s, OPCODE_ST_READ4B);
-+ *buf++ = b47s->cc_read(b47s, BCMA_CC_FLASHDATA);
-+ }
-+
-+ *retlen = orig_len;
-+
-+ return orig_len;
- }
-
- static int bcm47xxsflash_write_st(struct mtd_info *mtd, u32 offset, size_t len,
---- a/drivers/mtd/devices/bcm47xxsflash.h
-+++ b/drivers/mtd/devices/bcm47xxsflash.h
-@@ -3,6 +3,8 @@
-
- #include <linux/mtd/mtd.h>
-
-+#define BCM47XXSFLASH_WINDOW_SZ SZ_16M
-+
- /* Used for ST flashes only. */
- #define OPCODE_ST_WREN 0x0006 /* Write Enable */
- #define OPCODE_ST_WRDIS 0x0004 /* Write Disable */
-@@ -16,6 +18,7 @@
- #define OPCODE_ST_RES 0x03ab /* Read Electronic Signature */
- #define OPCODE_ST_CSA 0x1000 /* Keep chip select asserted */
- #define OPCODE_ST_SSE 0x0220 /* Sub-sector Erase */
-+#define OPCODE_ST_READ4B 0x6313 /* Read Data Bytes in 4Byte addressing mode */
-
- /* Used for Atmel flashes only. */
- #define OPCODE_AT_READ 0x07e8
+++ /dev/null
-From b522d7b0ebe3539340c2a6d46d787ae3d33bcb92 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 10 Jan 2017 23:15:24 +0100
-Subject: [PATCH] mtd: bcm47xxpart: move TRX parsing code to separated function
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This change simplifies main parsing loop logic a bit. In future it may
-be useful for moving TRX support to separated module / parser (if we
-implement support for them at some point).
-Finally parsing TRX at the end puts us in a better position as we have
-better flash layout knowledge. It may be useful e.g. if it appears there
-is more than 1 TRX partition.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Marek Vasut <marek.vasut@gmail.com>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 121 ++++++++++++++++++++++++++++------------------
- 1 file changed, 74 insertions(+), 47 deletions(-)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -83,6 +83,67 @@ out_default:
- return "rootfs";
- }
-
-+static int bcm47xxpart_parse_trx(struct mtd_info *master,
-+ struct mtd_partition *trx,
-+ struct mtd_partition *parts,
-+ size_t parts_len)
-+{
-+ struct trx_header header;
-+ size_t bytes_read;
-+ int curr_part = 0;
-+ int i, err;
-+
-+ if (parts_len < 3) {
-+ pr_warn("No enough space to add TRX partitions!\n");
-+ return -ENOMEM;
-+ }
-+
-+ err = mtd_read(master, trx->offset, sizeof(header), &bytes_read,
-+ (uint8_t *)&header);
-+ if (err && !mtd_is_bitflip(err)) {
-+ pr_err("mtd_read error while reading TRX header: %d\n", err);
-+ return err;
-+ }
-+
-+ i = 0;
-+
-+ /* We have LZMA loader if offset[2] points to sth */
-+ if (header.offset[2]) {
-+ bcm47xxpart_add_part(&parts[curr_part++], "loader",
-+ trx->offset + header.offset[i], 0);
-+ i++;
-+ }
-+
-+ if (header.offset[i]) {
-+ bcm47xxpart_add_part(&parts[curr_part++], "linux",
-+ trx->offset + header.offset[i], 0);
-+ i++;
-+ }
-+
-+ if (header.offset[i]) {
-+ size_t offset = trx->offset + header.offset[i];
-+ const char *name = bcm47xxpart_trx_data_part_name(master,
-+ offset);
-+
-+ bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0);
-+ i++;
-+ }
-+
-+ /*
-+ * Assume that every partition ends at the beginning of the one it is
-+ * followed by.
-+ */
-+ for (i = 0; i < curr_part; i++) {
-+ u64 next_part_offset = (i < curr_part - 1) ?
-+ parts[i + 1].offset :
-+ trx->offset + trx->size;
-+
-+ parts[i].size = next_part_offset - parts[i].offset;
-+ }
-+
-+ return curr_part;
-+}
-+
- static int bcm47xxpart_parse(struct mtd_info *master,
- struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -93,9 +154,7 @@ static int bcm47xxpart_parse(struct mtd_
- size_t bytes_read;
- uint32_t offset;
- uint32_t blocksize = master->erasesize;
-- struct trx_header *trx;
- int trx_part = -1;
-- int last_trx_part = -1;
- int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
- int err;
-
-@@ -182,54 +241,14 @@ static int bcm47xxpart_parse(struct mtd_
-
- /* TRX */
- if (buf[0x000 / 4] == TRX_MAGIC) {
-- if (BCM47XXPART_MAX_PARTS - curr_part < 4) {
-- pr_warn("Not enough partitions left to register trx, scanning stopped!\n");
-- break;
-- }
--
-- trx = (struct trx_header *)buf;
-+ struct trx_header *trx;
-
- trx_part = curr_part;
- bcm47xxpart_add_part(&parts[curr_part++], "firmware",
- offset, 0);
-
-- i = 0;
-- /* We have LZMA loader if offset[2] points to sth */
-- if (trx->offset[2]) {
-- bcm47xxpart_add_part(&parts[curr_part++],
-- "loader",
-- offset + trx->offset[i],
-- 0);
-- i++;
-- }
--
-- if (trx->offset[i]) {
-- bcm47xxpart_add_part(&parts[curr_part++],
-- "linux",
-- offset + trx->offset[i],
-- 0);
-- i++;
-- }
--
-- /*
-- * Pure rootfs size is known and can be calculated as:
-- * trx->length - trx->offset[i]. We don't fill it as
-- * we want to have jffs2 (overlay) in the same mtd.
-- */
-- if (trx->offset[i]) {
-- const char *name;
--
-- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]);
-- bcm47xxpart_add_part(&parts[curr_part++],
-- name,
-- offset + trx->offset[i],
-- 0);
-- i++;
-- }
--
-- last_trx_part = curr_part - 1;
--
- /* Jump to the end of TRX */
-+ trx = (struct trx_header *)buf;
- offset = roundup(offset + trx->length, blocksize);
- /* Next loop iteration will increase the offset */
- offset -= blocksize;
-@@ -307,9 +326,17 @@ static int bcm47xxpart_parse(struct mtd_
- parts[i + 1].offset : master->size;
-
- parts[i].size = next_part_offset - parts[i].offset;
-- if (i == last_trx_part && trx_part >= 0)
-- parts[trx_part].size = next_part_offset -
-- parts[trx_part].offset;
-+ }
-+
-+ /* If there was TRX parse it now */
-+ if (trx_part >= 0) {
-+ int num_parts;
-+
-+ num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part],
-+ parts + curr_part,
-+ BCM47XXPART_MAX_PARTS - curr_part);
-+ if (num_parts > 0)
-+ curr_part += num_parts;
- }
-
- *pparts = parts;
+++ /dev/null
-From 89a0d9a9f1941a086a82bc7cd73d275cec98ba14 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 10 Jan 2017 23:15:25 +0100
-Subject: [PATCH] mtd: bcm47xxpart: support layouts with multiple TRX
- partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some devices may have an extra TRX partition used as failsafe one. If
-we detect such partition we should set a proper name for it and don't
-parse it.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Marek Vasut <marek.vasut@gmail.com>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 56 ++++++++++++++++++++++++++++++++++++++---------
- 1 file changed, 46 insertions(+), 10 deletions(-)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -9,6 +9,7 @@
- *
- */
-
-+#include <linux/bcm47xx_nvram.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/slab.h>
-@@ -144,6 +145,30 @@ static int bcm47xxpart_parse_trx(struct
- return curr_part;
- }
-
-+/**
-+ * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader
-+ *
-+ * Some devices may have more than one TRX partition. In such case one of them
-+ * is the main one and another a failsafe one. Bootloader may fallback to the
-+ * failsafe firmware if it detects corruption of the main image.
-+ *
-+ * This function provides info about currently used TRX partition. It's the one
-+ * containing kernel started by the bootloader.
-+ */
-+static int bcm47xxpart_bootpartition(void)
-+{
-+ char buf[4];
-+ int bootpartition;
-+
-+ /* Check CFE environment variable */
-+ if (bcm47xx_nvram_getenv("bootpartition", buf, sizeof(buf)) > 0) {
-+ if (!kstrtoint(buf, 0, &bootpartition))
-+ return bootpartition;
-+ }
-+
-+ return 0;
-+}
-+
- static int bcm47xxpart_parse(struct mtd_info *master,
- struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -154,7 +179,8 @@ static int bcm47xxpart_parse(struct mtd_
- size_t bytes_read;
- uint32_t offset;
- uint32_t blocksize = master->erasesize;
-- int trx_part = -1;
-+ int trx_parts[2]; /* Array with indexes of TRX partitions */
-+ int trx_num = 0; /* Number of found TRX partitions */
- int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
- int err;
-
-@@ -243,7 +269,11 @@ static int bcm47xxpart_parse(struct mtd_
- if (buf[0x000 / 4] == TRX_MAGIC) {
- struct trx_header *trx;
-
-- trx_part = curr_part;
-+ if (trx_num >= ARRAY_SIZE(trx_parts))
-+ pr_warn("No enough space to store another TRX found at 0x%X\n",
-+ offset);
-+ else
-+ trx_parts[trx_num++] = curr_part;
- bcm47xxpart_add_part(&parts[curr_part++], "firmware",
- offset, 0);
-
-@@ -329,14 +359,20 @@ static int bcm47xxpart_parse(struct mtd_
- }
-
- /* If there was TRX parse it now */
-- if (trx_part >= 0) {
-- int num_parts;
-+ for (i = 0; i < trx_num; i++) {
-+ struct mtd_partition *trx = &parts[trx_parts[i]];
-
-- num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part],
-- parts + curr_part,
-- BCM47XXPART_MAX_PARTS - curr_part);
-- if (num_parts > 0)
-- curr_part += num_parts;
-+ if (i == bcm47xxpart_bootpartition()) {
-+ int num_parts;
-+
-+ num_parts = bcm47xxpart_parse_trx(master, trx,
-+ parts + curr_part,
-+ BCM47XXPART_MAX_PARTS - curr_part);
-+ if (num_parts > 0)
-+ curr_part += num_parts;
-+ } else {
-+ trx->name = "failsafe";
-+ }
- }
-
- *pparts = parts;
};
#define JEDEC_MFR(info) ((info)->id[0])
-@@ -1156,7 +1157,8 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -1163,7 +1164,8 @@ int spi_nor_scan(struct spi_nor *nor, co
if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
JEDEC_MFR(info) == SNOR_MFR_INTEL ||
write_enable(nor);
write_sr(nor, 0);
}
-@@ -1172,7 +1174,8 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -1179,7 +1181,8 @@ int spi_nor_scan(struct spi_nor *nor, co
mtd->_read = spi_nor_read;
/* NOR protection support for STmicro/Micron chips and similar */
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:56 +0000
-Subject: [PATCH] MIPS: Introduce irq_stack
-
-Allocate a per-cpu irq stack for use within interrupt handlers.
-
-Also add a utility function on_irq_stack to determine if a given stack
-pointer is within the irq stack for that cpu.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/include/asm/irq.h
-+++ b/arch/mips/include/asm/irq.h
-@@ -17,6 +17,18 @@
-
- #include <irq.h>
-
-+#define IRQ_STACK_SIZE THREAD_SIZE
-+
-+extern void *irq_stack[NR_CPUS];
-+
-+static inline bool on_irq_stack(int cpu, unsigned long sp)
-+{
-+ unsigned long low = (unsigned long)irq_stack[cpu];
-+ unsigned long high = low + IRQ_STACK_SIZE;
-+
-+ return (low <= sp && sp <= high);
-+}
-+
- #ifdef CONFIG_I8259
- static inline int irq_canonicalize(int irq)
- {
---- a/arch/mips/kernel/asm-offsets.c
-+++ b/arch/mips/kernel/asm-offsets.c
-@@ -101,6 +101,7 @@ void output_thread_info_defines(void)
- OFFSET(TI_REGS, thread_info, regs);
- DEFINE(_THREAD_SIZE, THREAD_SIZE);
- DEFINE(_THREAD_MASK, THREAD_MASK);
-+ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
- BLANK();
- }
-
---- a/arch/mips/kernel/irq.c
-+++ b/arch/mips/kernel/irq.c
-@@ -25,6 +25,8 @@
- #include <linux/atomic.h>
- #include <asm/uaccess.h>
-
-+void *irq_stack[NR_CPUS];
-+
- /*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
-@@ -55,6 +57,15 @@ void __init init_IRQ(void)
- irq_set_noprobe(i);
-
- arch_init_irq();
-+
-+ for_each_possible_cpu(i) {
-+ int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE;
-+ void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages);
-+
-+ irq_stack[i] = s;
-+ pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i,
-+ irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE);
-+ }
- }
-
- #ifdef CONFIG_DEBUG_STACKOVERFLOW
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:57 +0000
-Subject: [PATCH] MIPS: Stack unwinding while on IRQ stack
-
-Within unwind stack, check if the stack pointer being unwound is within
-the CPU's irq_stack and if so use that page rather than the task's stack
-page.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/kernel/process.c
-+++ b/arch/mips/kernel/process.c
-@@ -32,6 +32,7 @@
- #include <asm/cpu.h>
- #include <asm/dsp.h>
- #include <asm/fpu.h>
-+#include <asm/irq.h>
- #include <asm/msa.h>
- #include <asm/pgtable.h>
- #include <asm/mipsregs.h>
-@@ -507,7 +508,19 @@ EXPORT_SYMBOL(unwind_stack_by_address);
- unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
- unsigned long pc, unsigned long *ra)
- {
-- unsigned long stack_page = (unsigned long)task_stack_page(task);
-+ unsigned long stack_page = 0;
-+ int cpu;
-+
-+ for_each_possible_cpu(cpu) {
-+ if (on_irq_stack(cpu, *sp)) {
-+ stack_page = (unsigned long)irq_stack[cpu];
-+ break;
-+ }
-+ }
-+
-+ if (!stack_page)
-+ stack_page = (unsigned long)task_stack_page(task);
-+
- return unwind_stack_by_address(stack_page, sp, pc, ra);
- }
- #endif
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:58 +0000
-Subject: [PATCH] MIPS: Only change $28 to thread_info if coming from user
- mode
-
-The SAVE_SOME macro is used to save the execution context on all
-exceptions.
-If an exception occurs while executing user code, the stack is switched
-to the kernel's stack for the current task, and register $28 is switched
-to point to the current_thread_info, which is at the bottom of the stack
-region.
-If the exception occurs while executing kernel code, the stack is left,
-and this change ensures that register $28 is not updated. This is the
-correct behaviour when the kernel can be executing on the separate irq
-stack, because the thread_info will not be at the base of it.
-
-With this change, register $28 is only switched to it's kernel
-conventional usage of the currrent thread info pointer at the point at
-which execution enters kernel space. Doing it on every exception was
-redundant, but OK without an IRQ stack, but will be erroneous once that
-is introduced.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
-Reviewed-by: Maciej W. Rozycki <macro@imgtec.com>
----
-
---- a/arch/mips/include/asm/stackframe.h
-+++ b/arch/mips/include/asm/stackframe.h
-@@ -216,12 +216,19 @@
- LONG_S $25, PT_R25(sp)
- LONG_S $28, PT_R28(sp)
- LONG_S $31, PT_R31(sp)
-+
-+ /* Set thread_info if we're coming from user mode */
-+ mfc0 k0, CP0_STATUS
-+ sll k0, 3 /* extract cu0 bit */
-+ bltz k0, 9f
-+
- ori $28, sp, _THREAD_MASK
- xori $28, _THREAD_MASK
- #ifdef CONFIG_CPU_CAVIUM_OCTEON
- .set mips64
- pref 0, 0($28) /* Prefetch the current pointer */
- #endif
-+9:
- .set pop
- .endm
-
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:59 +0000
-Subject: [PATCH] MIPS: Switch to the irq_stack in interrupts
-
-When enterring interrupt context via handle_int or except_vec_vi, switch
-to the irq_stack of the current CPU if it is not already in use.
-
-The current stack pointer is masked with the thread size and compared to
-the base or the irq stack. If it does not match then the stack pointer
-is set to the top of that stack, otherwise this is a nested irq being
-handled on the irq stack so the stack pointer should be left as it was.
-
-The in-use stack pointer is placed in the callee saved register s1. It
-will be saved to the stack when plat_irq_dispatch is invoked and can be
-restored once control returns here.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/kernel/genex.S
-+++ b/arch/mips/kernel/genex.S
-@@ -188,9 +188,44 @@ NESTED(handle_int, PT_SIZE, sp)
-
- LONG_L s0, TI_REGS($28)
- LONG_S sp, TI_REGS($28)
-- PTR_LA ra, ret_from_irq
-- PTR_LA v0, plat_irq_dispatch
-- jr v0
-+
-+ /*
-+ * SAVE_ALL ensures we are using a valid kernel stack for the thread.
-+ * Check if we are already using the IRQ stack.
-+ */
-+ move s1, sp # Preserve the sp
-+
-+ /* Get IRQ stack for this CPU */
-+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
-+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
-+ lui k1, %hi(irq_stack)
-+#else
-+ lui k1, %highest(irq_stack)
-+ daddiu k1, %higher(irq_stack)
-+ dsll k1, 16
-+ daddiu k1, %hi(irq_stack)
-+ dsll k1, 16
-+#endif
-+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
-+ LONG_ADDU k1, k0
-+ LONG_L t0, %lo(irq_stack)(k1)
-+
-+ # Check if already on IRQ stack
-+ PTR_LI t1, ~(_THREAD_SIZE-1)
-+ and t1, t1, sp
-+ beq t0, t1, 2f
-+
-+ /* Switch to IRQ stack */
-+ li t1, _IRQ_STACK_SIZE
-+ PTR_ADD sp, t0, t1
-+
-+2:
-+ jal plat_irq_dispatch
-+
-+ /* Restore sp */
-+ move sp, s1
-+
-+ j ret_from_irq
- #ifdef CONFIG_CPU_MICROMIPS
- nop
- #endif
-@@ -263,8 +298,44 @@ NESTED(except_vec_vi_handler, 0, sp)
-
- LONG_L s0, TI_REGS($28)
- LONG_S sp, TI_REGS($28)
-- PTR_LA ra, ret_from_irq
-- jr v0
-+
-+ /*
-+ * SAVE_ALL ensures we are using a valid kernel stack for the thread.
-+ * Check if we are already using the IRQ stack.
-+ */
-+ move s1, sp # Preserve the sp
-+
-+ /* Get IRQ stack for this CPU */
-+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
-+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
-+ lui k1, %hi(irq_stack)
-+#else
-+ lui k1, %highest(irq_stack)
-+ daddiu k1, %higher(irq_stack)
-+ dsll k1, 16
-+ daddiu k1, %hi(irq_stack)
-+ dsll k1, 16
-+#endif
-+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
-+ LONG_ADDU k1, k0
-+ LONG_L t0, %lo(irq_stack)(k1)
-+
-+ # Check if already on IRQ stack
-+ PTR_LI t1, ~(_THREAD_SIZE-1)
-+ and t1, t1, sp
-+ beq t0, t1, 2f
-+
-+ /* Switch to IRQ stack */
-+ li t1, _IRQ_STACK_SIZE
-+ PTR_ADD sp, t0, t1
-+
-+2:
-+ jal plat_irq_dispatch
-+
-+ /* Restore sp */
-+ move sp, s1
-+
-+ j ret_from_irq
- END(except_vec_vi_handler)
-
- /*
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:21:00 +0000
-Subject: [PATCH] MIPS: Select HAVE_IRQ_EXIT_ON_IRQ_STACK
-
-Since do_IRQ is now invoked on a separate IRQ stack, we select
-HAVE_IRQ_EXIT_ON_IRQ_STACK so that softirq's may be invoked directly
-from irq_exit(), rather than requiring do_softirq_own_stack.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -9,6 +9,7 @@ config MIPS
- select HAVE_CONTEXT_TRACKING
- select HAVE_GENERIC_DMA_COHERENT
- select HAVE_IDE
-+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
- select HAVE_OPROFILE
- select HAVE_PERF_EVENTS
- select PERF_USE_VMALLOC
+++ /dev/null
-From de856416e7143e32afc4849625616554aa060f7a Mon Sep 17 00:00:00 2001
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Wed, 25 Jan 2017 17:00:25 +0000
-Subject: [PATCH] MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch
-
-Commit dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts")
-changed both the normal and vectored interrupt handlers. Unfortunately
-the vectored version, "except_vec_vi_handler", was incorrectly modified
-to unconditionally jal to plat_irq_dispatch, rather than doing a jalr to
-the vectored handler that has been set up. This is ok for many platforms
-which set the vectored handler to plat_irq_dispatch anyway, but will
-cause problems with platforms that use other handlers.
-
-Fixes: dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts")
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
-Cc: Ralf Baechle <ralf@linux-mips.org>
-Cc: Paul Burton <paul.burton@imgtec.com>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/15110/
-Signed-off-by: James Hogan <james.hogan@imgtec.com>
----
- arch/mips/kernel/genex.S | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/kernel/genex.S
-+++ b/arch/mips/kernel/genex.S
-@@ -330,7 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp)
- PTR_ADD sp, t0, t1
-
- 2:
-- jal plat_irq_dispatch
-+ jalr v0
-
- /* Restore sp */
- move sp, s1
+++ /dev/null
-From f1640c3ddeec12804bc9a21feee85fc15aca95f6 Mon Sep 17 00:00:00 2001
-From: wangweidong <wangweidong1@huawei.com>
-Date: Wed, 13 Jan 2016 11:06:41 +0800
-Subject: [PATCH] bgmac: fix a missing check for build_skb
-
-when build_skb failed, it may occure a NULL pointer.
-So add a 'NULL check' for it.
-
-Signed-off-by: Weidong Wang <wangweidong1@huawei.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -469,6 +469,11 @@ static int bgmac_dma_rx_read(struct bgma
- len -= ETH_FCS_LEN;
-
- skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE);
-+ if (unlikely(skb)) {
-+ bgmac_err(bgmac, "build_skb failed\n");
-+ put_page(virt_to_head_page(buf));
-+ break;
-+ }
- skb_put(skb, BGMAC_RX_FRAME_OFFSET +
- BGMAC_RX_BUF_OFFSET + len);
- skb_pull(skb, BGMAC_RX_FRAME_OFFSET +
+++ /dev/null
-From 750afbf8ee9c6a1c74a1fe5fc9852146b1d72687 Mon Sep 17 00:00:00 2001
-From: "David S. Miller" <davem@davemloft.net>
-Date: Fri, 15 Jan 2016 16:07:13 -0500
-Subject: [PATCH] bgmac: Fix reversed test of build_skb() return value.
-
-Fixes: f1640c3ddeec ("bgmac: fix a missing check for build_skb")
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -469,7 +469,7 @@ static int bgmac_dma_rx_read(struct bgma
- len -= ETH_FCS_LEN;
-
- skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE);
-- if (unlikely(skb)) {
-+ if (unlikely(!skb)) {
- bgmac_err(bgmac, "build_skb failed\n");
- put_page(virt_to_head_page(buf));
- break;
static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask,
u32 value, int timeout)
{
-@@ -990,11 +1001,9 @@ static void bgmac_mac_speed(struct bgmac
+@@ -991,11 +1002,9 @@ static void bgmac_mac_speed(struct bgmac
static void bgmac_miiconfig(struct bgmac *bgmac)
{
struct bcma_device *core = bgmac->core;
bcma_awrite32(core, BCMA_IOCTL,
bcma_aread32(core, BCMA_IOCTL) | 0x40 |
BGMAC_BCMA_IOCTL_SW_CLKEN);
-@@ -1058,9 +1067,7 @@ static void bgmac_chip_reset(struct bgma
+@@ -1059,9 +1068,7 @@ static void bgmac_chip_reset(struct bgma
}
/* Request Misc PLL for corerev > 2 */
bgmac_set(bgmac, BCMA_CLKCTLST,
BGMAC_BCMA_CLKCTLST_MISC_PLL_REQ);
bgmac_wait_value(bgmac->core, BCMA_CLKCTLST,
-@@ -1196,8 +1203,7 @@ static void bgmac_enable(struct bgmac *b
+@@ -1197,8 +1204,7 @@ static void bgmac_enable(struct bgmac *b
break;
}
rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);
rxq_ctl &= ~BGMAC_RXQ_CTL_MDP_MASK;
bp_clk = bcma_pmu_get_bus_clock(&bgmac->core->bus->drv_cc) /
-@@ -1475,14 +1481,12 @@ static int bgmac_fixed_phy_register(stru
+@@ -1477,14 +1483,12 @@ static int bgmac_fixed_phy_register(stru
static int bgmac_mii_register(struct bgmac *bgmac)
{
return bgmac_fixed_phy_register(bgmac);
mii_bus = mdiobus_alloc();
-@@ -1553,7 +1557,6 @@ static void bgmac_mii_unregister(struct
+@@ -1555,7 +1559,6 @@ static void bgmac_mii_unregister(struct
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
static int bgmac_probe(struct bcma_device *core)
{
struct net_device *net_dev;
struct bgmac *bgmac;
struct ssb_sprom *sprom = &core->bus->sprom;
-@@ -1634,8 +1637,7 @@ static int bgmac_probe(struct bcma_devic
+@@ -1641,8 +1644,7 @@ static int bgmac_probe(struct bcma_devic
bgmac_chip_reset(bgmac);
/* For Northstar, we have to take all GMAC core out of reset */
case BCMA_CHIP_ID_BCM53018:
return true;
default:
-@@ -1055,8 +1056,9 @@ static void bgmac_chip_reset(struct bgma
+@@ -1056,8 +1057,9 @@ static void bgmac_chip_reset(struct bgma
(ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188))
iost &= ~BGMAC_BCMA_IOST_ATTACHED;
+++ /dev/null
-From b4dfd8e92956b396d3438212bc9a0be6267b8b34 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Tue, 12 Apr 2016 13:30:45 +0200
-Subject: [PATCH] bgmac: reset & enable Ethernet core before using it
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes Ethernet on D-Link DIR-885L with BCM47094 SoC. Felix reported
-similar fix was needed for his BCM4709 device (Buffalo WXR-1900DHP?).
-I tested this for regressions on BCM4706, BCM4708A0 and BCM47081A0.
-
-Cc: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -1586,6 +1586,11 @@ static int bgmac_probe(struct bcma_devic
- dev_warn(&core->dev, "Using random MAC: %pM\n", mac);
- }
-
-+ /* This (reset &) enable is not preset in specs or reference driver but
-+ * Broadcom does it in arch PCI code when enabling fake PCI device.
-+ */
-+ bcma_core_enable(core, 0);
-+
- /* Allocation and references */
- net_dev = alloc_etherdev(sizeof(*bgmac));
- if (!net_dev)
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -1602,6 +1602,7 @@ static int bgmac_probe(struct bcma_devic
+@@ -1604,6 +1604,7 @@ static int bgmac_probe(struct bcma_devic
bgmac->net_dev = net_dev;
bgmac->core = core;
bcma_set_drvdata(core, bgmac);
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -1385,6 +1385,127 @@ static const struct net_device_ops bgmac
+@@ -1387,6 +1387,127 @@ static const struct net_device_ops bgmac
* ethtool_ops
**************************************************/
static int bgmac_get_settings(struct net_device *net_dev,
struct ethtool_cmd *cmd)
{
-@@ -1409,6 +1530,9 @@ static void bgmac_get_drvinfo(struct net
+@@ -1411,6 +1532,9 @@ static void bgmac_get_drvinfo(struct net
}
static const struct ethtool_ops bgmac_ethtool_ops = {
return NETDEV_TX_OK;
}
-@@ -284,6 +286,8 @@ static void bgmac_dma_tx_free(struct bgm
+@@ -285,6 +287,8 @@ static void bgmac_dma_tx_free(struct bgm
DMA_TO_DEVICE);
if (slot->skb) {
bytes_compl += slot->skb->len;
pkts_compl++;
-@@ -467,6 +471,7 @@ static int bgmac_dma_rx_read(struct bgma
+@@ -468,6 +472,7 @@ static int bgmac_dma_rx_read(struct bgma
bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
ring->start);
put_page(virt_to_head_page(buf));
break;
}
-@@ -474,6 +479,8 @@ static int bgmac_dma_rx_read(struct bgma
+@@ -475,6 +480,8 @@ static int bgmac_dma_rx_read(struct bgma
bgmac_err(bgmac, "Found oversized packet at slot %d, DMA issue!\n",
ring->start);
put_page(virt_to_head_page(buf));
break;
}
-@@ -484,6 +491,7 @@ static int bgmac_dma_rx_read(struct bgma
+@@ -485,6 +492,7 @@ static int bgmac_dma_rx_read(struct bgma
if (unlikely(!skb)) {
bgmac_err(bgmac, "build_skb failed\n");
put_page(virt_to_head_page(buf));
break;
}
skb_put(skb, BGMAC_RX_FRAME_OFFSET +
-@@ -493,6 +501,8 @@ static int bgmac_dma_rx_read(struct bgma
+@@ -494,6 +502,8 @@ static int bgmac_dma_rx_read(struct bgma
skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, bgmac->net_dev);
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -1323,7 +1323,7 @@ static int bgmac_open(struct net_device
+@@ -1324,7 +1324,7 @@ static int bgmac_open(struct net_device
}
napi_enable(&bgmac->napi);
- phy_start(bgmac->phy_dev);
+ phy_start(net_dev->phydev);
- netif_carrier_on(net_dev);
- return 0;
-@@ -1335,7 +1335,7 @@ static int bgmac_stop(struct net_device
+ netif_start_queue(net_dev);
+
+@@ -1337,7 +1337,7 @@ static int bgmac_stop(struct net_device
netif_carrier_off(net_dev);
napi_disable(&bgmac->napi);
bgmac_chip_intrs_off(bgmac);
-@@ -1373,12 +1373,10 @@ static int bgmac_set_mac_address(struct
+@@ -1375,12 +1375,10 @@ static int bgmac_set_mac_address(struct
static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
{
}
static const struct net_device_ops bgmac_netdev_ops = {
-@@ -1521,7 +1519,7 @@ static int bgmac_get_settings(struct net
+@@ -1523,7 +1521,7 @@ static int bgmac_get_settings(struct net
{
struct bgmac *bgmac = netdev_priv(net_dev);
}
static int bgmac_set_settings(struct net_device *net_dev,
-@@ -1529,7 +1527,7 @@ static int bgmac_set_settings(struct net
+@@ -1531,7 +1529,7 @@ static int bgmac_set_settings(struct net
{
struct bgmac *bgmac = netdev_priv(net_dev);
}
static void bgmac_get_drvinfo(struct net_device *net_dev,
-@@ -1566,7 +1564,7 @@ static int bgmac_mii_write(struct mii_bu
+@@ -1568,7 +1566,7 @@ static int bgmac_mii_write(struct mii_bu
static void bgmac_adjust_link(struct net_device *net_dev)
{
struct bgmac *bgmac = netdev_priv(net_dev);
bool update = false;
if (phy_dev->link) {
-@@ -1610,8 +1608,6 @@ static int bgmac_fixed_phy_register(stru
+@@ -1612,8 +1610,6 @@ static int bgmac_fixed_phy_register(stru
return err;
}
return err;
}
-@@ -1664,7 +1660,6 @@ static int bgmac_mii_register(struct bgm
+@@ -1666,7 +1662,6 @@ static int bgmac_mii_register(struct bgm
err = PTR_ERR(phy_dev);
goto err_unregister_bus;
}
+++ /dev/null
-From d2b13233879ca1268a1c027d4573109e5a777811 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Thu, 23 Jun 2016 14:23:12 -0700
-Subject: [PATCH 1/3] net: bgmac: Fix SOF bit checking
-
-We are checking for the Start of Frame bit in the ctl1 word, while this
-bit is set in the ctl0 word instead. Read the ctl0 word and update the
-check to verify that.
-
-Fixes: 9cde94506eac ("bgmac: implement scatter/gather support")
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -269,15 +269,16 @@ static void bgmac_dma_tx_free(struct bgm
- while (ring->start != ring->end) {
- int slot_idx = ring->start % BGMAC_TX_RING_SLOTS;
- struct bgmac_slot_info *slot = &ring->slots[slot_idx];
-- u32 ctl1;
-+ u32 ctl0, ctl1;
- int len;
-
- if (slot_idx == empty_slot)
- break;
-
-+ ctl0 = le32_to_cpu(ring->cpu_base[slot_idx].ctl0);
- ctl1 = le32_to_cpu(ring->cpu_base[slot_idx].ctl1);
- len = ctl1 & BGMAC_DESC_CTL1_LEN;
-- if (ctl1 & BGMAC_DESC_CTL0_SOF)
-+ if (ctl0 & BGMAC_DESC_CTL0_SOF)
- /* Unmap no longer used buffer */
- dma_unmap_single(dma_dev, slot->dma_addr, len,
- DMA_TO_DEVICE);
+++ /dev/null
-From c3897f2a69e54dd113fc9abd2daf872e5b495798 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Thu, 23 Jun 2016 14:25:32 -0700
-Subject: [PATCH 2/3] net: bgmac: Start transmit queue in bgmac_open
-
-The driver does not start the transmit queue in bgmac_open(). If the
-queue was stopped prior to closing then re-opening the interface, we
-would never be able to wake-up again.
-
-Fixes: dd4544f05469 ("bgmac: driver for GBit MAC core on BCMA bus")
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -1327,6 +1327,9 @@ static int bgmac_open(struct net_device
- phy_start(net_dev->phydev);
-
- netif_carrier_on(net_dev);
-+
-+ netif_start_queue(net_dev);
-+
- return 0;
- }
-
+++ /dev/null
-From 3894396e64994f31c3ef5c7e6f63dded0593e567 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Thu, 23 Jun 2016 14:25:33 -0700
-Subject: [PATCH 3/3] net: bgmac: Remove superflous netif_carrier_on()
-
-bgmac_open() calls phy_start() to initialize the PHY state machine,
-which will set the interface's carrier state accordingly, no need to
-force that as this could be conflicting with the PHY state determined by
-PHYLIB.
-
-Fixes: dd4544f05469 ("bgmac: driver for GBit MAC core on BCMA bus")
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.c
-+++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -1326,8 +1326,6 @@ static int bgmac_open(struct net_device
-
- phy_start(net_dev->phydev);
-
-- netif_carrier_on(net_dev);
--
- netif_start_queue(net_dev);
-
- return 0;
+++ /dev/null
-From aa8863e5d49417094b9457a0d53e8505e95a1863 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 31 Jan 2017 19:37:55 +0100
-Subject: [PATCH 2/3] net: bgmac: drop struct bcma_mdio we don't need anymore
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Adding struct bcma_mdio was a workaround for bcma code not having access
-to the struct bgmac used in the core code. Now we don't duplicate this
-struct we can just use it internally in bcma code.
-
-This simplifies code & allows access to all bgmac driver details from
-all places in bcma code.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 98 ++++++++++---------------
- drivers/net/ethernet/broadcom/bgmac-bcma.c | 2 +-
- drivers/net/ethernet/broadcom/bgmac.h | 2 +-
- 3 files changed, 42 insertions(+), 60 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
-@@ -12,11 +12,6 @@
- #include <linux/brcmphy.h>
- #include "bgmac.h"
-
--struct bcma_mdio {
-- struct bcma_device *core;
-- u8 phyaddr;
--};
--
- static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask,
- u32 value, int timeout)
- {
-@@ -37,7 +32,7 @@ static bool bcma_mdio_wait_value(struct
- * PHY ops
- **************************************************/
-
--static u16 bcma_mdio_phy_read(struct bcma_mdio *bcma_mdio, u8 phyaddr, u8 reg)
-+static u16 bcma_mdio_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
- {
- struct bcma_device *core;
- u16 phy_access_addr;
-@@ -56,12 +51,12 @@ static u16 bcma_mdio_phy_read(struct bcm
- BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
- BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
-
-- if (bcma_mdio->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
-- core = bcma_mdio->core->bus->drv_gmac_cmn.core;
-+ if (bgmac->bcma.core->id.id == BCMA_CORE_4706_MAC_GBIT) {
-+ core = bgmac->bcma.core->bus->drv_gmac_cmn.core;
- phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
- phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
- } else {
-- core = bcma_mdio->core;
-+ core = bgmac->bcma.core;
- phy_access_addr = BGMAC_PHY_ACCESS;
- phy_ctl_addr = BGMAC_PHY_CNTL;
- }
-@@ -87,7 +82,7 @@ static u16 bcma_mdio_phy_read(struct bcm
- }
-
- /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
--static int bcma_mdio_phy_write(struct bcma_mdio *bcma_mdio, u8 phyaddr, u8 reg,
-+static int bcma_mdio_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg,
- u16 value)
- {
- struct bcma_device *core;
-@@ -95,12 +90,12 @@ static int bcma_mdio_phy_write(struct bc
- u16 phy_ctl_addr;
- u32 tmp;
-
-- if (bcma_mdio->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
-- core = bcma_mdio->core->bus->drv_gmac_cmn.core;
-+ if (bgmac->bcma.core->id.id == BCMA_CORE_4706_MAC_GBIT) {
-+ core = bgmac->bcma.core->bus->drv_gmac_cmn.core;
- phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
- phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
- } else {
-- core = bcma_mdio->core;
-+ core = bgmac->bcma.core;
- phy_access_addr = BGMAC_PHY_ACCESS;
- phy_ctl_addr = BGMAC_PHY_CNTL;
- }
-@@ -110,8 +105,8 @@ static int bcma_mdio_phy_write(struct bc
- tmp |= phyaddr;
- bcma_write32(core, phy_ctl_addr, tmp);
-
-- bcma_write32(bcma_mdio->core, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
-- if (bcma_read32(bcma_mdio->core, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
-+ bcma_write32(bgmac->bcma.core, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
-+ if (bcma_read32(bgmac->bcma.core, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
- dev_warn(&core->dev, "Error setting MDIO int\n");
-
- tmp = BGMAC_PA_START;
-@@ -132,39 +127,39 @@ static int bcma_mdio_phy_write(struct bc
- }
-
- /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
--static void bcma_mdio_phy_init(struct bcma_mdio *bcma_mdio)
-+static void bcma_mdio_phy_init(struct bgmac *bgmac)
- {
-- struct bcma_chipinfo *ci = &bcma_mdio->core->bus->chipinfo;
-+ struct bcma_chipinfo *ci = &bgmac->bcma.core->bus->chipinfo;
- u8 i;
-
- if (ci->id == BCMA_CHIP_ID_BCM5356) {
- for (i = 0; i < 5; i++) {
-- bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x008b);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x15, 0x0100);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000f);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x12, 0x2aaa);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000b);
-+ bcma_mdio_phy_write(bgmac, i, 0x1f, 0x008b);
-+ bcma_mdio_phy_write(bgmac, i, 0x15, 0x0100);
-+ bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000f);
-+ bcma_mdio_phy_write(bgmac, i, 0x12, 0x2aaa);
-+ bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000b);
- }
- }
- if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
- (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
- (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
-- struct bcma_drv_cc *cc = &bcma_mdio->core->bus->drv_cc;
-+ struct bcma_drv_cc *cc = &bgmac->bcma.core->bus->drv_cc;
-
- bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
- bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
- for (i = 0; i < 5; i++) {
-- bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000f);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x16, 0x5284);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000b);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x0010);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000f);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x16, 0x5296);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x1073);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x9073);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x16, 0x52b6);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x9273);
-- bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000b);
-+ bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000f);
-+ bcma_mdio_phy_write(bgmac, i, 0x16, 0x5284);
-+ bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000b);
-+ bcma_mdio_phy_write(bgmac, i, 0x17, 0x0010);
-+ bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000f);
-+ bcma_mdio_phy_write(bgmac, i, 0x16, 0x5296);
-+ bcma_mdio_phy_write(bgmac, i, 0x17, 0x1073);
-+ bcma_mdio_phy_write(bgmac, i, 0x17, 0x9073);
-+ bcma_mdio_phy_write(bgmac, i, 0x16, 0x52b6);
-+ bcma_mdio_phy_write(bgmac, i, 0x17, 0x9273);
-+ bcma_mdio_phy_write(bgmac, i, 0x1f, 0x000b);
- }
- }
- }
-@@ -172,17 +167,17 @@ static void bcma_mdio_phy_init(struct bc
- /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
- static int bcma_mdio_phy_reset(struct mii_bus *bus)
- {
-- struct bcma_mdio *bcma_mdio = bus->priv;
-- u8 phyaddr = bcma_mdio->phyaddr;
-+ struct bgmac *bgmac = bus->priv;
-+ u8 phyaddr = bgmac->phyaddr;
-
-- if (bcma_mdio->phyaddr == BGMAC_PHY_NOREGS)
-+ if (phyaddr == BGMAC_PHY_NOREGS)
- return 0;
-
-- bcma_mdio_phy_write(bcma_mdio, phyaddr, MII_BMCR, BMCR_RESET);
-+ bcma_mdio_phy_write(bgmac, phyaddr, MII_BMCR, BMCR_RESET);
- udelay(100);
-- if (bcma_mdio_phy_read(bcma_mdio, phyaddr, MII_BMCR) & BMCR_RESET)
-- dev_err(&bcma_mdio->core->dev, "PHY reset failed\n");
-- bcma_mdio_phy_init(bcma_mdio);
-+ if (bcma_mdio_phy_read(bgmac, phyaddr, MII_BMCR) & BMCR_RESET)
-+ dev_err(bgmac->dev, "PHY reset failed\n");
-+ bcma_mdio_phy_init(bgmac);
-
- return 0;
- }
-@@ -202,16 +197,12 @@ static int bcma_mdio_mii_write(struct mi
- return bcma_mdio_phy_write(bus->priv, mii_id, regnum, value);
- }
-
--struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr)
-+struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac)
- {
-- struct bcma_mdio *bcma_mdio;
-+ struct bcma_device *core = bgmac->bcma.core;
- struct mii_bus *mii_bus;
- int i, err;
-
-- bcma_mdio = kzalloc(sizeof(*bcma_mdio), GFP_KERNEL);
-- if (!bcma_mdio)
-- return ERR_PTR(-ENOMEM);
--
- mii_bus = mdiobus_alloc();
- if (!mii_bus) {
- err = -ENOMEM;
-@@ -221,12 +212,12 @@ struct mii_bus *bcma_mdio_mii_register(s
- mii_bus->name = "bcma_mdio mii bus";
- sprintf(mii_bus->id, "%s-%d-%d", "bcma_mdio", core->bus->num,
- core->core_unit);
-- mii_bus->priv = bcma_mdio;
-+ mii_bus->priv = bgmac;
- mii_bus->read = bcma_mdio_mii_read;
- mii_bus->write = bcma_mdio_mii_write;
- mii_bus->reset = bcma_mdio_phy_reset;
- mii_bus->parent = &core->dev;
-- mii_bus->phy_mask = ~(1 << phyaddr);
-+ mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
-
- mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
- if (!mii_bus->irq) {
-@@ -236,9 +227,6 @@ struct mii_bus *bcma_mdio_mii_register(s
- for (i = 0; i < PHY_MAX_ADDR; i++)
- mii_bus->irq[i] = PHY_POLL;
-
-- bcma_mdio->core = core;
-- bcma_mdio->phyaddr = phyaddr;
--
- err = mdiobus_register(mii_bus);
- if (err) {
- dev_err(&core->dev, "Registration of mii bus failed\n");
-@@ -252,24 +240,18 @@ err_free_irq:
- err_free_bus:
- mdiobus_free(mii_bus);
- err:
-- kfree(bcma_mdio);
- return ERR_PTR(err);
- }
- EXPORT_SYMBOL_GPL(bcma_mdio_mii_register);
-
- void bcma_mdio_mii_unregister(struct mii_bus *mii_bus)
- {
-- struct bcma_mdio *bcma_mdio;
--
- if (!mii_bus)
- return;
-
-- bcma_mdio = mii_bus->priv;
--
- mdiobus_unregister(mii_bus);
- kfree(mii_bus->irq);
- mdiobus_free(mii_bus);
-- kfree(bcma_mdio);
- }
- EXPORT_SYMBOL_GPL(bcma_mdio_mii_unregister);
-
---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
-+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
-@@ -159,7 +159,7 @@ static int bgmac_probe(struct bcma_devic
-
- if (!bgmac_is_bcm4707_family(core) &&
- !(ci->id == BCMA_CHIP_ID_BCM53573 && core->core_unit == 1)) {
-- mii_bus = bcma_mdio_mii_register(core, bgmac->phyaddr);
-+ mii_bus = bcma_mdio_mii_register(bgmac);
- if (IS_ERR(mii_bus)) {
- err = PTR_ERR(mii_bus);
- goto err;
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -519,7 +519,7 @@ struct bgmac *bgmac_alloc(struct device
- int bgmac_enet_probe(struct bgmac *bgmac);
- void bgmac_enet_remove(struct bgmac *bgmac);
-
--struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr);
-+struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac);
- void bcma_mdio_mii_unregister(struct mii_bus *mii_bus);
-
- static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset)
+++ /dev/null
-From a7b221d8f0d75511c5f959584712a5dd35f88a86 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Mon, 18 Apr 2016 14:39:30 +0200
-Subject: [PATCH] spi: bcm53xx: add spi_flash_read callback for MMIO-based
- reads
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This implements more efficient reads of SPI-attached flash content.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
-
---- a/drivers/spi/spi-bcm53xx.c
-+++ b/drivers/spi/spi-bcm53xx.c
-@@ -10,6 +10,7 @@
- #include "spi-bcm53xx.h"
-
- #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
-+#define BCM53XXSPI_FLASH_WINDOW SZ_32M
-
- /* The longest observed required wait was 19 ms */
- #define BCM53XXSPI_SPE_TIMEOUT_MS 80
-@@ -17,8 +18,10 @@
- struct bcm53xxspi {
- struct bcma_device *core;
- struct spi_master *master;
-+ void __iomem *mmio_base;
-
- size_t read_offset;
-+ bool bspi; /* Boot SPI mode with memory mapping */
- };
-
- static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset)
-@@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(stru
- bcma_write32(b53spi->core, offset, value);
- }
-
-+static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi)
-+{
-+ struct device *dev = &b53spi->core->dev;
-+ unsigned long deadline;
-+ u32 tmp;
-+
-+ if (!b53spi->bspi)
-+ return;
-+
-+ tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
-+ if (tmp & 0x1)
-+ return;
-+
-+ deadline = jiffies + usecs_to_jiffies(200);
-+ do {
-+ tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS);
-+ if (!(tmp & 0x1)) {
-+ bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL,
-+ 0x1);
-+ ndelay(200);
-+ b53spi->bspi = false;
-+ return;
-+ }
-+ udelay(1);
-+ } while (!time_after_eq(jiffies, deadline));
-+
-+ dev_warn(dev, "Timeout disabling BSPI\n");
-+}
-+
-+static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi)
-+{
-+ u32 tmp;
-+
-+ if (b53spi->bspi)
-+ return;
-+
-+ tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL);
-+ if (!(tmp & 0x1))
-+ return;
-+
-+ bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0);
-+ b53spi->bspi = true;
-+}
-+
- static inline unsigned int bcm53xxspi_calc_timeout(size_t len)
- {
- /* Do some magic calculation based on length and buad. Add 10% and 1. */
-@@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struc
- u8 *buf;
- size_t left;
-
-+ bcm53xxspi_disable_bspi(b53spi);
-+
- if (t->tx_buf) {
- buf = (u8 *)t->tx_buf;
- left = t->len;
-@@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struc
- return 0;
- }
-
-+static int bcm53xxspi_flash_read(struct spi_device *spi,
-+ struct spi_flash_read_message *msg)
-+{
-+ struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master);
-+ int ret = 0;
-+
-+ if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW)
-+ return -EINVAL;
-+
-+ bcm53xxspi_enable_bspi(b53spi);
-+ memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len);
-+ msg->retlen = msg->len;
-+
-+ return ret;
-+}
-+
- /**************************************************
- * BCMA
- **************************************************/
-@@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcm
-
- static int bcm53xxspi_bcma_probe(struct bcma_device *core)
- {
-+ struct device *dev = &core->dev;
- struct bcm53xxspi *b53spi;
- struct spi_master *master;
- int err;
-@@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct
- return -ENOTSUPP;
- }
-
-- master = spi_alloc_master(&core->dev, sizeof(*b53spi));
-+ master = spi_alloc_master(dev, sizeof(*b53spi));
- if (!master)
- return -ENOMEM;
-
-@@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct
- b53spi->master = master;
- b53spi->core = core;
-
-+ if (core->addr_s[0])
-+ b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0],
-+ BCM53XXSPI_FLASH_WINDOW);
-+ b53spi->bspi = true;
-+ bcm53xxspi_disable_bspi(b53spi);
-+
- master->transfer_one = bcm53xxspi_transfer_one;
-+ if (b53spi->mmio_base)
-+ master->spi_flash_read = bcm53xxspi_flash_read;
-
- bcma_set_drvdata(core, b53spi);
-
-- err = devm_spi_register_master(&core->dev, master);
-+ err = devm_spi_register_master(dev, master);
- if (err) {
- spi_master_put(master);
- bcma_set_drvdata(core, NULL);
--- /dev/null
+From 4f04c210d031667e503d6538a72345a36f3b5d71 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 8 Jun 2017 18:08:32 +0200
+Subject: [PATCH] usb: core: read USB ports from DT in the usbport LED trigger
+ driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This uses DT info to read relation description of LEDs and USB ports. If
+DT has properly described LEDs, trigger will know when to turn them on.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/ledtrig-usbport.c | 56 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/usb/core/ledtrig-usbport.c
++++ b/drivers/usb/core/ledtrig-usbport.c
+@@ -11,8 +11,10 @@
+ #include <linux/device.h>
+ #include <linux/leds.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/slab.h>
+ #include <linux/usb.h>
++#include <linux/usb/of.h>
+
+ struct usbport_trig_data {
+ struct led_classdev *led_cdev;
+@@ -123,6 +125,57 @@ static const struct attribute_group port
+ * Adding & removing ports
+ ***************************************/
+
++/**
++ * usbport_trig_port_observed - Check if port should be observed
++ */
++static bool usbport_trig_port_observed(struct usbport_trig_data *usbport_data,
++ struct usb_device *usb_dev, int port1)
++{
++ struct device *dev = usbport_data->led_cdev->dev;
++ struct device_node *led_np = dev->of_node;
++ struct of_phandle_args args;
++ struct device_node *port_np;
++ int count, i;
++
++ if (!led_np)
++ return false;
++
++ /* Get node of port being added */
++ port_np = usb_of_get_child_node(usb_dev->dev.of_node, port1);
++ if (!port_np)
++ return false;
++
++ /* Amount of trigger sources for this LED */
++ count = of_count_phandle_with_args(led_np, "trigger-sources",
++ "#trigger-source-cells");
++ if (count < 0) {
++ dev_warn(dev, "Failed to get trigger sources for %s\n",
++ led_np->full_name);
++ return false;
++ }
++
++ /* Check list of sources for this specific port */
++ for (i = 0; i < count; i++) {
++ int err;
++
++ err = of_parse_phandle_with_args(led_np, "trigger-sources",
++ "#trigger-source-cells", i,
++ &args);
++ if (err) {
++ dev_err(dev, "Failed to get trigger source phandle at index %d: %d\n",
++ i, err);
++ continue;
++ }
++
++ of_node_put(args.np);
++
++ if (args.np == port_np)
++ return true;
++ }
++
++ return false;
++}
++
+ static int usbport_trig_add_port(struct usbport_trig_data *usbport_data,
+ struct usb_device *usb_dev,
+ const char *hub_name, int portnum)
+@@ -141,6 +194,8 @@ static int usbport_trig_add_port(struct
+ port->data = usbport_data;
+ port->hub = usb_dev;
+ port->portnum = portnum;
++ port->observed = usbport_trig_port_observed(usbport_data, usb_dev,
++ portnum);
+
+ len = strlen(hub_name) + 8;
+ port->port_name = kzalloc(len, GFP_KERNEL);
+@@ -255,6 +310,7 @@ static void usbport_trig_activate(struct
+ if (err)
+ goto err_free;
+ usb_for_each_dev(usbport_data, usbport_trig_add_usb_dev_ports);
++ usbport_trig_update_count(usbport_data);
+
+ /* Notifications */
+ usbport_data->nb.notifier_call = usbport_trig_notify,
--- /dev/null
+From 68620e594c250ba8c43a78e77f5296cb9952582e Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 14 Sep 2016 20:54:12 +0200
+Subject: [PATCH] leds: gpio: introduce gpio_blink_set_t
+
+Introduce a typedef gpio_blink_set_t to improve readability of the code.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+---
+ drivers/leds/leds-gpio.c | 6 ++----
+ include/linux/leds.h | 9 ++++++---
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/leds/leds-gpio.c
++++ b/drivers/leds/leds-gpio.c
+@@ -29,8 +29,7 @@ struct gpio_led_data {
+ u8 new_level;
+ u8 can_sleep;
+ u8 blinking;
+- int (*platform_gpio_blink_set)(struct gpio_desc *desc, int state,
+- unsigned long *delay_on, unsigned long *delay_off);
++ gpio_blink_set_t platform_gpio_blink_set;
+ };
+
+ static void gpio_led_work(struct work_struct *work)
+@@ -88,8 +87,7 @@ static int gpio_blink_set(struct led_cla
+
+ static int create_gpio_led(const struct gpio_led *template,
+ struct gpio_led_data *led_dat, struct device *parent,
+- int (*blink_set)(struct gpio_desc *, int, unsigned long *,
+- unsigned long *))
++ gpio_blink_set_t blink_set)
+ {
+ int ret, state;
+
+--- a/include/linux/leds.h
++++ b/include/linux/leds.h
+@@ -330,6 +330,11 @@ struct led_platform_data {
+ struct led_info *leds;
+ };
+
++struct gpio_desc;
++typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state,
++ unsigned long *delay_on,
++ unsigned long *delay_off);
++
+ /* For the leds-gpio driver */
+ struct gpio_led {
+ const char *name;
+@@ -352,9 +357,7 @@ struct gpio_led_platform_data {
+ #define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */
+ #define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */
+ #define GPIO_LED_BLINK 2 /* Please, blink */
+- int (*gpio_blink_set)(struct gpio_desc *desc, int state,
+- unsigned long *delay_on,
+- unsigned long *delay_off);
++ gpio_blink_set_t gpio_blink_set;
+ };
+
+ struct platform_device *gpio_led_register_device(
--- /dev/null
+From bc2c0dd85a0a31505ca2f92bef891ddac9126725 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 14 Sep 2016 20:55:27 +0200
+Subject: [PATCH] leds: gpio: switch to managed version of
+ led_classdev_register
+
+Using the managed version of led_classdev_register allows to
+significantly simplify the code.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+---
+ drivers/leds/leds-gpio.c | 23 ++---------------------
+ 1 file changed, 2 insertions(+), 21 deletions(-)
+
+--- a/drivers/leds/leds-gpio.c
++++ b/drivers/leds/leds-gpio.c
+@@ -143,7 +143,7 @@ static int create_gpio_led(const struct
+
+ INIT_WORK(&led_dat->work, gpio_led_work);
+
+- return led_classdev_register(parent, &led_dat->cdev);
++ return devm_led_classdev_register(parent, &led_dat->cdev);
+ }
+
+ static void delete_gpio_led(struct gpio_led_data *led)
+@@ -231,8 +231,6 @@ static struct gpio_leds_priv *gpio_leds_
+ return priv;
+
+ err:
+- for (count = priv->num_leds - 1; count >= 0; count--)
+- delete_gpio_led(&priv->leds[count]);
+ return ERR_PTR(ret);
+ }
+
+@@ -261,12 +259,8 @@ static int gpio_led_probe(struct platfor
+ ret = create_gpio_led(&pdata->leds[i],
+ &priv->leds[i],
+ &pdev->dev, pdata->gpio_blink_set);
+- if (ret < 0) {
+- /* On failure: unwind the led creations */
+- for (i = i - 1; i >= 0; i--)
+- delete_gpio_led(&priv->leds[i]);
++ if (ret < 0)
+ return ret;
+- }
+ }
+ } else {
+ priv = gpio_leds_create(pdev);
+@@ -279,17 +273,6 @@ static int gpio_led_probe(struct platfor
+ return 0;
+ }
+
+-static int gpio_led_remove(struct platform_device *pdev)
+-{
+- struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
+- int i;
+-
+- for (i = 0; i < priv->num_leds; i++)
+- delete_gpio_led(&priv->leds[i]);
+-
+- return 0;
+-}
+-
+ static void gpio_led_shutdown(struct platform_device *pdev)
+ {
+ struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
+@@ -304,7 +287,6 @@ static void gpio_led_shutdown(struct pla
+
+ static struct platform_driver gpio_led_driver = {
+ .probe = gpio_led_probe,
+- .remove = gpio_led_remove,
+ .shutdown = gpio_led_shutdown,
+ .driver = {
+ .name = "leds-gpio",
--- /dev/null
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 6 Mar 2017 06:19:44 +0100
+Subject: [PATCH] leds: core: add OF variants of LED registering functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These new functions allow passing an additional device_node argument
+that will be internally set for created LED device. Thanks to this LED
+core code and triggers will be able to access DT node for reading extra
+info.
+
+The easiest solution for achieving this was reworking old functions to
+more generic ones & adding simple defines for API compatibility.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+---
+ drivers/leds/led-class.c | 26 ++++++++++++++++----------
+ include/linux/leds.h | 14 ++++++++++----
+ 2 files changed, 26 insertions(+), 14 deletions(-)
+
+--- a/drivers/leds/led-class.c
++++ b/drivers/leds/led-class.c
+@@ -181,11 +181,14 @@ static int led_classdev_next_name(const
+ }
+
+ /**
+- * led_classdev_register - register a new object of led_classdev class.
+- * @parent: The device to register.
++ * of_led_classdev_register - register a new object of led_classdev class.
++ *
++ * @parent: parent of LED device
+ * @led_cdev: the led_classdev structure for this device.
++ * @np: DT node describing this LED
+ */
+-int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
++int of_led_classdev_register(struct device *parent, struct device_node *np,
++ struct led_classdev *led_cdev)
+ {
+ char name[64];
+ int ret;
+@@ -198,6 +201,7 @@ int led_classdev_register(struct device
+ led_cdev, led_cdev->groups, "%s", name);
+ if (IS_ERR(led_cdev->dev))
+ return PTR_ERR(led_cdev->dev);
++ led_cdev->dev->of_node = np;
+
+ if (ret)
+ dev_warn(parent, "Led %s renamed to %s due to name collision",
+@@ -230,7 +234,7 @@ int led_classdev_register(struct device
+
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(led_classdev_register);
++EXPORT_SYMBOL_GPL(of_led_classdev_register);
+
+ /**
+ * led_classdev_unregister - unregisters a object of led_properties class.
+@@ -269,12 +273,14 @@ static void devm_led_classdev_release(st
+ }
+
+ /**
+- * devm_led_classdev_register - resource managed led_classdev_register()
+- * @parent: The device to register.
++ * devm_of_led_classdev_register - resource managed led_classdev_register()
++ *
++ * @parent: parent of LED device
+ * @led_cdev: the led_classdev structure for this device.
+ */
+-int devm_led_classdev_register(struct device *parent,
+- struct led_classdev *led_cdev)
++int devm_of_led_classdev_register(struct device *parent,
++ struct device_node *np,
++ struct led_classdev *led_cdev)
+ {
+ struct led_classdev **dr;
+ int rc;
+@@ -283,7 +289,7 @@ int devm_led_classdev_register(struct de
+ if (!dr)
+ return -ENOMEM;
+
+- rc = led_classdev_register(parent, led_cdev);
++ rc = of_led_classdev_register(parent, np, led_cdev);
+ if (rc) {
+ devres_free(dr);
+ return rc;
+@@ -294,7 +300,7 @@ int devm_led_classdev_register(struct de
+
+ return 0;
+ }
+-EXPORT_SYMBOL_GPL(devm_led_classdev_register);
++EXPORT_SYMBOL_GPL(devm_of_led_classdev_register);
+
+ static int devm_led_classdev_match(struct device *dev, void *res, void *data)
+ {
+--- a/include/linux/leds.h
++++ b/include/linux/leds.h
+@@ -103,10 +103,16 @@ struct led_classdev {
+ struct mutex led_access;
+ };
+
+-extern int led_classdev_register(struct device *parent,
+- struct led_classdev *led_cdev);
+-extern int devm_led_classdev_register(struct device *parent,
+- struct led_classdev *led_cdev);
++extern int of_led_classdev_register(struct device *parent,
++ struct device_node *np,
++ struct led_classdev *led_cdev);
++#define led_classdev_register(parent, led_cdev) \
++ of_led_classdev_register(parent, NULL, led_cdev)
++extern int devm_of_led_classdev_register(struct device *parent,
++ struct device_node *np,
++ struct led_classdev *led_cdev);
++#define devm_led_classdev_register(parent, led_cdev) \
++ devm_of_led_classdev_register(parent, NULL, led_cdev)
+ extern void led_classdev_unregister(struct led_classdev *led_cdev);
+ extern void devm_led_classdev_unregister(struct device *parent,
+ struct led_classdev *led_cdev);
--- /dev/null
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 6 Mar 2017 06:19:45 +0100
+Subject: [PATCH] leds: gpio: use OF variant of LED registering function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In leds-gpio we support LEDs specified in DT so we should use
+(devm_)of_led_classdev_register. This allows passing DT node as argument
+for use by the LED subsystem.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+---
+ drivers/leds/leds-gpio.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/leds/leds-gpio.c
++++ b/drivers/leds/leds-gpio.c
+@@ -87,7 +87,7 @@ static int gpio_blink_set(struct led_cla
+
+ static int create_gpio_led(const struct gpio_led *template,
+ struct gpio_led_data *led_dat, struct device *parent,
+- gpio_blink_set_t blink_set)
++ struct device_node *np, gpio_blink_set_t blink_set)
+ {
+ int ret, state;
+
+@@ -143,7 +143,7 @@ static int create_gpio_led(const struct
+
+ INIT_WORK(&led_dat->work, gpio_led_work);
+
+- return devm_led_classdev_register(parent, &led_dat->cdev);
++ return devm_of_led_classdev_register(parent, np, &led_dat->cdev);
+ }
+
+ static void delete_gpio_led(struct gpio_led_data *led)
+@@ -219,7 +219,7 @@ static struct gpio_leds_priv *gpio_leds_
+ if (fwnode_property_present(child, "retain-state-suspended"))
+ led.retain_state_suspended = 1;
+
+- ret = create_gpio_led(&led, led_dat, dev, NULL);
++ ret = create_gpio_led(&led, led_dat, dev, np, NULL);
+ if (ret < 0) {
+ fwnode_handle_put(child);
+ goto err;
+@@ -256,9 +256,9 @@ static int gpio_led_probe(struct platfor
+
+ priv->num_leds = pdata->num_leds;
+ for (i = 0; i < priv->num_leds; i++) {
+- ret = create_gpio_led(&pdata->leds[i],
+- &priv->leds[i],
+- &pdev->dev, pdata->gpio_blink_set);
++ ret = create_gpio_led(&pdata->leds[i], &priv->leds[i],
++ &pdev->dev, NULL,
++ pdata->gpio_blink_set);
+ if (ret < 0)
+ return ret;
+ }
--- /dev/null
+From e498b4984db82b4ba3ceea7dba813222a31e9c2e Mon Sep 17 00:00:00 2001
+From: Laxman Dewangan <ldewangan@nvidia.com>
+Date: Wed, 9 Mar 2016 18:40:06 +0530
+Subject: [PATCH] thermal: of-thermal: Add devm version of
+ thermal_zone_of_sensor_register
+
+Add resource managed version of thermal_zone_of_sensor_register() and
+thermal_zone_of_sensor_unregister().
+
+This helps in reducing the code size in error path, remove of
+driver remove callbacks and making proper sequence for deallocations.
+
+Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+---
+ drivers/thermal/of-thermal.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/thermal.h | 18 ++++++++++
+ 2 files changed, 99 insertions(+)
+
+--- a/drivers/thermal/of-thermal.c
++++ b/drivers/thermal/of-thermal.c
+@@ -559,6 +559,87 @@ void thermal_zone_of_sensor_unregister(s
+ }
+ EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister);
+
++static void devm_thermal_zone_of_sensor_release(struct device *dev, void *res)
++{
++ thermal_zone_of_sensor_unregister(dev,
++ *(struct thermal_zone_device **)res);
++}
++
++static int devm_thermal_zone_of_sensor_match(struct device *dev, void *res,
++ void *data)
++{
++ struct thermal_zone_device **r = res;
++
++ if (WARN_ON(!r || !*r))
++ return 0;
++
++ return *r == data;
++}
++
++/**
++ * devm_thermal_zone_of_sensor_register - Resource managed version of
++ * thermal_zone_of_sensor_register()
++ * @dev: a valid struct device pointer of a sensor device. Must contain
++ * a valid .of_node, for the sensor node.
++ * @sensor_id: a sensor identifier, in case the sensor IP has more
++ * than one sensors
++ * @data: a private pointer (owned by the caller) that will be passed
++ * back, when a temperature reading is needed.
++ * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp.
++ *
++ * Refer thermal_zone_of_sensor_register() for more details.
++ *
++ * Return: On success returns a valid struct thermal_zone_device,
++ * otherwise, it returns a corresponding ERR_PTR(). Caller must
++ * check the return value with help of IS_ERR() helper.
++ * Registered hermal_zone_device device will automatically be
++ * released when device is unbounded.
++ */
++struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
++ struct device *dev, int sensor_id,
++ void *data, const struct thermal_zone_of_device_ops *ops)
++{
++ struct thermal_zone_device **ptr, *tzd;
++
++ ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr),
++ GFP_KERNEL);
++ if (!ptr)
++ return ERR_PTR(-ENOMEM);
++
++ tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops);
++ if (IS_ERR(tzd)) {
++ devres_free(ptr);
++ return tzd;
++ }
++
++ *ptr = tzd;
++ devres_add(dev, ptr);
++
++ return tzd;
++}
++EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_register);
++
++/**
++ * devm_thermal_zone_of_sensor_unregister - Resource managed version of
++ * thermal_zone_of_sensor_unregister().
++ * @dev: Device for which which resource was allocated.
++ * @tzd: a pointer to struct thermal_zone_device where the sensor is registered.
++ *
++ * This function removes the sensor callbacks and private data from the
++ * thermal zone device registered with devm_thermal_zone_of_sensor_register()
++ * API. It will also silent the zone by remove the .get_temp() and .get_trend()
++ * thermal zone device callbacks.
++ * Normally this function will not need to be called and the resource
++ * management code will ensure that the resource is freed.
++ */
++void devm_thermal_zone_of_sensor_unregister(struct device *dev,
++ struct thermal_zone_device *tzd)
++{
++ WARN_ON(devres_release(dev, devm_thermal_zone_of_sensor_release,
++ devm_thermal_zone_of_sensor_match, tzd));
++}
++EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
++
+ /*** functions parsing device tree nodes ***/
+
+ /**
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -364,6 +364,11 @@ thermal_zone_of_sensor_register(struct d
+ const struct thermal_zone_of_device_ops *ops);
+ void thermal_zone_of_sensor_unregister(struct device *dev,
+ struct thermal_zone_device *tz);
++struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
++ struct device *dev, int id, void *data,
++ const struct thermal_zone_of_device_ops *ops);
++void devm_thermal_zone_of_sensor_unregister(struct device *dev,
++ struct thermal_zone_device *tz);
+ #else
+ static inline struct thermal_zone_device *
+ thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
+@@ -378,6 +383,19 @@ void thermal_zone_of_sensor_unregister(s
+ {
+ }
+
++static inline struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
++ struct device *dev, int id, void *data,
++ const struct thermal_zone_of_device_ops *ops)
++{
++ return ERR_PTR(-ENODEV);
++}
++
++static inline
++void devm_thermal_zone_of_sensor_unregister(struct device *dev,
++ struct thermal_zone_device *tz)
++{
++}
++
+ #endif
+
+ #if IS_ENABLED(CONFIG_THERMAL)
--- /dev/null
+From 4a7069a32c99a81950de035535b0a064dcceaeba Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@codeaurora.org>
+Date: Thu, 5 May 2016 14:21:42 +0530
+Subject: [PATCH] thermal: core: export apis to get slope and offset
+
+Add apis for platform thermal drivers to query for slope and offset
+attributes, which might be needed for temperature calculations.
+
+Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+---
+ Documentation/thermal/sysfs-api.txt | 12 ++++++++++++
+ drivers/thermal/thermal_core.c | 30 ++++++++++++++++++++++++++++++
+ include/linux/thermal.h | 8 ++++++++
+ 3 files changed, 50 insertions(+)
+
+--- a/Documentation/thermal/sysfs-api.txt
++++ b/Documentation/thermal/sysfs-api.txt
+@@ -72,6 +72,18 @@ temperature) and throttle appropriate de
+ It deletes the corresponding entry form /sys/class/thermal folder and
+ unbind all the thermal cooling devices it uses.
+
++1.1.7 int thermal_zone_get_slope(struct thermal_zone_device *tz)
++
++ This interface is used to read the slope attribute value
++ for the thermal zone device, which might be useful for platform
++ drivers for temperature calculations.
++
++1.1.8 int thermal_zone_get_offset(struct thermal_zone_device *tz)
++
++ This interface is used to read the offset attribute value
++ for the thermal zone device, which might be useful for platform
++ drivers for temperature calculations.
++
+ 1.2 thermal cooling device interface
+ 1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name,
+ void *devdata, struct thermal_cooling_device_ops *)
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -2061,6 +2061,36 @@ exit:
+ }
+ EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
+
++/**
++ * thermal_zone_get_slope - return the slope attribute of the thermal zone
++ * @tz: thermal zone device with the slope attribute
++ *
++ * Return: If the thermal zone device has a slope attribute, return it, else
++ * return 1.
++ */
++int thermal_zone_get_slope(struct thermal_zone_device *tz)
++{
++ if (tz && tz->tzp)
++ return tz->tzp->slope;
++ return 1;
++}
++EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
++
++/**
++ * thermal_zone_get_offset - return the offset attribute of the thermal zone
++ * @tz: thermal zone device with the offset attribute
++ *
++ * Return: If the thermal zone device has a offset attribute, return it, else
++ * return 0.
++ */
++int thermal_zone_get_offset(struct thermal_zone_device *tz)
++{
++ if (tz && tz->tzp)
++ return tz->tzp->offset;
++ return 0;
++}
++EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
++
+ #ifdef CONFIG_NET
+ static const struct genl_multicast_group thermal_event_mcgrps[] = {
+ { .name = THERMAL_GENL_MCAST_GROUP_NAME, },
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -432,6 +432,8 @@ thermal_of_cooling_device_register(struc
+ void thermal_cooling_device_unregister(struct thermal_cooling_device *);
+ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
+ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
++int thermal_zone_get_slope(struct thermal_zone_device *tz);
++int thermal_zone_get_offset(struct thermal_zone_device *tz);
+
+ int get_tz_trend(struct thermal_zone_device *, int);
+ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
+@@ -489,6 +491,12 @@ static inline struct thermal_zone_device
+ static inline int thermal_zone_get_temp(
+ struct thermal_zone_device *tz, int *temp)
+ { return -ENODEV; }
++static inline int thermal_zone_get_slope(
++ struct thermal_zone_device *tz)
++{ return -ENODEV; }
++static inline int thermal_zone_get_offset(
++ struct thermal_zone_device *tz)
++{ return -ENODEV; }
+ static inline int get_tz_trend(struct thermal_zone_device *tz, int trip)
+ { return -ENODEV; }
+ static inline struct thermal_instance *
--- /dev/null
+From a94cb7eeecc4104a6874339f90c5d0647359c102 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 3 Apr 2017 17:48:29 +0200
+Subject: [PATCH] thermal: broadcom: add Northstar thermal driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Northstar is a SoC family commonly used in home routers. This commit
+adds a driver for checking CPU temperature. As Northstar Plus seems to
+also have this IP block this new symbol gets ARCH_BCM_IPROC dependency.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Jon Mason <jon.mason@broadcom.com>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+---
+ drivers/thermal/Kconfig | 5 ++
+ drivers/thermal/Makefile | 1 +
+ drivers/thermal/broadcom/Kconfig | 8 +++
+ drivers/thermal/broadcom/Makefile | 1 +
+ drivers/thermal/broadcom/ns-thermal.c | 105 ++++++++++++++++++++++++++++++++++
+ 5 files changed, 120 insertions(+)
+ create mode 100644 drivers/thermal/broadcom/Kconfig
+ create mode 100644 drivers/thermal/broadcom/Makefile
+ create mode 100644 drivers/thermal/broadcom/ns-thermal.c
+
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -365,6 +365,11 @@ config INTEL_PCH_THERMAL
+ Thermal reporting device will provide temperature reading,
+ programmable trip points and other information.
+
++menu "Broadcom thermal drivers"
++depends on ARCH_BCM || COMPILE_TEST
++source "drivers/thermal/broadcom/Kconfig"
++endmenu
++
+ menu "Texas Instruments thermal drivers"
+ depends on ARCH_HAS_BANDGAP || COMPILE_TEST
+ source "drivers/thermal/ti-soc-thermal/Kconfig"
+--- a/drivers/thermal/Makefile
++++ b/drivers/thermal/Makefile
+@@ -26,6 +26,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += c
+ thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
+
+ # platform thermal drivers
++obj-y += broadcom/
+ obj-$(CONFIG_QCOM_SPMI_TEMP_ALARM) += qcom-spmi-temp-alarm.o
+ obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
+ obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
+--- /dev/null
++++ b/drivers/thermal/broadcom/Kconfig
+@@ -0,0 +1,8 @@
++config BCM_NS_THERMAL
++ tristate "Northstar thermal driver"
++ depends on ARCH_BCM_IPROC || COMPILE_TEST
++ help
++ Northstar is a family of SoCs that includes e.g. BCM4708, BCM47081,
++ BCM4709 and BCM47094. It contains DMU (Device Management Unit) block
++ with a thermal sensor that allows checking CPU temperature. This
++ driver provides support for it.
+--- /dev/null
++++ b/drivers/thermal/broadcom/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_BCM_NS_THERMAL) += ns-thermal.o
+--- /dev/null
++++ b/drivers/thermal/broadcom/ns-thermal.c
+@@ -0,0 +1,105 @@
++/*
++ * Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/platform_device.h>
++#include <linux/thermal.h>
++
++#define PVTMON_CONTROL0 0x00
++#define PVTMON_CONTROL0_SEL_MASK 0x0000000e
++#define PVTMON_CONTROL0_SEL_TEMP_MONITOR 0x00000000
++#define PVTMON_CONTROL0_SEL_TEST_MODE 0x0000000e
++#define PVTMON_STATUS 0x08
++
++struct ns_thermal {
++ struct thermal_zone_device *tz;
++ void __iomem *pvtmon;
++};
++
++static int ns_thermal_get_temp(void *data, int *temp)
++{
++ struct ns_thermal *ns_thermal = data;
++ int offset = thermal_zone_get_offset(ns_thermal->tz);
++ int slope = thermal_zone_get_slope(ns_thermal->tz);
++ u32 val;
++
++ val = readl(ns_thermal->pvtmon + PVTMON_CONTROL0);
++ if ((val & PVTMON_CONTROL0_SEL_MASK) != PVTMON_CONTROL0_SEL_TEMP_MONITOR) {
++ /* Clear current mode selection */
++ val &= ~PVTMON_CONTROL0_SEL_MASK;
++
++ /* Set temp monitor mode (it's the default actually) */
++ val |= PVTMON_CONTROL0_SEL_TEMP_MONITOR;
++
++ writel(val, ns_thermal->pvtmon + PVTMON_CONTROL0);
++ }
++
++ val = readl(ns_thermal->pvtmon + PVTMON_STATUS);
++ *temp = slope * val + offset;
++
++ return 0;
++}
++
++static const struct thermal_zone_of_device_ops ns_thermal_ops = {
++ .get_temp = ns_thermal_get_temp,
++};
++
++static int ns_thermal_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct ns_thermal *ns_thermal;
++
++ ns_thermal = devm_kzalloc(dev, sizeof(*ns_thermal), GFP_KERNEL);
++ if (!ns_thermal)
++ return -ENOMEM;
++
++ ns_thermal->pvtmon = of_iomap(dev_of_node(dev), 0);
++ if (WARN_ON(!ns_thermal->pvtmon))
++ return -ENOENT;
++
++ ns_thermal->tz = devm_thermal_zone_of_sensor_register(dev, 0,
++ ns_thermal,
++ &ns_thermal_ops);
++ if (IS_ERR(ns_thermal->tz)) {
++ iounmap(ns_thermal->pvtmon);
++ return PTR_ERR(ns_thermal->tz);
++ }
++
++ platform_set_drvdata(pdev, ns_thermal);
++
++ return 0;
++}
++
++static int ns_thermal_remove(struct platform_device *pdev)
++{
++ struct ns_thermal *ns_thermal = platform_get_drvdata(pdev);
++
++ iounmap(ns_thermal->pvtmon);
++
++ return 0;
++}
++
++static const struct of_device_id ns_thermal_of_match[] = {
++ { .compatible = "brcm,ns-thermal", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ns_thermal_of_match);
++
++static struct platform_driver ns_thermal_driver = {
++ .probe = ns_thermal_probe,
++ .remove = ns_thermal_remove,
++ .driver = {
++ .name = "ns-thermal",
++ .of_match_table = ns_thermal_of_match,
++ },
++};
++module_platform_driver(ns_thermal_driver);
++
++MODULE_DESCRIPTION("Northstar thermal driver");
++MODULE_LICENSE("GPL v2");
--- /dev/null
+From d44264c8735f79da3253520024841311c555ca31 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Fri, 14 Apr 2017 22:25:12 +0200
+Subject: [PATCH] thermal: broadcom: fix compilation of Northstar driver
+
+---
+ drivers/thermal/broadcom/ns-thermal.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/thermal/broadcom/ns-thermal.c
++++ b/drivers/thermal/broadcom/ns-thermal.c
+@@ -6,6 +6,7 @@
+ * published by the Free Software Foundation.
+ */
+
++#include <asm/io.h>
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+ #include <linux/platform_device.h>
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
-@@ -5326,7 +5326,7 @@ static void __init_refok alloc_node_mem_
+@@ -5345,7 +5345,7 @@ static void __init_refok alloc_node_mem_
mem_map = NODE_DATA(0)->node_mem_map;
#if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM)
if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
+++ /dev/null
-From: Tobias Wolf <dev-NTEO@vplace.de>
-Date: Wed, 23 Nov 2016 10:40:07 +0100
-Subject: [PATCH] of: Add check to of_scan_flat_dt() before accessing
- initial_boot_params
-
-An empty __dtb_start to __dtb_end section might result in initial_boot_params
-being null for arch/mips/ralink. This showed that the boot process hangs
-indefinitely in of_scan_flat_dt().
-
-Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
----
-
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -632,9 +632,12 @@ int __init of_scan_flat_dt(int (*it)(uns
- const char *pathp;
- int offset, rc = 0, depth = -1;
-
-- for (offset = fdt_next_node(blob, -1, &depth);
-- offset >= 0 && depth >= 0 && !rc;
-- offset = fdt_next_node(blob, offset, &depth)) {
-+ if (!blob)
-+ return 0;
-+
-+ for (offset = fdt_next_node(blob, -1, &depth);
-+ offset >= 0 && depth >= 0 && !rc;
-+ offset = fdt_next_node(blob, offset, &depth)) {
-
- pathp = fdt_get_name(blob, offset, NULL);
- if (*pathp == '/')
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
-@@ -782,7 +782,7 @@ static int jffs2_rename (struct inode *o
+@@ -779,18 +779,31 @@ static int jffs2_rename (struct inode *o
+ int ret;
+ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
+ struct jffs2_inode_info *victim_f = NULL;
++ struct inode *fst_inode = d_inode(old_dentry);
++ struct inode *snd_inode = d_inode(new_dentry);
uint8_t type;
uint32_t now;
+ if (flags & ~(RENAME_WHITEOUT | RENAME_EXCHANGE))
return -EINVAL;
++ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) {
++ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) {
++ inc_nlink(new_dir_i);
++ drop_nlink(old_dir_i);
++ }
++ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) {
++ drop_nlink(new_dir_i);
++ inc_nlink(old_dir_i);
++ }
++ }
++
/* The VFS will check for us and prevent trying to rename a
-@@ -790,7 +790,7 @@ static int jffs2_rename (struct inode *o
+ * file over a directory and vice versa, but if it's a directory,
* the VFS can't check whether the victim is empty. The filesystem
* needs to do that for itself.
*/
victim_f = JFFS2_INODE_INFO(d_inode(new_dentry));
if (d_is_dir(new_dentry)) {
struct jffs2_full_dirent *fd;
-@@ -825,7 +825,7 @@ static int jffs2_rename (struct inode *o
+@@ -825,7 +838,7 @@ static int jffs2_rename (struct inode *o
if (ret)
return ret;
/* There was a victim. Kill it off nicely */
if (d_is_dir(new_dentry))
clear_nlink(d_inode(new_dentry));
-@@ -851,6 +851,12 @@ static int jffs2_rename (struct inode *o
+@@ -845,12 +858,18 @@ static int jffs2_rename (struct inode *o
+
+ /* If it was a directory we moved, and there was no victim,
+ increase i_nlink on its new parent */
+- if (d_is_dir(old_dentry) && !victim_f)
++ if (d_is_dir(old_dentry) && !victim_f && !(flags & RENAME_EXCHANGE))
+ inc_nlink(new_dir_i);
+
if (flags & RENAME_WHITEOUT)
/* Replace with whiteout */
ret = jffs2_whiteout(old_dir_i, old_dentry);
else
/* Unlink the original */
ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-@@ -882,7 +888,7 @@ static int jffs2_rename (struct inode *o
+@@ -882,7 +901,7 @@ static int jffs2_rename (struct inode *o
return ret;
}
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -217,11 +217,13 @@ EXPORT_SYMBOL_GPL(br_handle_frame_finish
+@@ -218,11 +218,13 @@ EXPORT_SYMBOL_GPL(br_handle_frame_finish
static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net_bridge_port *p = br_port_get_rcu(skb->dev);
return 0; /* process further */
}
-@@ -296,6 +298,18 @@ rx_handler_result_t br_handle_frame(stru
+@@ -297,6 +299,18 @@ rx_handler_result_t br_handle_frame(stru
forward:
switch (p->state) {
defect7374_enable_data_eps_zero(dev);
ep0_start(dev);
-@@ -3063,7 +3063,7 @@ static void handle_stat0_irqs(struct net
+@@ -3060,7 +3060,7 @@ static void handle_stat0_irqs(struct net
}
ep->stopped = 0;
dev->protocol_stall = 0;
if (ep->dev->quirks & PLX_2280)
tmp = BIT(FIFO_OVERFLOW) |
BIT(FIFO_UNDERFLOW);
-@@ -3090,7 +3090,7 @@ static void handle_stat0_irqs(struct net
+@@ -3087,7 +3087,7 @@ static void handle_stat0_irqs(struct net
cpu_to_le32s(&u.raw[0]);
cpu_to_le32s(&u.raw[1]);
defect7374_workaround(dev, u.r);
tmp = 0;
-@@ -3173,7 +3173,7 @@ static void handle_stat0_irqs(struct net
+@@ -3170,7 +3170,7 @@ static void handle_stat0_irqs(struct net
} else {
ep_vdbg(dev, "%s clear halt\n", e->ep.name);
clear_halt(e);
!list_empty(&e->queue) && e->td_dma)
restart_dma(e);
}
-@@ -3195,7 +3195,7 @@ static void handle_stat0_irqs(struct net
+@@ -3192,7 +3192,7 @@ static void handle_stat0_irqs(struct net
if (e->ep.name == ep0name)
goto do_stall;
set_halt(e);
abort_dma(e);
allow_status(ep);
ep_vdbg(dev, "%s set halt\n", ep->ep.name);
-@@ -3234,7 +3234,7 @@ do_stall:
+@@ -3231,7 +3231,7 @@ do_stall:
#undef w_length
next_endpoints:
u32 mask = (BIT(ENDPOINT_0_INTERRUPT) |
USB3380_IRQSTAT0_EP_INTR_MASK_IN |
USB3380_IRQSTAT0_EP_INTR_MASK_OUT);
-@@ -3399,7 +3399,7 @@ __acquires(dev->lock)
+@@ -3392,7 +3392,7 @@ static void handle_stat1_irqs(struct net
writel(tmp, &dma->dmastat);
/* dma sync*/
u32 r_dmacount = readl(&dma->dmacount);
if (!ep->is_in && (r_dmacount & 0x00FFFFFF) &&
(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT)))
-@@ -3468,7 +3468,7 @@ static irqreturn_t net2280_irq(int irq,
+@@ -3461,7 +3461,7 @@ static irqreturn_t net2280_irq(int irq,
/* control requests and PIO */
handle_stat0_irqs(dev, readl(&dev->regs->irqstat0));
/* re-enable interrupt to trigger any possible new interrupt */
u32 pciirqenb1 = readl(&dev->regs->pciirqenb1);
writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1);
-@@ -3513,7 +3513,7 @@ static void net2280_remove(struct pci_de
+@@ -3506,7 +3506,7 @@ static void net2280_remove(struct pci_de
}
if (dev->got_irq)
free_irq(pdev->irq, dev);
pci_disable_msi(pdev);
if (dev->regs)
iounmap(dev->regs);
-@@ -3593,7 +3593,7 @@ static int net2280_probe(struct pci_dev
+@@ -3586,7 +3586,7 @@ static int net2280_probe(struct pci_dev
dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200);
dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300);
u32 fsmvalue;
u32 usbstat;
dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *)
-@@ -3637,7 +3637,7 @@ static int net2280_probe(struct pci_dev
+@@ -3630,7 +3630,7 @@ static int net2280_probe(struct pci_dev
goto done;
}
if (pci_enable_msi(pdev))
ep_err(dev, "Failed to enable MSI mode\n");
-@@ -3755,10 +3755,19 @@ static const struct pci_device_id pci_id
+@@ -3748,10 +3748,19 @@ static const struct pci_device_id pci_id
.class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_PLX,
},
{
.class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
-@@ -3767,7 +3776,7 @@ static const struct pci_device_id pci_id
+@@ -3760,7 +3769,7 @@ static const struct pci_device_id pci_id
.device = 0x3382,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
+++ /dev/null
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] Revert "bcma: init serial console directly from ChipCommon
- code"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit 4c81acab3816 ("bcma: init serial console directly
-from ChipCommon code") as it broke IRQ assignment. Getting IRQ with
-bcma_core_irq helper on SoC requires MIPS core to be set. It happens
-*after* ChipCommon initialization so we can't do this so early.
-
-This fixes a user reported regression. It wasn't critical as serial was
-still somehow working but lack of IRQs was making in unreliable.
-
-Fixes: 4c81acab3816 ("bcma: init serial console directly from ChipCommon code")
-Reported-by: Felix Fietkau <nbd@nbd.name>
-Cc: stable@vger.kernel.org # 4.6+
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/bcma/bcma_private.h | 3 +++
- drivers/bcma/driver_chipcommon.c | 11 +++--------
- drivers/bcma/driver_mips.c | 3 +++
- 3 files changed, 9 insertions(+), 8 deletions(-)
-
---- a/drivers/bcma/bcma_private.h
-+++ b/drivers/bcma/bcma_private.h
-@@ -45,6 +45,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
- void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc);
- void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
- void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
-+#endif /* CONFIG_BCMA_DRIVER_MIPS */
-
- /* driver_chipcommon_b.c */
- int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb);
---- a/drivers/bcma/driver_chipcommon.c
-+++ b/drivers/bcma/driver_chipcommon.c
-@@ -15,8 +15,6 @@
- #include <linux/platform_device.h>
- #include <linux/bcma/bcma.h>
-
--static void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
--
- static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
- u32 mask, u32 value)
- {
-@@ -186,9 +184,6 @@ void bcma_core_chipcommon_early_init(str
- if (cc->capabilities & BCMA_CC_CAP_PMU)
- bcma_pmu_early_init(cc);
-
-- if (IS_BUILTIN(CONFIG_BCM47XX) && bus->hosttype == BCMA_HOSTTYPE_SOC)
-- bcma_chipco_serial_init(cc);
--
- if (bus->hosttype == BCMA_HOSTTYPE_SOC)
- bcma_core_chipcommon_flash_detect(cc);
-
-@@ -378,9 +373,9 @@ u32 bcma_chipco_gpio_pulldown(struct bcm
- return res;
- }
-
--static void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
- {
--#if IS_BUILTIN(CONFIG_BCM47XX)
- unsigned int irq;
- u32 baud_base;
- u32 i;
-@@ -422,5 +417,5 @@ static void bcma_chipco_serial_init(stru
- ports[i].baud_base = baud_base;
- ports[i].reg_shift = 0;
- }
--#endif /* CONFIG_BCM47XX */
- }
-+#endif /* CONFIG_BCMA_DRIVER_MIPS */
---- a/drivers/bcma/driver_mips.c
-+++ b/drivers/bcma/driver_mips.c
-@@ -278,9 +278,12 @@ static void bcma_core_mips_nvram_init(st
-
- void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
- {
-+ struct bcma_bus *bus = mcore->core->bus;
-+
- if (mcore->early_setup_done)
- return;
-
-+ bcma_chipco_serial_init(&bus->drv_cc);
- bcma_core_mips_nvram_init(mcore);
-
- mcore->early_setup_done = true;
--- a/Makefile
+++ b/Makefile
-@@ -621,12 +621,12 @@ KBUILD_CFLAGS += $(call cc-disable-warni
- KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
+@@ -624,12 +624,12 @@ KBUILD_CFLAGS += $(call cc-disable-warni
+ KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
-KBUILD_CFLAGS += -Os
---
--- a/include/linux/module.h
+++ b/include/linux/module.h
-@@ -169,9 +169,10 @@ void trim_init_extable(struct module *m)
+@@ -169,6 +169,7 @@ void trim_init_extable(struct module *m)
/* Generic info of form tag = "info" */
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info)
/* For userspace: you can also call me... */
--#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
-+#define MODULE_ALIAS(_alias) MODULE_INFO_STRIP(alias, _alias)
-
- /* Soft module dependencies. See man modprobe.d for details.
- * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz")
+ #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
@@ -212,12 +213,12 @@ void trim_init_extable(struct module *m)
* Author(s), use "Name <email>" or just "Name", for multiple
* authors use multiple MODULE_AUTHOR() statements/lines.
+++ /dev/null
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Sat, 2 Jan 2016 01:04:52 +0100
-Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating
- offsets
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 40 insertions(+), 10 deletions(-)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -62,6 +62,34 @@ static void bcm47xxpart_add_part(struct
- part->mask_flags = mask_flags;
- }
-
-+/*
-+ * Calculate real end offset (address) for a given amount of data. It checks
-+ * all blocks skipping bad ones.
-+ */
-+static size_t bcm47xxpart_real_offset(struct mtd_info *master, size_t offset,
-+ size_t bytes)
-+{
-+ size_t real_offset = offset;
-+
-+ if (mtd_block_isbad(master, real_offset))
-+ pr_warn("Base offset shouldn't be at bad block");
-+
-+ while (bytes >= master->erasesize) {
-+ bytes -= master->erasesize;
-+ real_offset += master->erasesize;
-+ while (mtd_block_isbad(master, real_offset)) {
-+ real_offset += master->erasesize;
-+
-+ if (real_offset >= master->size)
-+ return real_offset - master->erasesize;
-+ }
-+ }
-+
-+ real_offset += bytes;
-+
-+ return real_offset;
-+}
-+
- static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
- size_t offset)
- {
-@@ -91,6 +119,7 @@ static int bcm47xxpart_parse_trx(struct
- {
- struct trx_header header;
- size_t bytes_read;
-+ size_t offset;
- int curr_part = 0;
- int i, err;
-
-@@ -110,21 +139,25 @@ static int bcm47xxpart_parse_trx(struct
-
- /* We have LZMA loader if offset[2] points to sth */
- if (header.offset[2]) {
-- bcm47xxpart_add_part(&parts[curr_part++], "loader",
-- trx->offset + header.offset[i], 0);
-+ offset = bcm47xxpart_real_offset(master, trx->offset,
-+ header.offset[i]);
-+ bcm47xxpart_add_part(&parts[curr_part++], "loader", offset, 0);
- i++;
- }
-
- if (header.offset[i]) {
-- bcm47xxpart_add_part(&parts[curr_part++], "linux",
-- trx->offset + header.offset[i], 0);
-+ offset = bcm47xxpart_real_offset(master, trx->offset,
-+ header.offset[i]);
-+ bcm47xxpart_add_part(&parts[curr_part++], "linux", offset, 0);
- i++;
- }
-
- if (header.offset[i]) {
-- size_t offset = trx->offset + header.offset[i];
-- const char *name = bcm47xxpart_trx_data_part_name(master,
-- offset);
-+ const char *name;
-+
-+ offset = bcm47xxpart_real_offset(master, trx->offset,
-+ header.offset[i]);
-+ name = bcm47xxpart_trx_data_part_name(master, offset);
-
- bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0);
- i++;
+++ /dev/null
-From fd54aa583296f9adfb1f519affbc10ba521eb809 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Wed, 28 Jan 2015 22:14:41 +0100
-Subject: [PATCH] mtd: bcm47xxpart: detect T_Meter partition
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It can be found on many Netgear devices. It consists of many 0x30 blocks
-starting with 4D 54.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -39,6 +39,7 @@
- #define NVRAM_HEADER 0x48534C46 /* FLSH */
- #define POT_MAGIC1 0x54544f50 /* POTT */
- #define POT_MAGIC2 0x504f /* OP */
-+#define T_METER_MAGIC 0x4D540000 /* MT */
- #define ML_MAGIC1 0x39685a42
- #define ML_MAGIC2 0x26594131
- #define TRX_MAGIC 0x30524448
-@@ -297,6 +298,15 @@ static int bcm47xxpart_parse(struct mtd_
- MTD_WRITEABLE);
- continue;
- }
-+
-+ /* T_Meter */
-+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
-+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
-+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) {
-+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset,
-+ MTD_WRITEABLE);
-+ continue;
-+ }
-
- /* TRX */
- if (buf[0x000 / 4] == TRX_MAGIC) {
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -1159,6 +1159,7 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -1166,6 +1166,7 @@ int spi_nor_scan(struct spi_nor *nor, co
if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
JEDEC_MFR(info) == SNOR_MFR_INTEL ||
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -3111,6 +3113,7 @@ static int packet_create(struct net *net
+@@ -3115,6 +3117,7 @@ static int packet_create(struct net *net
mutex_init(&po->pg_vec_lock);
po->rollover = NULL;
po->prot_hook.func = packet_rcv;
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
-@@ -3733,6 +3736,16 @@ packet_setsockopt(struct socket *sock, i
+@@ -3744,6 +3747,16 @@ packet_setsockopt(struct socket *sock, i
po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
return 0;
}
default:
return -ENOPROTOOPT;
}
-@@ -3785,6 +3798,13 @@ static int packet_getsockopt(struct sock
+@@ -3796,6 +3809,13 @@ static int packet_getsockopt(struct sock
case PACKET_VNET_HDR:
val = po->has_vnet_hdr;
break;
---
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -168,7 +168,11 @@ int br_handle_frame_finish(struct net *n
+@@ -169,7 +169,11 @@ int br_handle_frame_finish(struct net *n
if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
br_do_proxy_arp(skb, br, vid, p);
---
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -152,7 +152,7 @@ int br_handle_frame_finish(struct net *n
+@@ -153,7 +153,7 @@ int br_handle_frame_finish(struct net *n
br_multicast_rcv(br, p, skb, vid))
goto drop;
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -191,8 +191,8 @@ int br_handle_frame_finish(struct net *n
+@@ -192,8 +192,8 @@ int br_handle_frame_finish(struct net *n
unicast = false;
br->dev->stats.multicast++;
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
-@@ -1812,27 +1812,7 @@ void netlink_detachskb(struct sock *sk,
+@@ -1187,24 +1187,7 @@ void netlink_detachskb(struct sock *sk,
static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation)
{
- int delta;
-
WARN_ON(skb->sk != NULL);
-- if (netlink_skb_is_mmaped(skb))
-- return skb;
--
- delta = skb->end - skb->tail;
- if (is_vmalloc_addr(skb->head) || delta * 2 < skb->truesize)
- return skb;
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
-@@ -2180,7 +2180,7 @@ static inline int pskb_network_may_pull(
+@@ -2177,7 +2177,7 @@ static inline int pskb_network_may_pull(
* NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
*/
#ifndef NET_SKB_PAD
+ qdisc = qdisc_create_dflt(dev_queue, &fq_codel_qdisc_ops,
TC_H_MAKE(TC_H_MAJ(sch->handle),
TC_H_MIN(ntx + 1)));
- if (qdisc == NULL)
+ if (!qdisc)
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
-@@ -124,7 +124,7 @@ static int mqprio_init(struct Qdisc *sch
+@@ -122,7 +122,7 @@ static int mqprio_init(struct Qdisc *sch
for (i = 0; i < dev->num_tx_queues; i++) {
dev_queue = netdev_get_tx_queue(dev, i);
+ qdisc = qdisc_create_dflt(dev_queue, &fq_codel_qdisc_ops,
TC_H_MAKE(TC_H_MAJ(sch->handle),
TC_H_MIN(i + 1)));
- if (qdisc == NULL) {
+ if (!qdisc)
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
-@@ -1948,7 +1948,7 @@ static int __init pktsched_init(void)
+@@ -1951,7 +1951,7 @@ static int __init pktsched_init(void)
return err;
}
__skb_tunnel_rx(skb, t->dev, t->net);
-@@ -1245,6 +1382,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
+@@ -1247,6 +1384,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
__u32 mtu;
u8 tproto;
int err;
tproto = ACCESS_ONCE(t->parms.proto);
if ((tproto != IPPROTO_IPV6 && tproto != 0) ||
-@@ -1275,6 +1413,18 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
+@@ -1277,6 +1415,18 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
fl6.flowi6_mark = skb->mark;
err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
if (err != 0) {
if (err == -EMSGSIZE)
-@@ -1389,6 +1539,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
+@@ -1391,6 +1541,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
t->parms.flowinfo = p->flowinfo;
t->parms.link = p->link;
t->parms.proto = p->proto;
ip6_tnl_dst_reset(t);
ip6_tnl_link_config(t);
return 0;
-@@ -1427,6 +1585,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
+@@ -1429,6 +1587,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
p->flowinfo = u->flowinfo;
p->link = u->link;
p->proto = u->proto;
memcpy(p->name, u->name, sizeof(u->name));
}
-@@ -1722,6 +1881,15 @@ static int ip6_tnl_validate(struct nlatt
+@@ -1724,6 +1883,15 @@ static int ip6_tnl_validate(struct nlatt
return 0;
}
static void ip6_tnl_netlink_parms(struct nlattr *data[],
struct __ip6_tnl_parm *parms)
{
-@@ -1753,6 +1921,46 @@ static void ip6_tnl_netlink_parms(struct
+@@ -1755,6 +1923,46 @@ static void ip6_tnl_netlink_parms(struct
if (data[IFLA_IPTUN_PROTO])
parms->proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
}
static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
-@@ -1805,6 +2013,12 @@ static void ip6_tnl_dellink(struct net_d
+@@ -1807,6 +2015,12 @@ static void ip6_tnl_dellink(struct net_d
static size_t ip6_tnl_get_size(const struct net_device *dev)
{
return
/* IFLA_IPTUN_LINK */
nla_total_size(4) +
-@@ -1822,6 +2036,24 @@ static size_t ip6_tnl_get_size(const str
+@@ -1824,6 +2038,24 @@ static size_t ip6_tnl_get_size(const str
nla_total_size(4) +
/* IFLA_IPTUN_PROTO */
nla_total_size(1) +
0;
}
-@@ -1829,6 +2061,9 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -1831,6 +2063,9 @@ static int ip6_tnl_fill_info(struct sk_b
{
struct ip6_tnl *tunnel = netdev_priv(dev);
struct __ip6_tnl_parm *parm = &tunnel->parms;
if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
-@@ -1837,8 +2072,27 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -1839,8 +2074,27 @@ static int ip6_tnl_fill_info(struct sk_b
nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) ||
nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
return 0;
nla_put_failure:
-@@ -1862,6 +2116,7 @@ static const struct nla_policy ip6_tnl_p
+@@ -1864,6 +2118,7 @@ static const struct nla_policy ip6_tnl_p
[IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 },
[IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
[IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
static void rt_fibinfo_free(struct rtable __rcu **rtp)
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -2368,6 +2368,7 @@ static const char *const rtn_type_names[
+@@ -2370,6 +2370,7 @@ static const char *const rtn_type_names[
[RTN_THROW] = "THROW",
[RTN_NAT] = "NAT",
[RTN_XRESOLVE] = "XRESOLVE",
default:
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
-@@ -84,6 +84,10 @@ static int fib6_rule_action(struct fib_r
+@@ -73,6 +73,10 @@ static int fib6_rule_action(struct fib_r
err = -EACCES;
rt = net->ipv6.ip6_prohibit_entry;
goto discard_pkt;
static const struct rt6_info ip6_blk_hole_entry_template = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
-@@ -1885,6 +1902,11 @@ static struct rt6_info *ip6_route_info_c
+@@ -1889,6 +1906,11 @@ static struct rt6_info *ip6_route_info_c
rt->dst.output = ip6_pkt_prohibit_out;
rt->dst.input = ip6_pkt_prohibit;
break;
case RTN_THROW:
case RTN_UNREACHABLE:
default:
-@@ -2486,6 +2508,17 @@ static int ip6_pkt_prohibit_out(struct n
+@@ -2492,6 +2514,17 @@ static int ip6_pkt_prohibit_out(struct n
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
}
/*
* Allocate a dst for local (unicast / anycast) address.
*/
-@@ -2728,7 +2761,8 @@ static int rtm_to_fib6_config(struct sk_
+@@ -2734,7 +2767,8 @@ static int rtm_to_fib6_config(struct sk_
if (rtm->rtm_type == RTN_UNREACHABLE ||
rtm->rtm_type == RTN_BLACKHOLE ||
rtm->rtm_type == RTN_PROHIBIT ||
case -EAGAIN:
rtm->rtm_type = RTN_THROW;
break;
-@@ -3363,6 +3400,8 @@ static int ip6_route_dev_notify(struct n
+@@ -3366,6 +3403,8 @@ static int ip6_route_dev_notify(struct n
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
#endif
-@@ -3579,6 +3618,17 @@ static int __net_init ip6_route_net_init
+@@ -3588,6 +3627,17 @@ static int __net_init ip6_route_net_init
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
ip6_template_metrics, true);
#endif
net->ipv6.sysctl.flush_delay = 0;
-@@ -3597,6 +3647,8 @@ out:
+@@ -3606,6 +3656,8 @@ out:
return ret;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
out_ip6_prohibit_entry:
kfree(net->ipv6.ip6_prohibit_entry);
out_ip6_null_entry:
-@@ -3614,6 +3666,7 @@ static void __net_exit ip6_route_net_exi
+@@ -3623,6 +3675,7 @@ static void __net_exit ip6_route_net_exi
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
kfree(net->ipv6.ip6_prohibit_entry);
kfree(net->ipv6.ip6_blk_hole_entry);
#endif
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
}
-@@ -3711,6 +3764,9 @@ int __init ip6_route_init(void)
+@@ -3696,6 +3749,9 @@ void __init ip6_route_init_special_entri
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev =
+ in6_dev_get(init_net.loopback_dev);
#endif
- ret = fib6_init();
- if (ret)
+ }
+
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -4219,6 +4219,9 @@ static enum gro_result dev_gro_receive(s
+@@ -4256,6 +4256,9 @@ static enum gro_result dev_gro_receive(s
enum gro_result ret;
int grow;
if (!(skb->dev->features & NETIF_F_GRO))
goto normal;
-@@ -5378,6 +5381,48 @@ static void __netdev_adjacent_dev_unlink
+@@ -5422,6 +5425,48 @@ static void __netdev_adjacent_dev_unlink
&upper_dev->adj_list.lower);
}
static int __netdev_upper_dev_link(struct net_device *dev,
struct net_device *upper_dev, bool master,
void *private)
-@@ -5449,6 +5494,7 @@ static int __netdev_upper_dev_link(struc
+@@ -5493,6 +5538,7 @@ static int __netdev_upper_dev_link(struc
goto rollback_lower_mesh;
}
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev,
&changeupper_info.info);
return 0;
-@@ -5575,6 +5621,7 @@ void netdev_upper_dev_unlink(struct net_
+@@ -5619,6 +5665,7 @@ void netdev_upper_dev_unlink(struct net_
list_for_each_entry(i, &upper_dev->all_adj_list.upper, list)
__netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr);
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev,
&changeupper_info.info);
}
-@@ -6115,6 +6162,7 @@ int dev_set_mac_address(struct net_devic
+@@ -6159,6 +6206,7 @@ int dev_set_mac_address(struct net_devic
if (err)
return err;
dev->addr_assign_type = NET_ADDR_SET;
* @phydev: the phy_device struct
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
-@@ -796,6 +796,7 @@ void phy_start_machine(struct phy_device
+@@ -800,6 +800,7 @@ void phy_start_machine(struct phy_device
void phy_stop_machine(struct phy_device *phydev);
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
-@@ -1213,7 +1213,7 @@ int genphy_config_init(struct phy_device
- return 0;
- }
-
--static int gen10g_soft_reset(struct phy_device *phydev)
-+static int no_soft_reset(struct phy_device *phydev)
- {
- /* Do nothing for now */
- return 0;
-@@ -1448,7 +1448,7 @@ static struct phy_driver genphy_driver[]
- .phy_id = 0xffffffff,
- .phy_id_mask = 0xffffffff,
- .name = "Generic PHY",
-- .soft_reset = genphy_soft_reset,
-+ .soft_reset = no_soft_reset,
- .config_init = genphy_config_init,
- .features = PHY_GBIT_FEATURES | SUPPORTED_MII |
- SUPPORTED_AUI | SUPPORTED_FIBRE |
-@@ -1463,7 +1463,7 @@ static struct phy_driver genphy_driver[]
+@@ -1465,7 +1465,7 @@ static struct phy_driver genphy_driver[]
.phy_id = 0xffffffff,
.phy_id_mask = 0xffffffff,
.name = "Generic 10G PHY",
- .soft_reset = gen10g_soft_reset,
-+ .soft_reset = no_soft_reset,
++ .soft_reset = genphy_no_soft_reset,
.config_init = gen10g_config_init,
.features = 0,
.config_aneg = gen10g_config_aneg,
phy_device_free(phydev);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
-@@ -835,6 +835,23 @@ void mdio_bus_exit(void);
+@@ -839,6 +839,23 @@ void mdio_bus_exit(void);
extern struct bus_type mdio_bus_type;
*/
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
-@@ -2211,6 +2211,10 @@ static inline int pskb_trim(struct sk_bu
+@@ -2208,6 +2208,10 @@ static inline int pskb_trim(struct sk_bu
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
}
/**
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
* @skb: buffer to alter
-@@ -2315,16 +2319,6 @@ static inline struct sk_buff *dev_alloc_
+@@ -2312,16 +2316,6 @@ static inline struct sk_buff *dev_alloc_
}
help
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -2708,10 +2708,20 @@ static int xmit_one(struct sk_buff *skb,
+@@ -2743,10 +2743,20 @@ static int xmit_one(struct sk_buff *skb,
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
dev_queue_xmit_nit(skb, dev);
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
-@@ -97,6 +97,8 @@ struct amd_chipset_type {
+@@ -98,6 +98,8 @@ struct amd_chipset_type {
u8 rev;
};
static struct amd_chipset_info {
struct pci_dev *nb_dev;
struct pci_dev *smbus_dev;
-@@ -450,6 +452,10 @@ void usb_amd_dev_put(void)
+@@ -457,6 +459,10 @@ void usb_amd_dev_put(void)
}
EXPORT_SYMBOL_GPL(usb_amd_dev_put);
/*
* Make sure the controller is completely inactive, unable to
* generate interrupts or do DMA.
-@@ -529,8 +535,17 @@ reset_needed:
+@@ -536,8 +542,17 @@ reset_needed:
uhci_reset_hc(pdev, base);
return 1;
}
static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
{
u16 cmd;
-@@ -1095,3 +1110,4 @@ static void quirk_usb_early_handoff(stru
+@@ -1102,3 +1117,4 @@ static void quirk_usb_early_handoff(stru
}
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff);
#endif /* __LINUX_USB_PCI_QUIRKS_H */
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
-@@ -459,7 +459,14 @@ extern int usb_hcd_pci_probe(struct pci_
+@@ -460,7 +460,14 @@ extern int usb_hcd_pci_probe(struct pci_
extern void usb_hcd_pci_remove(struct pci_dev *dev);
extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
obj-$(CONFIG_PROC_FS) += net-procfs.o
--- a/net/core/sock.c
+++ b/net/core/sock.c
-@@ -1469,9 +1469,11 @@ void sk_destruct(struct sock *sk)
+@@ -1474,9 +1474,11 @@ void sk_destruct(struct sock *sk)
static void __sk_free(struct sock *sk)
{
Support for UNIX socket monitoring interface used by the ss tool.
--- a/net/netlink/Kconfig
+++ b/net/netlink/Kconfig
-@@ -13,6 +13,7 @@ config NETLINK_MMAP
+@@ -4,6 +4,7 @@
config NETLINK_DIAG
tristate "NETLINK: socket monitoring interface"
goto err;
--- a/net/core/sock.c
+++ b/net/core/sock.c
-@@ -3036,6 +3036,8 @@ static __net_initdata struct pernet_oper
+@@ -3042,6 +3042,8 @@ static __net_initdata struct pernet_oper
static int __init proto_init(void)
{
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -2639,10 +2639,12 @@ static const struct file_operations fib_
+@@ -2641,10 +2641,12 @@ static const struct file_operations fib_
int __net_init fib_proc_init(struct net *net)
{
&fib_triestat_fops))
goto out2;
-@@ -2652,17 +2654,21 @@ int __net_init fib_proc_init(struct net
+@@ -2654,17 +2656,21 @@ int __net_init fib_proc_init(struct net
return 0;
out3:
endif
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
-@@ -2717,6 +2717,7 @@ enum {
+@@ -2722,6 +2722,7 @@ enum {
DIO_SKIP_DIO_COUNT = 0x08,
};
void dio_end_io(struct bio *bio, int error);
ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
-@@ -2724,6 +2725,18 @@ ssize_t __blockdev_direct_IO(struct kioc
+@@ -2729,6 +2730,18 @@ ssize_t __blockdev_direct_IO(struct kioc
loff_t offset, get_block_t get_block,
dio_iodone_t end_io, dio_submit_t submit_io,
int flags);
--- /dev/null
+From 13f00eb4493c217269b76614759e452d8302955e Mon Sep 17 00:00:00 2001
+From: Paul Eggert <eggert@cs.ucla.edu>
+Date: Thu, 31 Mar 2016 16:35:29 -0700
+Subject: [PATCH] automake: port to Perl 5.22 and later
+
+Without this change, Perl 5.22 complains "Unescaped left brace in
+regex is deprecated" and this is planned to become a hard error in
+Perl 5.26. See:
+http://search.cpan.org/dist/perl-5.22.0/pod/perldelta.pod#A_literal_%22{%22_should_now_be_escaped_in_a_pattern
+* bin/automake.in (substitute_ac_subst_variables): Escape left brace.
+---
+ bin/automake.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bin/automake.in b/bin/automake.in
+index a3a0aa318..2c8f31e14 100644
+--- a/bin/automake.in
++++ b/bin/automake.in
+@@ -3878,7 +3878,7 @@ sub substitute_ac_subst_variables_worker
+ sub substitute_ac_subst_variables
+ {
+ my ($text) = @_;
+- $text =~ s/\${([^ \t=:+{}]+)}/substitute_ac_subst_variables_worker ($1)/ge;
++ $text =~ s/\$[{]([^ \t=:+{}]+)}/substitute_ac_subst_variables_worker ($1)/ge;
+ return $text;
+ }
+
+--
+2.13.1
+